WP Statistics - Version 13.0.4

Version Description

  • Compatibility with PHP v7.2 and adjustment requires PHP version in the Composer to 5.6
  • Fixed the issue to get the Referred::get() method during the initial plugin.
  • Fixed issue to create tables queries in MariaDB v10.3
  • Fixed the ChartJs conflict with some plugins.
  • Disabled the Cronjob for table optimization in the background process (we're going to create an option on the Optimization page to handle it)
  • Minor Improvements.
Download this release

Release Info

Developer mostafa.s1990
Plugin Icon 128x128 WP Statistics
Version 13.0.4
Comparing to
See all releases

Code changes from version 13.0.3 to 13.0.4

Files changed (96) hide show
  1. assets/js/chartjs/chart.bundle.min.js +1 -1
  2. includes/admin/class-wp-statistics-admin-assets.php +1 -1
  3. includes/class-wp-statistics-install.php +11 -11
  4. includes/class-wp-statistics-schedule.php +0 -18
  5. includes/class-wp-statistics.php +23 -34
  6. includes/vendor/autoload.php +1 -1
  7. includes/vendor/composer/InstalledVersions.php +0 -281
  8. includes/vendor/composer/autoload_real.php +4 -4
  9. includes/vendor/composer/autoload_static.php +3 -3
  10. includes/vendor/composer/installed.json +30 -38
  11. includes/vendor/composer/installed.php +0 -96
  12. includes/vendor/composer/platform_check.php +0 -25
  13. includes/vendor/maxmind-db/reader/CHANGELOG.md +0 -20
  14. includes/vendor/maxmind-db/reader/README.md +2 -2
  15. includes/vendor/maxmind-db/reader/autoload.php +1 -3
  16. includes/vendor/maxmind-db/reader/composer.json +4 -4
  17. includes/vendor/maxmind-db/reader/ext/maxminddb.c +236 -338
  18. includes/vendor/maxmind-db/reader/ext/php_maxminddb.h +1 -1
  19. includes/vendor/maxmind-db/reader/package.xml +0 -60
  20. includes/vendor/maxmind-db/reader/src/MaxMind/Db/Reader.php +47 -85
  21. includes/vendor/maxmind-db/reader/src/MaxMind/Db/Reader/Decoder.php +77 -79
  22. includes/vendor/maxmind-db/reader/src/MaxMind/Db/Reader/InvalidDatabaseException.php +0 -2
  23. includes/vendor/maxmind-db/reader/src/MaxMind/Db/Reader/Metadata.php +62 -86
  24. includes/vendor/maxmind-db/reader/src/MaxMind/Db/Reader/Util.php +2 -7
  25. includes/vendor/maxmind/web-service-common/CHANGELOG.md +0 -15
  26. includes/vendor/maxmind/web-service-common/README.md +1 -1
  27. includes/vendor/maxmind/web-service-common/composer.json +2 -2
  28. includes/vendor/maxmind/web-service-common/src/Exception/AuthenticationException.php +0 -2
  29. includes/vendor/maxmind/web-service-common/src/Exception/HttpException.php +5 -7
  30. includes/vendor/maxmind/web-service-common/src/Exception/InsufficientFundsException.php +0 -2
  31. includes/vendor/maxmind/web-service-common/src/Exception/InvalidInputException.php +0 -2
  32. includes/vendor/maxmind/web-service-common/src/Exception/InvalidRequestException.php +6 -8
  33. includes/vendor/maxmind/web-service-common/src/Exception/IpAddressNotFoundException.php +0 -2
  34. includes/vendor/maxmind/web-service-common/src/Exception/PermissionRequiredException.php +0 -2
  35. includes/vendor/maxmind/web-service-common/src/Exception/WebServiceException.php +0 -2
  36. includes/vendor/maxmind/web-service-common/src/WebService/Client.php +49 -51
  37. includes/vendor/maxmind/web-service-common/src/WebService/Http/CurlRequest.php +15 -15
  38. includes/vendor/maxmind/web-service-common/src/WebService/Http/Request.php +15 -5
  39. includes/vendor/maxmind/web-service-common/src/WebService/Http/RequestFactory.php +4 -3
  40. includes/vendor/whichbrowser/parser/.coveralls.yml +7 -0
  41. includes/vendor/whichbrowser/parser/.gitignore +12 -0
  42. includes/vendor/whichbrowser/parser/.travis.yml +39 -0
  43. includes/vendor/whichbrowser/parser/README.md +4 -15
  44. includes/vendor/whichbrowser/parser/composer.json +3 -3
  45. includes/vendor/whichbrowser/parser/data/applications-bots.php +1 -2
  46. includes/vendor/whichbrowser/parser/data/applications-browsers.php +0 -2
  47. includes/vendor/whichbrowser/parser/data/browsers-chrome.php +0 -20
  48. includes/vendor/whichbrowser/parser/data/indices/models-android.php +911 -1169
  49. includes/vendor/whichbrowser/parser/data/models-android.php +33 -395
  50. includes/vendor/whichbrowser/parser/data/models-ios.php +0 -18
  51. includes/vendor/whichbrowser/parser/data/regexes/applications-bots.php +1 -1
  52. includes/vendor/whichbrowser/parser/data/regexes/applications-browsers.php +1 -1
  53. includes/vendor/whichbrowser/parser/phpunit.xml +32 -0
  54. includes/vendor/whichbrowser/parser/src/Analyser/Derive.php +0 -4
  55. includes/vendor/whichbrowser/parser/src/Analyser/Header/Useragent/Browser.php +4 -27
  56. includes/vendor/whichbrowser/parser/src/Model/Primitive/Base.php +1 -1
  57. includes/vendor/whichbrowser/parser/src/Model/Primitive/NameVersion.php +3 -8
  58. includes/vendor/whichbrowser/parser/src/Model/Version.php +1 -1
  59. includes/vendor/whichbrowser/parser/tests/data/appliance/amstrad.yaml +4 -0
  60. includes/vendor/whichbrowser/parser/tests/data/appliance/familyhub.yaml +4 -0
  61. includes/vendor/whichbrowser/parser/tests/data/appliance/i-opener.yaml +4 -0
  62. includes/vendor/whichbrowser/parser/tests/data/appliance/weblight.yaml +8 -0
  63. includes/vendor/whichbrowser/parser/tests/data/bots/disabled.yaml +25 -0
  64. includes/vendor/whichbrowser/parser/tests/data/bots/false-positive.yaml +8 -0
  65. includes/vendor/whichbrowser/parser/tests/data/bots/generic.yaml +508 -0
  66. includes/vendor/whichbrowser/parser/tests/data/camera/os-android.yaml +4 -0
  67. includes/vendor/whichbrowser/parser/tests/data/camera/os-tizen.yaml +8 -0
  68. includes/vendor/whichbrowser/parser/tests/data/car/tesla.yaml +8 -0
  69. includes/vendor/whichbrowser/parser/tests/data/car/volvo.yaml +9 -0
  70. includes/vendor/whichbrowser/parser/tests/data/desktop/app-editor.yaml +28 -0
  71. includes/vendor/whichbrowser/parser/tests/data/desktop/app-mediaplayer.yaml +4 -0
  72. includes/vendor/whichbrowser/parser/tests/data/desktop/browser-arachne.yaml +8 -0
  73. includes/vendor/whichbrowser/parser/tests/data/desktop/browser-brave.yaml +12 -0
  74. includes/vendor/whichbrowser/parser/tests/data/desktop/browser-chrome.yaml +64 -0
  75. includes/vendor/whichbrowser/parser/tests/data/desktop/browser-chromium.yaml +52 -0
  76. includes/vendor/whichbrowser/parser/tests/data/desktop/browser-edge.yaml +32 -0
  77. includes/vendor/whichbrowser/parser/tests/data/desktop/browser-firefox.yaml +256 -0
  78. includes/vendor/whichbrowser/parser/tests/data/desktop/browser-icab.yaml +40 -0
  79. includes/vendor/whichbrowser/parser/tests/data/desktop/browser-ie.yaml +104 -0
  80. includes/vendor/whichbrowser/parser/tests/data/desktop/browser-konqueror.yaml +80 -0
  81. includes/vendor/whichbrowser/parser/tests/data/desktop/browser-maxthon.yaml +136 -0
  82. includes/vendor/whichbrowser/parser/tests/data/desktop/browser-midori.yaml +60 -0
  83. includes/vendor/whichbrowser/parser/tests/data/desktop/browser-mosaic.yaml +96 -0
  84. includes/vendor/whichbrowser/parser/tests/data/desktop/browser-netfront.yaml +20 -0
  85. includes/vendor/whichbrowser/parser/tests/data/desktop/browser-netscape.yaml +76 -0
  86. includes/vendor/whichbrowser/parser/tests/data/desktop/browser-omniweb.yaml +92 -0
  87. includes/vendor/whichbrowser/parser/tests/data/desktop/browser-opera.yaml +431 -0
  88. includes/vendor/whichbrowser/parser/tests/data/desktop/browser-other.yaml +160 -0
  89. includes/vendor/whichbrowser/parser/tests/data/desktop/browser-qq.yaml +68 -0
  90. includes/vendor/whichbrowser/parser/tests/data/desktop/browser-safari.yaml +220 -0
  91. includes/vendor/whichbrowser/parser/tests/data/desktop/browser-seamonkey.yaml +88 -0
  92. includes/vendor/whichbrowser/parser/tests/data/desktop/browser-text.yaml +48 -0
  93. includes/vendor/whichbrowser/parser/tests/data/desktop/browser-uc.yaml +101 -0
  94. includes/vendor/whichbrowser/parser/tests/data/desktop/engine-goanna.yaml +28 -0
  95. includes/vendor/whichbrowser/parser/tests/data/desktop/engine-servo.yaml +12 -0
  96. includes/vendor/whichbrowser/parser/tests/data/desktop/os-amigaos.yaml +18 -0
assets/js/chartjs/chart.bundle.min.js CHANGED
@@ -4,4 +4,4 @@
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"==typeof define&&define.amd?define(e):(t=t||self).Chart=e()}(this,(function(){"use strict";"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self&&self;function t(){throw new Error("Dynamic requires are not currently supported by rollup-plugin-commonjs")}function e(t,e){return t(e={exports:{}},e.exports),e.exports}var n={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]},i=e((function(t){var e={};for(var i in n)n.hasOwnProperty(i)&&(e[n[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=e[t];if(i)return i;var a,r,o,s=1/0;for(var l in n)if(n.hasOwnProperty(l)){var u=n[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 n[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]}}));i.rgb,i.hsl,i.hsv,i.hwb,i.cmyk,i.xyz,i.lab,i.lch,i.hex,i.keyword,i.ansi16,i.ansi256,i.hcg,i.apple,i.gray;function a(t){var e=function(){for(var t={},e=Object.keys(i),n=e.length,a=0;a<n;a++)t[e[a]]={distance:-1,parent:null};return t}(),n=[t];for(e[t].distance=0;n.length;)for(var a=n.pop(),r=Object.keys(i[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,n.unshift(l))}return e}function r(t,e){return function(n){return e(t(n))}}function o(t,e){for(var n=[e[t].parent,t],a=i[e[t].parent][t],o=e[t].parent;e[o].parent;)n.unshift(e[o].parent),a=r(i[e[o].parent][o],a),o=e[o].parent;return a.conversion=n,a}var s={};Object.keys(i).forEach((function(t){s[t]={},Object.defineProperty(s[t],"channels",{value:i[t].channels}),Object.defineProperty(s[t],"labels",{value:i[t].labels});var e=function(t){for(var e=a(t),n={},i=Object.keys(e),r=i.length,s=0;s<r;s++){var l=i[s];null!==e[l].parent&&(n[l]=o(l,e))}return n}(t);Object.keys(e).forEach((function(n){var i=e[n];s[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),s[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 l=s,u={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]},d={getRgba:h,getHsla:c,getRgb:function(t){var e=h(t);return e&&e.slice(0,3)},getHsl:function(t){var e=c(t);return e&&e.slice(0,3)},getHwb:f,getAlpha:function(t){var e=h(t);if(e)return e[3];if(e=c(t))return e[3];if(e=f(t))return e[3]},hexString:function(t,e){e=void 0!==e&&3===t.length?e:t[3];return"#"+b(t[0])+b(t[1])+b(t[2])+(e>=0&&e<1?b(Math.round(255*e)):"")},rgbString:function(t,e){if(e<1||t[3]&&t[3]<1)return g(t,e);return"rgb("+t[0]+", "+t[1]+", "+t[2]+")"},rgbaString:g,percentString:function(t,e){if(e<1||t[3]&&t[3]<1)return m(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:m,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 y[t.slice(0,3)]}};function h(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=u[i[1]]))return}for(r=0;r<e.length;r++)e[r]=v(e[r],0,255);return n=n||0==n?v(n,0,1):1,e[3]=n,e}}function c(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[v(parseInt(e[1]),0,360),v(parseFloat(e[2]),0,100),v(parseFloat(e[3]),0,100),v(isNaN(n)?1:n,0,1)]}}}function f(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[v(parseInt(e[1]),0,360),v(parseFloat(e[2]),0,100),v(parseFloat(e[3]),0,100),v(isNaN(n)?1:n,0,1)]}}}function g(t,e){return void 0===e&&(e=void 0!==t[3]?t[3]:1),"rgba("+t[0]+", "+t[1]+", "+t[2]+", "+e+")"}function m(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 v(t,e,n){return Math.min(Math.max(e,t),n)}function b(t){var e=t.toString(16).toUpperCase();return e.length<2?"0"+e:e}var y={};for(var x in u)y[u[x]]=x;var _=function(t){return t instanceof _?t:this instanceof _?(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=d.getRgba(t))?this.setValues("rgb",e):(e=d.getHsla(t))?this.setValues("hsl",e):(e=d.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 _(t);var e};_.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 d.hexString(this.values.rgb)},rgbString:function(){return d.rgbString(this.values.rgb,this.values.alpha)},rgbaString:function(){return d.rgbaString(this.values.rgb,this.values.alpha)},percentString:function(){return d.percentString(this.values.rgb,this.values.alpha)},hslString:function(){return d.hslString(this.values.hsl,this.values.alpha)},hslaString:function(){return d.hslaString(this.values.hsl,this.values.alpha)},hwbString:function(){return d.hwbString(this.values.hwb,this.values.alpha)},keyword:function(){return d.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 _,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}},_.prototype.spaces={rgb:["red","green","blue"],hsl:["hue","saturation","lightness"],hsv:["hue","saturation","value"],hwb:["hue","whiteness","blackness"],cmyk:["cyan","magenta","yellow","black"]},_.prototype.maxes={rgb:[255,255,255],hsl:[360,100,100],hsv:[360,100,100],hwb:[360,100,100],cmyk:[100,100,100,100]},_.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},_.prototype.setValues=function(t,e){var n,i,a=this.values,r=this.spaces,o=this.maxes,s=1;if(this.valid=!0,"alpha"===t)s=e;else if(e.length)a[t]=e.slice(0,t.length),s=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)];s=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]];s=e.alpha}if(a.alpha=Math.max(0,Math.min(1,void 0===s?a.alpha:s)),"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]=l[t][d](a[t]));return!0},_.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)},_.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=_);var w=_;function k(t){return-1===["__proto__","prototype","constructor"].indexOf(t)}var M,S={noop:function(){},uid:(M=0,function(){return M++}),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 S.valueOrDefault(S.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(S.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(S.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(!S.arrayEquals(a,r))return!1}else if(a!==r)return!1;return!0},clone:function(t){if(S.isArray(t))return t.map(S.clone);if(S.isObject(t)){for(var e=Object.create(t),n=Object.keys(t),i=n.length,a=0;a<i;++a)e[n[a]]=S.clone(t[n[a]]);return e}return t},_merger:function(t,e,n,i){if(k(t)){var a=e[t],r=n[t];S.isObject(a)&&S.isObject(r)?S.merge(a,r,i):e[t]=S.clone(r)}},_mergerIf:function(t,e,n){if(k(t)){var i=e[t],a=n[t];S.isObject(i)&&S.isObject(a)?S.mergeIf(i,a):e.hasOwnProperty(t)||(e[t]=S.clone(a))}},merge:function(t,e,n){var i,a,r,o,s,l=S.isArray(e)?e:[e],u=l.length;if(!S.isObject(t))return t;for(i=(n=n||{}).merger||S._merger,a=0;a<u;++a)if(e=l[a],S.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 S.merge(t,e,{merger:S._mergerIf})},extend:Object.assign||function(t){return S.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=S.inherits,t&&S.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')}},D=S;S.callCallback=S.callback,S.indexOf=function(t,e,n){return Array.prototype.indexOf.call(t,e,n)},S.getValueOrDefault=S.valueOrDefault,S.getValueAtIndexOrDefault=S.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};D.easingEffects=C;var T=Math.PI,O=T/180,A=2*T,F=T/2,I=T/4,L=2*T/3,R={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,-T,-F),t.arc(u,l,o,-F,0),t.arc(u,d,o,0,F),t.arc(s,d,o,F,T)):s<u?(t.moveTo(s,n),t.arc(u,l,o,-F,F),t.arc(s,l,o,F,T+F)):l<d?(t.arc(s,l,o,-T,0),t.arc(s,d,o,0,T)):t.arc(s,l,o,-T,T),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)*O;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,A),t.closePath();break;case"triangle":t.moveTo(i+Math.sin(h)*n,a-Math.cos(h)*n),h+=L,t.lineTo(i+Math.sin(h)*n,a-Math.cos(h)*n),h+=L,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+I)*u,l=Math.sin(h+I)*u,t.arc(i-s,a-l,d,h-T,h-F),t.arc(i+l,a-s,d,h-F,h),t.arc(i+s,a+l,d,h,h+F),t.arc(i-l,a+s,d,h+F,h+T),t.closePath();break;case"rect":if(!r){u=Math.SQRT1_2*n,t.rect(i-u,a-u,2*u,2*u);break}h+=I;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+=I;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+=I,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)}},N=R;D.clear=R.clear,D.drawRoundedRectangle=function(t){t.beginPath(),R.roundedRect.apply(R,arguments)};var W={_set:function(t,e){return D.merge(this[t]||(this[t]={}),e)}};W._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 Y=W,z=D.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 D.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=Y.global,n=z(t.fontSize,e.defaultFontSize),i={family:z(t.fontFamily,e.defaultFontFamily),lineHeight:D.options.toLineHeight(z(t.lineHeight,e.defaultLineHeight),n),size:n,style:z(t.fontStyle,e.defaultFontStyle),weight:null,string:""};return i.string=function(t){return!t||D.isNullOrUndef(t.size)||D.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&&D.isArray(o)&&(o=o[n],s=!1),void 0!==o))return i&&!s&&(i.cacheable=!1),o}},V={_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}},H=V;D.log10=V.log10;var B=D,j=P,U=N,G=E,q=H,Z={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]))}};B.easing=j,B.canvas=U,B.options=G,B.math=q,B.rtl=Z;var $=function(t){B.extend(this,t),this.initialize.apply(this,arguments)};B.extend($.prototype,{_type:void 0,initialize:function(){this.hidden=!1},pivot:function(){var t=this;return t._view||(t._view=B.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=w(l)).valid&&(c=w(u)).valid){e[o]=c.mix(h,i).rgbString();continue}}else if(B.isFinite(l)&&B.isFinite(u)){e[o]=l+(u-l)*i;continue}e[o]=u}}(i,a,n,t),e):(e._view=B.extend({},n),e._start=null,e)},tooltipPosition:function(){return{x:this._model.x,y:this._model.y}},hasValue:function(){return B.isNumber(this._model.x)&&B.isNumber(this._model.y)}}),$.extend=B.inherits;var X=$,K=X.extend({chart:null,currentStep:0,numSteps:60,easing:"",render:null,onAnimationProgress:null,onAnimationComplete:null}),J=K;Object.defineProperty(K.prototype,"animationObject",{get:function(){return this}}),Object.defineProperty(K.prototype,"chartInstance",{get:function(){return this.chart},set:function(t){this.chart=t}}),Y._set("global",{animation:{duration:1e3,easing:"easeOutQuart",onProgress:B.noop,onComplete:B.noop}});var Q={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=B.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=B.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),B.callback(t.render,[e,t],e),B.callback(t.onAnimationProgress,[t],e),t.currentStep>=n?(B.callback(t.onAnimationComplete,[t],e),e.animating=!1,a.splice(r,1)):++r}},tt=B.options.resolve,et=["push","pop","shift","splice","unshift"];function nt(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||(et.forEach((function(e){delete t[e]})),delete t._chartjs)}}var it=function(t,e){this.initialize(t,e)};B.extend(it.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&&nt(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&&nt(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]}}),et.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 B.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=B.merge(Object.create(null),[this.chart.options.datasets[this._type],this.getDataset()],{merger:function(t,e,n){"_meta"!==t&&"data"!==t&&B._merger(t,e,n)}})},_update:function(t){this._configure(),this._cachedDataOpts=null,this.update(t)},update:B.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]=tt([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},m={cacheable:!i};if(i=i||{},B.isArray(c))for(o=0,s=c.length;o<s;++o)f[l=c[o]]=tt([i[l],d[l],h[l]],g,e,m);else for(o=0,s=(r=Object.keys(c)).length;o<s;++o)f[l=r[o]]=tt([i[l],d[c[l]],d[l],h[l]],g,e,m);return m.cacheable&&(n._cachedDataOpts=Object.freeze(f)),f},removeHoverStyle:function(t){B.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=B.getHoverColor;t.$previousStyle={backgroundColor:a.backgroundColor,borderColor:a.borderColor,borderWidth:a.borderWidth},a.backgroundColor=tt([i.hoverBackgroundColor,e.hoverBackgroundColor,r(a.backgroundColor)],void 0,n),a.borderColor=tt([i.hoverBorderColor,e.hoverBorderColor,r(a.borderColor)],void 0,n),a.borderWidth=tt([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)}}),it.extend=B.inherits;var at=it,rt=2*Math.PI;function ot(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 st(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+rt,ot(t,n),n.endAngle=r,n.endAngle===n.startAngle&&n.fullCircles&&(n.endAngle+=rt,n.fullCircles--)),t.beginPath(),t.arc(n.x,n.y,n.innerRadius,n.startAngle+rt,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+rt),a=0;a<n.fullCircles;++a)t.stroke()}(t,e,n,i),i&&ot(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()}Y._set("global",{elements:{arc:{backgroundColor:Y.global.defaultColor,borderColor:"#fff",borderWidth:2,borderAlign:"center"}}});var lt=X.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=B.getAngleFromPoint(n,{x:t,y:e}),a=i.angle,r=i.distance,o=n.startAngle,s=n.endAngle;s<o;)s+=rt;for(;a>s;)a-=rt;for(;a<o;)a+=rt;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/rt)};if(e.save(),e.fillStyle=n.backgroundColor,e.strokeStyle=n.borderColor,a.fullCircles){for(a.endAngle=a.startAngle+rt,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%rt}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&&st(e,n,a),e.restore()}}),ut=B.valueOrDefault,dt=Y.global.defaultColor;Y._set("global",{elements:{line:{tension:.4,backgroundColor:dt,borderWidth:3,borderColor:dt,borderCapStyle:"butt",borderDash:[],borderDashOffset:0,borderJoinStyle:"miter",capBezierPoints:!0,fill:!0}}});var ht=X.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=Y.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=B.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=ut(a.borderDashOffset,u.borderDashOffset),r.lineJoin=a.borderJoinStyle||u.borderJoinStyle,r.lineWidth=ut(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?B.previousItem(s,t):s[d],n.skip||(d!==t-1&&!o||-1===d?r.moveTo(n.x,n.y):B.canvas.lineTo(r,e._view,n),d=t);h&&r.closePath(),r.stroke(),r.restore()}}}),ct=B.valueOrDefault,ft=Y.global.defaultColor;function gt(t){var e=this._view;return!!e&&Math.abs(t-e.x)<e.radius+e.hitRadius}Y._set("global",{elements:{point:{radius:3,pointStyle:"circle",backgroundColor:ft,borderColor:ft,borderWidth:1,hitRadius:1,hoverRadius:4,hoverBorderWidth:1}}});var mt=X.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:gt,inXRange:gt,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=Y.global,u=l.defaultColor;e.skip||(void 0===t||B.canvas._isPointInArea(e,t))&&(n.strokeStyle=e.borderColor||u,n.lineWidth=ct(e.borderWidth,l.elements.point.borderWidth),n.fillStyle=e.backgroundColor||u,B.canvas.drawPoint(n,i,r,o,s,a))}}),pt=Y.global.defaultColor;function vt(t){return t&&void 0!==t.width}function bt(t){var e,n,i,a,r;return vt(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 yt(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=yt(e,"left","right")):t.base<t.y&&(e=yt(e,"bottom","top")),n[e]=!0,n):n}(t);return B.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 _t(t,e,n){var i=null===e,a=null===n,r=!(!t||i&&a)&&bt(t);return r&&(i||e>=r.left&&e<=r.right)&&(a||n>=r.top&&n<=r.bottom)}Y._set("global",{elements:{rectangle:{backgroundColor:pt,borderColor:pt,borderSkipped:"bottom",borderWidth:0}}});var wt=X.extend({_type:"rectangle",draw:function(){var t=this._chart.ctx,e=this._view,n=function(t){var e=bt(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 _t(this._view,t,e)},inLabelRange:function(t,e){var n=this._view;return vt(n)?_t(n,t,null):_t(n,null,e)},inXRange:function(t){return _t(this._view,t,null)},inYRange:function(t){return _t(this._view,null,t)},getCenterPoint:function(){var t,e,n=this._view;return vt(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 vt(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={},Mt=lt,St=ht,Dt=mt,Ct=wt;kt.Arc=Mt,kt.Line=St,kt.Point=Dt,kt.Rectangle=Ct;var Pt=B._deprecated,Tt=B.valueOrDefault;function Ot(t,e,n){var i,a,r=n.barThickness,o=e.stackCount,s=e.pixels[t],l=B.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 B.isNullOrUndef(r)?(i=l*n.categoryPercentage,a=n.barPercentage):(i=r*o,a=1),{chunk:i/o,ratio:a,start:s-i/2}}Y._set("bar",{hover:{mode:"label"},scales:{xAxes:[{type:"category",offset:!0,gridLines:{offsetGridLines:!0}}],yAxes:[{type:"linear"}]}}),Y._set("global",{datasets:{bar:{categoryPercentage:.8,barPercentage:.9}}});var At=at.extend({dataElementType:kt.Rectangle,_dataElementOptions:["backgroundColor","borderColor","borderSkipped","borderWidth","barPercentage","barThickness","categoryPercentage","maxBarThickness","minBarLength"],initialize:function(){var t,e,n=this;at.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]},B.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),m=h._parseValue(f[t].data[e]),p=n.minBarLength,v=h.options.stacked,b=this.getMeta().stack,y=void 0===m.start?0:m.max>=0&&m.min>=0?m.min:m.max,x=void 0===m.start?m.end:m.max>=0&&m.min>=0?m.max-m.min:m.min-m.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,(m.min<0&&r<0||m.max>=0&&r>0)&&(y+=r));return o=h.getPixelForValue(y),l=(s=h.getPixelForValue(y+x))-o,void 0!==p&&Math.abs(l)<p&&(l=p,s=x>=0&&!c||x<0&&c?o-p:o+p),{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):Ot(e,n,i),r=this.getStackIndex(t,this.getMeta().stack),o=a.start+a.chunk*r+a.chunk/2,s=Math.min(Tt(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(B.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()}B.canvas.unclipArea(t.ctx)},_resolveDataElementOptions:function(){var t=this,e=B.extend({},at.prototype._resolveDataElementOptions.apply(t,arguments)),n=t._getIndexScale().options,i=t._getValueScale().options;return e.barPercentage=Tt(n.barPercentage,e.barPercentage),e.barThickness=Tt(n.barThickness,e.barThickness),e.categoryPercentage=Tt(n.categoryPercentage,e.categoryPercentage),e.maxBarThickness=Tt(n.maxBarThickness,e.maxBarThickness),e.minBarLength=Tt(i.minBarLength,e.minBarLength),e}}),Ft=B.valueOrDefault,It=B.options.resolve;Y._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 Lt=at.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;B.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=B.getHoverColor;t.$previousStyle={backgroundColor:e.backgroundColor,borderColor:e.borderColor,borderWidth:e.borderWidth,radius:e.radius},e.backgroundColor=Ft(n.hoverBackgroundColor,i(n.backgroundColor)),e.borderColor=Ft(n.hoverBorderColor,i(n.borderColor)),e.borderWidth=Ft(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=at.prototype._resolveDataElementOptions.apply(n,arguments),l={chart:i,dataIndex:e,dataset:a,datasetIndex:n.index};return n._cachedDataOpts===s&&(s=B.extend({},s)),s.radius=It([r.radius,o.r,n._config.radius,i.options.elements.point.radius],l,e),s}}),Rt=B.valueOrDefault,Nt=Math.PI,Wt=2*Nt,Yt=Nt/2;Y._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:-Yt,circumference:Wt,tooltips:{callbacks:{title:function(){return""},label:function(t,e){var n=e.labels[t.index],i=": "+e.datasets[t.datasetIndex].data[t.index];return B.isArray(n)?(n=n.slice())[0]+=i:n+=i,n}}}});var zt=at.extend({dataElementType:kt.Arc,linkScales:B.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,m=l.cutoutPercentage/100||0,p=l.circumference,v=r._getRingWeight(r.index);if(p<Wt){var b=l.rotation%Wt,y=(b+=b>=Nt?-Wt:b<-Nt?Wt:0)+p,x=Math.cos(b),_=Math.sin(b),w=Math.cos(y),k=Math.sin(y),M=b<=0&&y>=0||y>=Wt,S=b<=Yt&&y>=Yt||y>=Wt+Yt,D=b<=-Yt&&y>=-Yt||y>=Nt+Yt,C=b===-Nt||y>=Nt?-1:Math.min(x,x*m,w,w*m),P=D?-1:Math.min(_,_*m,k,k*m),T=M?1:Math.max(x,x*m,w,w*m),O=S?1:Math.max(_,_*m,k,k*m);u=(T-C)/2,d=(O-P)/2,h=-(T+C)/2,c=-(O+P)/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*m,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/Wt),g=n&&s.animateScale?0:i.innerRadius,m=n&&s.animateScale?0:i.outerRadius,p=t._options||{};B.extend(t,{_datasetIndex:i.index,_index:e,_model:{backgroundColor:p.backgroundColor,borderColor:p.borderColor,borderWidth:p.borderWidth,borderAlign:p.borderAlign,x:l+a.offsetX,y:u+a.offsetY,startAngle:d,endAngle:h,circumference:f,outerRadius:m,innerRadius:g,label:B.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 B.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)?Wt*(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=B.getHoverColor;t.$previousStyle={backgroundColor:e.backgroundColor,borderColor:e.borderColor,borderWidth:e.borderWidth},e.backgroundColor=Rt(n.hoverBackgroundColor,i(n.backgroundColor)),e.borderColor=Rt(n.hoverBorderColor,i(n.borderColor)),e.borderWidth=Rt(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(Rt(this.chart.data.datasets[t].weight,1),0)},_getVisibleDatasetWeightTotal:function(){return this._getRingWeightOffset(this.chart.data.datasets.length)}});Y._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"}}),Y._set("global",{datasets:{horizontalBar:{categoryPercentage:.8,barPercentage:.9}}});var Et=At.extend({_getValueScaleId:function(){return this.getMeta().xAxisID},_getIndexScaleId:function(){return this.getMeta().yAxisID}}),Vt=B.valueOrDefault,Ht=B.options.resolve,Bt=B.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 Ut(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 Gt(t){var e,n,i,a;return B.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}}Y._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 qt=at.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=Vt(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:Vt(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=at.prototype._resolveDatasetElementOptions.apply(e,arguments);return o.spanGaps=Vt(n.spanGaps,a.spanGaps),o.tension=Vt(n.lineTension,r.tension),o.steppedLine=Ht([i.steppedLine,n.steppedLine,r.stepped]),o.clip=Gt(Vt(n.clip,Ut(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)B.splineCurveMonotone(l);else for(t=0,e=l.length;t<e;++t)n=l[t]._model,i=B.splineCurve(B.previousItem(l,t)._model,n,B.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,Bt(n,s)&&(t>0&&Bt(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&&Bt(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,B.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(),B.canvas.unclipArea(e.ctx));o<s;++o)i[o].draw(a)},setHoverStyle:function(t){var e=t._model,n=t._options,i=B.getHoverColor;t.$previousStyle={backgroundColor:e.backgroundColor,borderColor:e.borderColor,borderWidth:e.borderWidth,radius:e.radius},e.backgroundColor=Vt(n.hoverBackgroundColor,i(n.backgroundColor)),e.borderColor=Vt(n.hoverBorderColor,i(n.borderColor)),e.borderWidth=Vt(n.hoverBorderWidth,n.borderWidth),e.radius=Vt(n.hoverRadius,n.radius)}}),Zt=B.options.resolve;Y._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 $t=at.extend({dataElementType:kt.Arc,linkScales:B.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],m=g+(t.hidden?0:i._angles[e]),p=s.animateScale?0:l.getDistanceFromCenterForValue(r.data[e]),v=t._options||{};B.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?p:f,startAngle:n&&s.animateRotate?c:g,endAngle:n&&s.animateRotate?c:m,label:B.valueAtIndexOrDefault(u,e,u[e])}}),t.pivot()},countVisibleElements:function(){var t=this.getDataset(),e=this.getMeta(),n=0;return B.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=B.getHoverColor,a=B.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 Zt([e.chart.options.elements.arc.angle,2*Math.PI/n],r,t)}});Y._set("pie",B.clone(Y.doughnut)),Y._set("pie",{cutoutPercentage:0});var Xt=zt,Kt=B.valueOrDefault;Y._set("radar",{spanGaps:!1,scale:{type:"radialLinear"},elements:{line:{fill:"start",tension:0}}});var Jt=at.extend({datasetElementType:kt.Line,dataElementType:kt.Point,linkScales:B.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:Kt(a.tension,u?u.tension:0),hitRadius:l.hitRadius}},_resolveDatasetElementOptions:function(){var t=this,e=t._config,n=t.chart.options,i=at.prototype._resolveDatasetElementOptions.apply(t,arguments);return i.spanGaps=Kt(e.spanGaps,n.spanGaps),i.tension=Kt(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=B.splineCurve(B.previousItem(o,t,!0)._model,n,B.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=B.getHoverColor;t.$previousStyle={backgroundColor:e.backgroundColor,borderColor:e.borderColor,borderWidth:e.borderWidth,radius:e.radius},e.backgroundColor=Kt(n.hoverBackgroundColor,i(n.backgroundColor)),e.borderColor=Kt(n.hoverBorderColor,i(n.borderColor)),e.borderWidth=Kt(n.hoverBorderWidth,n.borderWidth),e.radius=Kt(n.hoverRadius,n.radius)}});Y._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+")"}}}}),Y._set("global",{datasets:{scatter:{showLine:!1}}});var Qt={bar:At,bubble:Lt,doughnut:zt,horizontalBar:Et,line:qt,polarArea:$t,pie:Xt,radar:Jt,scatter:qt};function te(t,e){return t.native?{x:t.x,y:t.y}:B.getRelativePosition(t,e)}function ee(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 ne(t,e){var n=[];return ee(t,(function(t){t.inRange(e.x,e.y)&&n.push(t)})),n}function ie(t,e,n,i){var a=Number.POSITIVE_INFINITY,r=[];return ee(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 ae(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 re(t,e,n){var i=te(e,t);n.axis=n.axis||"x";var a=ae(n.axis),r=n.intersect?ne(t,i):ie(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 oe={modes:{single:function(t,e){var n=te(e,t),i=[];return ee(t,(function(t){if(t.inRange(n.x,n.y))return i.push(t),i})),i.slice(0,1)},label:re,index:re,dataset:function(t,e,n){var i=te(e,t);n.axis=n.axis||"xy";var a=ae(n.axis),r=n.intersect?ne(t,i):ie(t,i,!1,a);return r.length>0&&(r=t.getDatasetMeta(r[0]._datasetIndex).data),r},"x-axis":function(t,e){return re(t,e,{intersect:!1})},point:function(t,e){return ne(t,te(e,t))},nearest:function(t,e,n){var i=te(e,t);n.axis=n.axis||"xy";var a=ae(n.axis);return ie(t,i,n.intersect,a)},x:function(t,e,n){var i=te(e,t),a=[],r=!1;return ee(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=te(e,t),a=[],r=!1;return ee(t,(function(t){t.inYRange(i.y)&&a.push(t),t.inRange(i.x,i.y)&&(r=!0)})),n.intersect&&!r&&(a=[]),a}}},se=B.extend;function le(t,e){return B.where(t,(function(t){return t.pos===e}))}function ue(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 de(t,e,n,i){return Math.max(t[n],e[n])+Math.max(t[i],e[i])}function he(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-de(o,t,"left","right"),a=e.outerHeight-de(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 ce(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 fe(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,ce(r.horizontal,e)),he(e,n,r)&&(l=!0,u.length&&(s=!0)),o.fullWidth||u.push(r);return s&&fe(u,e,n)||l}function ge(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}Y._set("global",{layout:{padding:{top:0,right:0,bottom:0,left:0}}});var me,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=B.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=ue(le(e,"left"),!0),i=ue(le(e,"right")),a=ue(le(e,"top"),!0),r=ue(le(e,"bottom"));return{leftAndTop:n.concat(a),rightAndBottom:i.concat(r),chartArea:le(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=se({maxPadding:se({},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),fe(l,h,d),fe(u,h,d)&&fe(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),ge(s.leftAndTop,h,d),h.x+=h.w,h.y+=h.h,ge(s.rightAndBottom,h,d),t.chartArea={left:h.left,top:h.top,right:h.left+h.w,bottom:h.top+h.h},B.each(s.chartArea,(function(e){var n=e.box;se(n,t.chartArea),n.update(h.w,h.h)}))}}},ve=(me=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}"}))&&me.default||me,be="$chartjs",ye="chartjs-size-monitor",xe="chartjs-render-monitor",_e="chartjs-render-animation",we=["animationstart","webkitAnimationStart"],ke={touchstart:"mousedown",touchmove:"mousemove",touchend:"mouseup",pointerenter:"mouseenter",pointerdown:"mousedown",pointermove:"mousemove",pointerup:"mouseup",pointerleave:"mouseout",pointerout:"mouseout"};function Me(t,e){var n=B.getStyle(t,e),i=n&&n.match(/^(\d+)(\.\d+)?px$/);return i?Number(i[1]):void 0}var Se=!!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 De(t,e,n){t.addEventListener(e,n,Se)}function Ce(t,e,n){t.removeEventListener(e,n,Se)}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 Te(t){var e=document.createElement("div");return e.className=t||"",e}function Oe(t,e,n){var i,a,r,o,s=t[be]||(t[be]={}),l=s.resizer=function(t){var e=Te(ye),n=Te(ye+"-expand"),i=Te(ye+"-shrink");n.appendChild(Te()),i.appendChild(Te()),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 De(n,"scroll",a.bind(n,"expand")),De(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,B.requestAnimFrame.call(window,(function(){r=!1,i.apply(a,o)})))}));!function(t,e){var n=t[be]||(t[be]={}),i=n.renderProxy=function(t){t.animationName===_e&&e()};B.each(we,(function(e){De(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 Ae(t){var e=t[be]||{},n=e.resizer;delete e.resizer,function(t){var e=t[be]||{},n=e.renderProxy;n&&(B.each(we,(function(e){Ce(t,e,n)})),delete e.renderProxy),t.classList.remove(xe)}(t),n&&n.parentNode&&n.parentNode.removeChild(n)}var Fe={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[be]||(t[be]={});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,ve)}},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[be]={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=Me(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=Me(t,"height");void 0!==r&&(t.height=o)}}(t,e),n):null},releaseContext:function(t){var e=t.canvas;if(e[be]){var n=e[be].initial;["height","width"].forEach((function(t){var i=n[t];B.isNullOrUndef(i)?e.removeAttribute(t):e.setAttribute(t,i)})),B.each(n.style||{},(function(t,n){e.style[n]=t})),e.width=e.width,delete e[be]}},addEventListener:function(t,e,n){var i=t.canvas;if("resize"!==e){var a=n[be]||(n[be]={});De(i,e,(a.proxies||(a.proxies={}))[t.id+"_"+e]=function(e){n(function(t,e){var n=ke[t.type]||t.type,i=B.getRelativePosition(t,e);return Pe(n,e,i.x,i.y,t)}(e,t))})}else Oe(i,n,t)},removeEventListener:function(t,e,n){var i=t.canvas;if("resize"!==e){var a=((n[be]||{}).proxies||{})[t.id+"_"+e];a&&Ce(i,e,a)}else Ae(i)}};B.addEvent=De,B.removeEvent=Ce;var Ie=Fe._enabled?Fe:{acquireContext:function(t){return t&&t.canvas&&(t=t.canvas),t&&t.getContext("2d")||null}},Le=B.extend({initialize:function(){},acquireContext:function(){},releaseContext:function(){},addEventListener:function(){},removeEventListener:function(){}},Ie);Y._set("global",{plugins:{}});var Re={_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=B.clone(Y.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}},Ne={constructors:{},defaults:{},registerScaleType:function(t,e,n){this.constructors[t]=e,this.defaults[t]=B.clone(n)},getScaleConstructor:function(t){return this.constructors.hasOwnProperty(t)?this.constructors[t]:void 0},getScaleDefaults:function(t){return this.defaults.hasOwnProperty(t)?B.merge(Object.create(null),[Y.scale,this.defaults[t]]):{}},updateScaleDefaults:function(t,e){this.defaults.hasOwnProperty(t)&&(this.defaults[t]=B.extend(this.defaults[t],e))},addScalesToLayout:function(t){B.each(t.scales,(function(e){e.fullWidth=e.options.fullWidth,e.position=e.options.position,e.weight=e.options.weight,pe.addBox(t,e)}))}},We=B.valueOrDefault,Ye=B.rtl.getRtlAdapter;Y._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:B.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:B.noop,beforeBody:B.noop,beforeLabel:B.noop,label:function(t,e){var n=e.datasets[t.datasetIndex].label||"";return n&&(n+=": "),B.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:B.noop,afterBody:B.noop,beforeFooter:B.noop,footer:B.noop,afterFooter:B.noop}}});var ze={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=B.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&&(B.isArray(e)?Array.prototype.push.apply(t,e):t.push(e)),t}function Ve(t){return("string"==typeof t||t instanceof String)&&t.indexOf("\n")>-1?t.split("\n"):t}function He(t){var e=Y.global;return{xPadding:t.xPadding,yPadding:t.yPadding,xAlign:t.xAlign,yAlign:t.yAlign,rtl:t.rtl,textDirection:t.textDirection,bodyFontColor:t.bodyFontColor,_bodyFontFamily:We(t.bodyFontFamily,e.defaultFontFamily),_bodyFontStyle:We(t.bodyFontStyle,e.defaultFontStyle),_bodyAlign:t.bodyAlign,bodyFontSize:We(t.bodyFontSize,e.defaultFontSize),bodySpacing:t.bodySpacing,titleFontColor:t.titleFontColor,_titleFontFamily:We(t.titleFontFamily,e.defaultFontFamily),_titleFontStyle:We(t.titleFontStyle,e.defaultFontStyle),titleFontSize:We(t.titleFontSize,e.defaultFontSize),_titleAlign:t.titleAlign,titleSpacing:t.titleSpacing,titleMarginBottom:t.titleMarginBottom,footerFontColor:t.footerFontColor,_footerFontFamily:We(t.footerFontFamily,e.defaultFontFamily),_footerFontStyle:We(t.footerFontStyle,e.defaultFontStyle),footerFontSize:We(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 Be(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([],Ve(t))}var Ue=X.extend({initialize:function(){this._model=He(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,Ve(i)),o=Ee(o,Ve(a)),o=Ee(o,Ve(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 B.each(t,(function(t){var r={before:[],lines:[],after:[]};Ee(r.before,Ve(i.beforeLabel.call(n,t,e))),Ee(r.lines,i.label.call(n,t,e)),Ee(r.after,Ve(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,Ve(n)),r=Ee(r,Ve(i)),r=Ee(r,Ve(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=He(c),m=h._active,p=h._data,v={xAlign:f.xAlign,yAlign:f.yAlign},b={x:f.x,y:f.y},y={width:f.width,height:f.height},x={x:f.caretX,y:f.caretY};if(m.length){g.opacity=1;var _=[],w=[];x=ze[c.position].call(h,m,h._eventPosition);var k=[];for(e=0,n=m.length;e<n;++e)k.push((i=m[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&&(k=k.filter((function(t){return c.filter(t,p)}))),c.itemSort&&(k=k.sort((function(t,e){return c.itemSort(t,e,p)}))),B.each(k,(function(t){_.push(c.callbacks.labelColor.call(h,t,h._chart)),w.push(c.callbacks.labelTextColor.call(h,t,h._chart))})),g.title=h.getTitle(k,p),g.beforeBody=h.getBeforeBody(k,p),g.body=h.getBody(k,p),g.afterBody=h.getAfterBody(k,p),g.footer=h.getFooter(k,p),g.x=x.x,g.y=x.y,g.caretPadding=c.caretPadding,g.labelColors=_,g.labelTextColors=w,g.dataPoints=k,y=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=B.fontString(u,e._titleFontStyle,e._titleFontFamily),B.each(e.title,f),n.font=B.fontString(d,e._bodyFontStyle,e._bodyFontFamily),B.each(e.beforeBody.concat(e.afterBody),f),c=e.displayColors?d+2:0,B.each(r,(function(t){B.each(t.before,f),B.each(t.lines,f),B.each(t.after,f)})),c=0,n.font=B.fontString(h,e._footerFontStyle,e._footerFontFamily),B.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,y,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,y),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=y.width,g.height=y.height,g.caretX=x.x,g.caretY=x.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,m=e.width,p=e.height;if("center"===c)s=g+p/2,"left"===h?(a=(i=f)-u,r=i,o=s+u,l=s-u):(a=(i=f+m)+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+m-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+p)+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=Ye(e.rtl,e.x,e.width);for(t.x=Be(e,e._titleAlign),n.textAlign=l.textAlign(e._titleAlign),n.textBaseline="middle",i=e.titleFontSize,a=e.titleSpacing,n.fillStyle=e.titleFontColor,n.font=B.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,m=e.displayColors,p=0,v=m?Be(e,"left"):0,b=Ye(e.rtl,e.x,e.width),y=function(e){n.fillText(e,b.x(t.x+p),t.y+h/2),t.y+=h+c},x=b.textAlign(f);for(n.textAlign=f,n.textBaseline="middle",n.font=B.fontString(h,e._bodyFontStyle,e._bodyFontFamily),t.x=Be(e,x),n.fillStyle=e.bodyFontColor,B.each(e.beforeBody,y),p=m&&"right"!==x?"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,B.each(i.before,y),l=0,d=(o=i.lines).length;l<d;++l){if(m){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}y(o[l])}B.each(i.after,y)}p=0,B.each(e.afterBody,y),t.y-=c},drawFooter:function(t,e,n){var i,a,r=e.footer,o=r.length;if(o){var s=Ye(e.rtl,e.x,e.width);for(t.x=Be(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=B.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,B.rtl.overrideTextDirection(t,e.textDirection),this.drawTitle(i,e,t),this.drawBody(i,e,t),this.drawFooter(i,e,t),B.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=!B.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}}),Ge=ze,qe=Ue;qe.positioners=Ge;var Ze=B.valueOrDefault;function $e(){return B.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=Ze(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?B.merge(e[t][a],[Ne.getScaleDefaults(r),o]):B.merge(e[t][a],o)}else B._merger(t,e,n,i)}})}function Xe(){return B.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]=$e(a,r):"scale"===t?e[t]=B.merge(a,[Ne.getScaleDefaults(r.type),r]):B._merger(t,e,n,i)}})}function Ke(t){var e=t.options;B.each(t.scales,(function(e){pe.removeBox(t,e)})),e=Xe(Y.global,Y[t.config.type],e),t.options=t.config.options=e,t.ensureScalesHaveIDs(),t.buildOrUpdateScales(),t.tooltip._options=e.tooltips,t.tooltip.initialize()}function Je(t,e,n){var i,a=function(t){return t.id===i};do{i=e+n++}while(B.findIndex(t,a)>=0);return i}function Qe(t){return"top"===t||"bottom"===t}function tn(t,e){return function(n,i){return n[t]===i[t]?n[e]-i[e]:n[t]-i[t]}}Y._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 en=function(t,e){return this.construct(t,e),this};B.extend(en.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=Xe(Y.global,Y[t.type],t.options||{}),t}(e);var i=Le.acquireContext(t,e),a=i&&i.canvas,r=a&&a.height,o=a&&a.width;n.id=B.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,en.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 Re.notify(t,"beforeInit"),B.retinaScale(t,t.options.devicePixelRatio),t.bindEvents(),t.options.responsive&&t.resize(!0),t.initToolTip(),Re.notify(t,"afterInit"),t},clear:function(){return B.canvas.clear(this),this},stop:function(){return Q.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(B.getMaximumWidth(i))),o=Math.max(0,Math.floor(a?r/a:B.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",B.retinaScale(e,n.devicePixelRatio),!t)){var s={width:r,height:o};Re.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;B.each(e.xAxes,(function(t,n){t.id||(t.id=Je(e.xAxes,"x-axis-",n))})),B.each(e.yAxes,(function(t,n){t.id||(t.id=Je(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"}),B.each(i,(function(e){var i=e.options,r=i.id,o=Ze(i.type,e.dtype);Qe(i.position)!==Qe(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=Ne.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)})),B.each(a,(function(t,e){t||delete n[e]})),t.scales=n,Ne.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=Qt[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;B.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]}),Ke(i),Re._invalidate(i),!1!==Re.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&&B.each(a,(function(t){t.reset()})),i.updateDatasets(),i.tooltip.initialize(),i.lastActive=[],Re.notify(i,"afterUpdate"),i._layers.sort(tn("z","_idx")),i._bufferedRender?i._bufferedRequest={duration:t.duration,easing:t.easing,lazy:t.lazy}:i.render(t)}},updateLayout:function(){var t=this;!1!==Re.notify(t,"beforeLayout")&&(pe.update(this,this.width,this.height),t._layers=[],B.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})),Re.notify(t,"afterScaleUpdate"),Re.notify(t,"afterLayout"))},updateDatasets:function(){if(!1!==Re.notify(this,"beforeDatasetsUpdate")){for(var t=0,e=this.data.datasets.length;t<e;++t)this.updateDataset(t);Re.notify(this,"afterDatasetsUpdate")}},updateDataset:function(t){var e=this.getDatasetMeta(t),n={meta:e,index:t};!1!==Re.notify(this,"beforeDatasetUpdate",[n])&&(e.controller._update(),Re.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=Ze(t.duration,n&&n.duration),a=t.lazy;if(!1!==Re.notify(e,"beforeRender")){var r=function(t){Re.notify(e,"afterRender"),B.callback(n&&n.onComplete,[t],e)};if(n&&i){var o=new J({numSteps:i/16.66,easing:t.easing||n.easing,render:function(t,e){var n=B.easing.effects[e.easing],i=e.currentStep,a=i/e.numSteps;t.draw(n(a),a,i)},onAnimationProgress:n.onProgress,onAnimationComplete:r});Q.addAnimation(e,o,i,a)}else e.draw(),r(new J({numSteps:0,chart:e}));return e}},draw:function(t){var e,n,i=this;if(i.clear(),B.isNullOrUndef(t)&&(t=1),i.transition(t),!(i.width<=0||i.height<=0)&&!1!==Re.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),Re.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(tn("order","index")),i},_getSortedVisibleDatasetMetas:function(){return this._getSortedDatasetMetas(!0)},drawDatasets:function(t){var e,n;if(!1!==Re.notify(this,"beforeDatasetsDraw",[t])){for(n=(e=this._getSortedVisibleDatasetMetas()).length-1;n>=0;--n)this.drawDataset(e[n],t);Re.notify(this,"afterDatasetsDraw",[t])}},drawDataset:function(t,e){var n={meta:t,index:t.index,easingValue:e};!1!==Re.notify(this,"beforeDatasetDraw",[n])&&(t.controller.draw(e),Re.notify(this,"afterDatasetDraw",[n]))},_drawTooltip:function(t){var e=this.tooltip,n={tooltip:e,easingValue:t};!1!==Re.notify(this,"beforeTooltipDraw",[n])&&(e.draw(),Re.notify(this,"afterTooltipDraw",[n]))},getElementAtEvent:function(t){return oe.modes.single(this,t)},getElementsAtEvent:function(t){return oe.modes.label(this,t,{intersect:!0})},getElementsAtXAxis:function(t){return oe.modes["x-axis"](this,t,{intersect:!0})},getElementsAtEventForMode:function(t,e,n){var i=oe.modes[e];return"function"==typeof i?i(this,t,n):[]},getDatasetAtEvent:function(t){return oe.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(),B.canvas.clear(n),Le.releaseContext(n.ctx),n.canvas=null,n.ctx=null),Re.notify(n,"destroy"),delete en.instances[n.id]},toBase64Image:function(){return this.canvas.toDataURL.apply(this.canvas,arguments)},initToolTip:function(){var t=this;t.tooltip=new qe({_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)};B.each(t.options.events,(function(i){Le.addEventListener(t,i,n),e[i]=n})),t.options.responsive&&(n=function(){t.resize()},Le.addEventListener(t,"resize",n),e.resize=n)},unbindEvents:function(){var t=this,e=t._listeners;e&&(delete t._listeners,B.each(e,(function(e,n){Le.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!==Re.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)),Re.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),B.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=!B.arrayEquals(n.active,n.lastActive),n.lastActive=n.active,e}}),en.instances={};var nn=en;en.Controller=en,en.types={},B.configMerge=Xe,B.scaleMerge=$e;function an(){throw new Error("This method is not implemented: either no adapter can be found or an incomplete integration was provided.")}function rn(t){this.options=t||{}}B.extend(rn.prototype,{formats:an,parse:an,format:an,add:an,diff:an,startOf:an,endOf:an,_create:function(t){return t}}),rn.override=function(t){B.extend(rn.prototype,t)};var on={_date:rn},sn={formatters:{values:function(t){return B.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=B.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=B.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(B.log10(t)));return 0===t?"0":1===i||2===i||5===i||0===e||e===n.length-1?t.toExponential():""}}},ln=B.isArray,un=B.isNullOrUndef,dn=B.valueOrDefault,hn=B.valueAtIndexOrDefault;function cn(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 fn(t,e,n,i){var a,r,o,s,l,u,d,h,c,f,g,m,p,v=n.length,b=[],y=[],x=[],_=0,w=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,un(s)||ln(s)){if(ln(s))for(r=0,o=s.length;r<o;++r)g=s[r],un(g)||ln(g)||(c=B.measureText(t,d.data,d.gc,c,g),f+=h)}else c=B.measureText(t,d.data,d.gc,c,s),f=h;b.push(c),y.push(f),x.push(h/2),_=Math.max(c,_),w=Math.max(f,w)}function k(t){return{width:b[t]||0,height:y[t]||0,offset:x[t]||0}}return function(t,e){B.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),m=b.indexOf(_),p=y.indexOf(w),{first:k(0),last:k(v-1),widest:k(m),highest:k(p)}}function gn(t){return t.drawTicks?t.tickMarkLength:0}function mn(t){var e,n;return t.display?(e=B.options._parseFont(t),n=B.options.toPadding(t.padding),e.lineHeight+n.height):0}function pn(t,e){return B.extend(B.options._parseFont({fontFamily:dn(e.fontFamily,t.fontFamily),fontSize:dn(e.fontSize,t.fontSize),fontStyle:dn(e.fontStyle,t.fontStyle),lineHeight:dn(e.lineHeight,t.lineHeight)}),{color:B.options.resolve([e.fontColor,t.fontColor,Y.global.defaultFontColor])})}function vn(t){var e=pn(t,t.minor);return{minor:e,major:t.major.enabled?pn(t,t.major):e}}function bn(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 yn(t,e,n,i){var a,r,o,s,l=dn(n,0),u=Math.min(dn(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}Y._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:sn.formatters.values,minor:{},major:{}}});var xn=X.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(){B.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=B.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(){B.callback(this.options.afterUpdate,[this])},beforeSetDimensions:function(){B.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(){B.callback(this.options.afterSetDimensions,[this])},beforeDataLimits:function(){B.callback(this.options.beforeDataLimits,[this])},determineDataLimits:B.noop,afterDataLimits:function(){B.callback(this.options.afterDataLimits,[this])},beforeBuildTicks:function(){B.callback(this.options.beforeBuildTicks,[this])},buildTicks:B.noop,afterBuildTicks:function(t){var e=this;return ln(t)&&t.length?B.callback(e.options.afterBuildTicks,[e,t]):(e.ticks=B.callback(e.options.afterBuildTicks,[e,e.ticks])||e.ticks,t)},beforeTickToLabelConversion:function(){B.callback(this.options.beforeTickToLabelConversion,[this])},convertTicksToLabels:function(){var t=this.options.ticks;this.ticks=this.ticks.map(t.userCallback||t.callback,this)},afterTickToLabelConversion:function(){B.callback(this.options.afterTickToLabelConversion,[this])},beforeCalculateTickRotation:function(){B.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-gn(l.gridLines)-u.padding-mn(l.scaleLabel),o=Math.sqrt(e*e+n*n),f=B.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(){B.callback(this.options.afterCalculateTickRotation,[this])},beforeFit:function(){B.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=gn(o)+mn(r)),u?s&&(e.height=gn(o)+mn(r)):e.height=t.maxHeight,a.display&&s){var d=vn(a),h=t._getLabelSizes(),c=h.first,f=h.last,g=h.widest,m=h.highest,p=.4*d.minor.lineHeight,v=a.padding;if(u){var b=0!==t.labelRotation,y=B.toRadians(t.labelRotation),x=Math.cos(y),_=Math.sin(y),w=_*g.width+x*(m.height-(b?m.offset:0))+(b?0:p);e.height=Math.min(t.maxHeight,e.height+w+v);var k,M,S=t.getPixelForTick(0)-t.left,D=t.right-t.getPixelForTick(t.getTicks().length-1);b?(k=l?x*c.width+_*c.offset:_*(c.height-c.offset),M=l?_*(f.height-f.offset):x*f.width+_*f.offset):(k=c.width/2,M=f.width/2),t.paddingLeft=Math.max((k-S)*t.width/(t.width-S),0)+3,t.paddingRight=Math.max((M-D)*t.width/(t.width-D),0)+3}else{var C=a.mirror?0:g.width+v+p;e.width=Math.min(t.maxWidth,e.width+C),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(){B.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(un(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=fn(t.ctx,vn(t.options.ticks),t.getTicks(),t.longestTextCache),t.longestLabelWidth=e.widest.width),e},_parseValue:function(t){var e,n,i,a;return ln(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:B.noop,getPixelForValue:B.noop,getValueForPixel:B.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),bn(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=B.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++)yn(t,i,l[e],l[e+1]);return a=u>1?(h-d)/(u-1):null,yn(t,i,B.isNullOrUndef(a)?0:d-a,d),yn(t,i,h,B.isNullOrUndef(a)?t.length:h+a),bn(t)}return yn(t,i),bn(t)},_tickSize:function(){var t=this.options.ticks,e=B.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,m,p,v,b=this,y=b.chart,x=b.options,_=x.gridLines,w=x.position,k=_.offsetGridLines,M=b.isHorizontal(),S=b._ticksToDraw,D=S.length+(k?1:0),C=gn(_),P=[],T=_.drawBorder?hn(_.lineWidth,0,0):0,O=T/2,A=B._alignPixel,F=function(t){return A(y,t,T)};for("top"===w?(e=F(b.bottom),s=b.bottom-C,u=e-O,h=F(t.top)+O,f=t.bottom):"bottom"===w?(e=F(b.top),h=t.top,f=F(t.bottom)-O,s=e+O,u=b.top+C):"left"===w?(e=F(b.right),o=b.right-C,l=e-O,d=F(t.left)+O,c=t.right):(e=F(b.left),d=t.left,c=F(t.right)-O,o=e+O,l=b.left+C),n=0;n<D;++n)i=S[n]||{},un(i.label)&&n<S.length||(n===b.zeroLineIndex&&x.offset===k?(g=_.zeroLineWidth,m=_.zeroLineColor,p=_.zeroLineBorderDash||[],v=_.zeroLineBorderDashOffset||0):(g=hn(_.lineWidth,n,1),m=hn(_.color,n,"rgba(0,0,0,0.1)"),p=_.borderDash||[],v=_.borderDashOffset||0),void 0!==(a=cn(b,i._index||n,k))&&(r=A(y,a,g),M?o=l=d=c=r:s=u=h=f=r,P.push({tx1:o,ty1:s,tx2:l,ty2:u,x1:d,y1:h,x2:c,y2:f,width:g,color:m,borderDash:p,borderDashOffset:v})));return P.ticksLength=D,P.borderValue=e,P},_computeLabelItems:function(){var t,e,n,i,a,r,o,s,l,u,d,h,c=this,f=c.options,g=f.ticks,m=f.position,p=g.mirror,v=c.isHorizontal(),b=c._ticksToDraw,y=vn(g),x=g.padding,_=gn(f.gridLines),w=-B.toRadians(c.labelRotation),k=[];for("top"===m?(r=c.bottom-_-x,o=w?"left":"center"):"bottom"===m?(r=c.top+_+x,o=w?"right":"center"):"left"===m?(a=c.right-(p?0:_)-x,o=p?"left":"right"):(a=c.left+(p?0:_)+x,o=p?"right":"left"),t=0,e=b.length;t<e;++t)i=(n=b[t]).label,un(i)||(s=c.getPixelForTick(n._index||t)+g.labelOffset,u=(l=n.major?y.major:y.minor).lineHeight,d=ln(i)?i.length:1,v?(a=s,h="top"===m?((w?1:.5)-d)*u:(w?0:.5)*u):(r=s,h=(1-d)*u/2),k.push({x:a,y:r,rotation:w,label:i,font:l,textOffset:h,textAlign:o}));return k},_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=B._alignPixel,h=n.drawBorder?hn(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,m,p,v=h,b=hn(n.lineWidth,c.ticksLength-1,1),y=c.borderValue;e.isHorizontal()?(f=d(u,e.left,v)-v/2,g=d(u,e.right,b)+b/2,m=p=y):(m=d(u,e.top,v)-v/2,p=d(u,e.bottom,b)+b/2,f=g=y),l.lineWidth=h,l.strokeStyle=hn(n.color,0),l.beginPath(),l.moveTo(f,m),l.lineTo(g,p),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,ln(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=dn(i.fontColor,Y.global.defaultFontColor),s=B.options._parseFont(i),l=B.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 _n=xn,wn=B.isNullOrUndef,kn=_n.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;_n.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 wn(e)||wn(n)||(t=o.chart.data.datasets[n].data[e]),wn(t)||(i=o.isHorizontal()?t.x:t.y),(void 0!==i||void 0!==t&&isNaN(e))&&(a=o._getLabels(),t=B.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}}),Mn={position:"bottom"};kn._defaults=Mn;var Sn=B.noop,Dn=B.isNullOrUndef;var Cn=_n.extend({getRightValue:function(t){return"string"==typeof t?+t:_n.prototype.getRightValue.call(this,t)},handleTickRangeOptions:function(){var t=this,e=t.options.ticks;if(e.beginAtZero){var n=B.sign(t.min),i=B.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:Sn,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:B.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,m=B.niceNum((g-f)/u/l)*l;if(m<1e-14&&Dn(d)&&Dn(h))return[f,g];(r=Math.ceil(g/m)-Math.floor(f/m))>u&&(m=B.niceNum(r*m/u/l)*l),s||Dn(c)?n=Math.pow(10,B._decimalPlaces(m)):(n=Math.pow(10,c),m=Math.ceil(m*n)/n),i=Math.floor(f/m)*m,a=Math.ceil(g/m)*m,s&&(!Dn(d)&&B.almostWhole(d/m,m/1e3)&&(i=d),!Dn(h)&&B.almostWhole(h/m,m/1e3)&&(a=h)),r=(a-i)/m,r=B.almostEquals(r,Math.round(r),m/1e3)?Math.round(r):Math.ceil(r),i=Math.round(i*n)/n,a=Math.round(a*n)/n,o.push(Dn(d)?i:d);for(var p=1;p<r;++p)o.push(Math.round((i+p*m)*n)/n);return o.push(Dn(h)?a:h),o}(i,t);t.handleDirectionalChanges(),t.max=B.max(a),t.min=B.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),_n.prototype.convertTicksToLabels.call(t)},_configure:function(){var t,e=this,n=e.getTicks(),i=e.min,a=e.max;_n.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:sn.formatters.linear}};function Tn(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 On(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 An=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?Tn(a,u,e,n):On(a,e,n);B.each(u,(function(t){i=t.pos.concat(t.neg),a.min=Math.min(a.min,B.min(i)),a.max=Math.max(a.max,B.max(i))})),a.min=B.isFinite(a.min)&&!isNaN(a.min)?a.min:0,a.max=B.isFinite(a.max)&&!isNaN(a.max)?a.max:1,a.handleTickRangeOptions()},_computeTickLimit:function(){var t;return this.isHorizontal()?Math.ceil(this.width/40):(t=B.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])}}),Fn=Pn;An._defaults=Fn;var In=B.valueOrDefault,Ln=B.math.log10;var Rn={position:"left",ticks:{callback:sn.formatters.logarithmic}};function Nn(t,e){return B.isFinite(t)&&t>=0?t:e}var Wn=_n.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 m=f[g];n=o._parseValue(i[a]),isNaN(n.min)||isNaN(n.max)||e.data[a].hidden||n.min<0||n.max<0||(m[a]=m[a]||0,m[a]+=n.max)}}B.each(f,(function(t){if(t.length>0){var e=B.min(t),n=B.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=B.isFinite(o.min)?o.min:null,o.max=B.isFinite(o.max)?o.max:null,o.minNotZero=B.isFinite(o.minNotZero)?o.minNotZero:null,this.handleTickRangeOptions()},handleTickRangeOptions:function(){var t=this,e=t.options.ticks;t.min=Nn(e.min,t.min),t.max=Nn(e.max,t.max),t.min===t.max&&(0!==t.min&&null!==t.min?(t.min=Math.pow(10,Math.floor(Ln(t.min))-1),t.max=Math.pow(10,Math.floor(Ln(t.max))+1)):(t.min=1,t.max=10)),null===t.min&&(t.min=Math.pow(10,Math.floor(Ln(t.max))-1)),null===t.max&&(t.max=0!==t.min?Math.pow(10,Math.floor(Ln(t.min))+1):10),null===t.minNotZero&&(t.min>0?t.minNotZero=t.min:t.max<1?t.minNotZero=Math.pow(10,Math.floor(Ln(t.max))):t.minNotZero=1)},buildTicks:function(){var t=this,e=t.options.ticks,n=!t.isHorizontal(),i={min:Nn(e.min),max:Nn(e.max)},a=t.ticks=function(t,e){var n,i,a=[],r=In(t.min,Math.pow(10,Math.floor(Ln(e.min)))),o=Math.floor(Ln(e.max)),s=Math.ceil(e.max/Math.pow(10,o));0===r?(n=Math.floor(Ln(e.minNotZero)),i=Math.floor(e.minNotZero/Math.pow(10,n)),a.push(r),r=i*Math.pow(10,n)):(n=Math.floor(Ln(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=In(t.max,r);return a.push(u),a}(i,t);t.max=B.max(a),t.min=B.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(),_n.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(Ln(t));return Math.floor(t/Math.pow(10,e))*Math.pow(10,e)},_configure:function(){var t=this,e=t.min,n=0;_n.prototype._configure.call(t),0===e&&(e=t._getFirstTickValue(t.minNotZero),n=In(t.options.ticks.fontSize,Y.global.defaultFontSize)/t._length),t._startValue=Ln(e),t._valueOffset=n,t._valueRange=(Ln(t.max)-Ln(e))/(1-n)},getPixelForValue:function(t){var e=this,n=0;return(t=+e.getRightValue(t))>e.min&&t>0&&(n=(Ln(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)}}),Yn=Rn;Wn._defaults=Yn;var zn=B.valueOrDefault,En=B.valueAtIndexOrDefault,Vn=B.options.resolve,Hn={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:sn.formatters.linear},pointLabels:{display:!0,fontSize:10,callback:function(t){return t}}};function Bn(t){var e=t.ticks;return e.display&&t.display?zn(e.fontSize,Y.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 Un(t){return 0===t||180===t?"center":t<180?"left":"right"}function Gn(t,e,n,i){var a,r,o=n.y+i/2;if(B.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 qn(t,e,n){90===t||270===t?n.y-=e.h/2:(t>270||t<90)&&(n.y-=e.h)}function Zn(t){return B.isNumber(t)?t:0}var $n=Cn.extend({setDimensions:function(){var t=this;t.width=t.maxWidth,t.height=t.maxHeight,t.paddingTop=Bn(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;B.each(e.data.datasets,(function(a,r){if(e.isDatasetVisible(r)){var o=e.getDatasetMeta(r);B.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/Bn(this.options))},convertTicksToLabels:function(){var t=this;Cn.prototype.convertTicksToLabels.call(t),t.pointLabels=t.chart.data.labels.map((function(){var e=B.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=B.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=B.isArray(u)?{w:B.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=B.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=Zn(a),r=Zn(r),o=Zn(o),s=Zn(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(B.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=zn(s.lineWidth,o.lineWidth),u=zn(s.color,o.color);if(r.pointLabels.display&&function(t){var e=t.ctx,n=t.options,i=n.pointLabels,a=Bn(n),r=t.getDistanceFromCenterForValue(n.ticks.reverse?t.min:t.max),o=B.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,Y.global.defaultFontColor);e.fillStyle=d;var h=t.getIndexAngle(s),c=B.toDegrees(h);e.textAlign=Un(c),qn(c,t._pointLabelSizes[s],u),Gn(e,t.pointLabels[s],u,o.lineHeight)}e.restore()}(i),o.display&&B.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(Vn([s.borderDash,o.borderDash,[]])),a.lineDashOffset=Vn([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=B.options._parseFont(n),s=zn(n.fontColor,Y.global.defaultFontColor);e.save(),e.font=o.string,e.translate(t.xCenter,t.yCenter),e.rotate(r),e.textAlign="center",e.textBaseline="middle",B.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:B.noop}),Xn=Hn;$n._defaults=Xn;var Kn=B._deprecated,Jn=B.options.resolve,Qn=B.valueOrDefault,ti=Number.MIN_SAFE_INTEGER||-9007199254740991,ei=Number.MAX_SAFE_INTEGER||9007199254740991,ni={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}},ii=Object.keys(ni);function ai(t,e){return t-e}function ri(t){return B.valueOrDefault(t.time.min,t.ticks.min)}function oi(t){return B.valueOrDefault(t.time.max,t.ticks.max)}function si(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 li(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)),B.isFinite(o)||(o="string"==typeof r?n.parse(o,r):n.parse(o)),null!==o?+o:(a||"function"!=typeof r||(o=r(e),B.isFinite(o)||(o=n.parse(o))),o)}function ui(t,e){if(B.isNullOrUndef(e))return null;var n=t.options.time,i=li(t,t.getRightValue(e));return null===i?i:(n.round&&(i=+t._adapter.startOf(i,n.round)),i)}function di(t,e,n,i){var a,r,o,s=ii.length;for(a=ii.indexOf(t);a<s-1;++a)if(o=(r=ni[ii[a]]).steps?r.steps:ei,r.common&&Math.ceil((n-e)/(o*r.size))<=i)return ii[a];return ii[s-1]}function hi(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 ci=_n.extend({initialize:function(){this.mergeTicksOptions(),_n.prototype.initialize.call(this)},update:function(){var t=this,e=t.options,n=e.time||(e.time={}),i=t._adapter=new on._date(e.adapters.date);return Kn("time scale",n.format,"time.format","time.parser"),Kn("time scale",n.min,"time.min","ticks.min"),Kn("time scale",n.max,"time.max","ticks.max"),B.mergeIf(n.displayFormats,i.formats()),_n.prototype.update.apply(t,arguments)},getRightValue:function(t){return t&&void 0!==t.t&&(t=t.t),_n.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=ei,f=ti,g=[],m=[],p=[],v=s._getLabels();for(t=0,n=v.length;t<n;++t)p.push(ui(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,B.isObject(a[0]))for(m[t]=[],e=0,i=a.length;e<i;++e)r=ui(s,a[e]),g.push(r),m[t][e]=r;else m[t]=p.slice(0),o||(g=g.concat(p),o=!0);else m[t]=[];p.length&&(c=Math.min(c,p[0]),f=Math.max(f,p[p.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(ai):g.sort(ai),c=Math.min(c,g[0]),f=Math.max(f,g[g.length-1])),c=ui(s,ri(d))||c,f=ui(s,oi(d))||f,c=c===ei?+u.startOf(Date.now(),h):c,f=f===ti?+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:m,labels:p}},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||di(s.minUnit,e,n,i),u=Jn([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=ui(i,ri(o))||a,r=ui(i,oi(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?di(l.minUnit,i.min,i.max,h):function(t,e,n,i,a){var r,o;for(r=ii.length-1;r>=ii.indexOf(n);r--)if(o=ii[r],ni[o].common&&t._adapter.diff(a,i,o)>=e-1)return o;return ii[n?ii.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=ii.indexOf(t)+1,n=ii.length;e<n;++e)if(ni[ii[e]].common)return ii[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=si(t,"time",e[0],"pos"),s=1===e.length?1-r:(si(t,"time",e[1],"pos")-r)/2,o=si(t,"time",e[e.length-1],"pos"),l=1===e.length?o:(o-si(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(),hi(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 B.isObject(s)&&(o=n.getRightValue(s)),r.tooltipFormat?i.format(li(n,o),r.tooltipFormat):"string"==typeof o?o:i.format(li(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,m=Jn([g.callback,g.userCallback,h.callback,h.userCallback]);return m?m(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=si(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=ui(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=si(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=B.toRadians(this.isHorizontal()?e.maxRotation:e.minRotation),a=Math.cos(i),r=Math.sin(i),o=Qn(e.fontSize,Y.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,hi(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}}),fi={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}}};ci._defaults=fi;var gi={category:kn,linear:An,logarithmic:Wn,radialLinear:$n,time:ci},mi=e((function(e,n){e.exports=function(){var n,i;function a(){return n.apply(null,arguments)}function r(t){return t instanceof Array||"[object Array]"===Object.prototype.toString.call(t)}function o(t){return null!=t&&"[object Object]"===Object.prototype.toString.call(t)}function s(t){return void 0===t}function l(t){return"number"==typeof t||"[object Number]"===Object.prototype.toString.call(t)}function u(t){return t instanceof Date||"[object Date]"===Object.prototype.toString.call(t)}function d(t,e){var n,i=[];for(n=0;n<t.length;++n)i.push(e(t[n],n));return i}function h(t,e){return Object.prototype.hasOwnProperty.call(t,e)}function c(t,e){for(var n in e)h(e,n)&&(t[n]=e[n]);return h(e,"toString")&&(t.toString=e.toString),h(e,"valueOf")&&(t.valueOf=e.valueOf),t}function f(t,e,n,i){return Ie(t,e,n,i,!0).utc()}function g(t){return null==t._pf&&(t._pf={empty:!1,unusedTokens:[],unusedInput:[],overflow:-2,charsLeftOver:0,nullInput:!1,invalidMonth:null,invalidFormat:!1,userInvalidated:!1,iso:!1,parsedDateParts:[],meridiem:null,rfc2822:!1,weekdayMismatch:!1}),t._pf}function m(t){if(null==t._isValid){var e=g(t),n=i.call(e.parsedDateParts,(function(t){return null!=t})),a=!isNaN(t._d.getTime())&&e.overflow<0&&!e.empty&&!e.invalidMonth&&!e.invalidWeekday&&!e.weekdayMismatch&&!e.nullInput&&!e.invalidFormat&&!e.userInvalidated&&(!e.meridiem||e.meridiem&&n);if(t._strict&&(a=a&&0===e.charsLeftOver&&0===e.unusedTokens.length&&void 0===e.bigHour),null!=Object.isFrozen&&Object.isFrozen(t))return a;t._isValid=a}return t._isValid}function p(t){var e=f(NaN);return null!=t?c(g(e),t):g(e).userInvalidated=!0,e}i=Array.prototype.some?Array.prototype.some:function(t){for(var e=Object(this),n=e.length>>>0,i=0;i<n;i++)if(i in e&&t.call(this,e[i],i,e))return!0;return!1};var v=a.momentProperties=[];function b(t,e){var n,i,a;if(s(e._isAMomentObject)||(t._isAMomentObject=e._isAMomentObject),s(e._i)||(t._i=e._i),s(e._f)||(t._f=e._f),s(e._l)||(t._l=e._l),s(e._strict)||(t._strict=e._strict),s(e._tzm)||(t._tzm=e._tzm),s(e._isUTC)||(t._isUTC=e._isUTC),s(e._offset)||(t._offset=e._offset),s(e._pf)||(t._pf=g(e)),s(e._locale)||(t._locale=e._locale),v.length>0)for(n=0;n<v.length;n++)s(a=e[i=v[n]])||(t[i]=a);return t}var y=!1;function x(t){b(this,t),this._d=new Date(null!=t._d?t._d.getTime():NaN),this.isValid()||(this._d=new Date(NaN)),!1===y&&(y=!0,a.updateOffset(this),y=!1)}function _(t){return t instanceof x||null!=t&&null!=t._isAMomentObject}function w(t){return t<0?Math.ceil(t)||0:Math.floor(t)}function k(t){var e=+t,n=0;return 0!==e&&isFinite(e)&&(n=w(e)),n}function M(t,e,n){var i,a=Math.min(t.length,e.length),r=Math.abs(t.length-e.length),o=0;for(i=0;i<a;i++)(n&&t[i]!==e[i]||!n&&k(t[i])!==k(e[i]))&&o++;return o+r}function S(t){!1===a.suppressDeprecationWarnings&&"undefined"!=typeof console&&console.warn&&console.warn("Deprecation warning: "+t)}function D(t,e){var n=!0;return c((function(){if(null!=a.deprecationHandler&&a.deprecationHandler(null,t),n){for(var i,r=[],o=0;o<arguments.length;o++){if(i="","object"==typeof arguments[o]){for(var s in i+="\n["+o+"] ",arguments[0])i+=s+": "+arguments[0][s]+", ";i=i.slice(0,-2)}else i=arguments[o];r.push(i)}S(t+"\nArguments: "+Array.prototype.slice.call(r).join("")+"\n"+(new Error).stack),n=!1}return e.apply(this,arguments)}),e)}var C,P={};function T(t,e){null!=a.deprecationHandler&&a.deprecationHandler(t,e),P[t]||(S(e),P[t]=!0)}function O(t){return t instanceof Function||"[object Function]"===Object.prototype.toString.call(t)}function A(t,e){var n,i=c({},t);for(n in e)h(e,n)&&(o(t[n])&&o(e[n])?(i[n]={},c(i[n],t[n]),c(i[n],e[n])):null!=e[n]?i[n]=e[n]:delete i[n]);for(n in t)h(t,n)&&!h(e,n)&&o(t[n])&&(i[n]=c({},i[n]));return i}function F(t){null!=t&&this.set(t)}a.suppressDeprecationWarnings=!1,a.deprecationHandler=null,C=Object.keys?Object.keys:function(t){var e,n=[];for(e in t)h(t,e)&&n.push(e);return n};var I={};function L(t,e){var n=t.toLowerCase();I[n]=I[n+"s"]=I[e]=t}function R(t){return"string"==typeof t?I[t]||I[t.toLowerCase()]:void 0}function N(t){var e,n,i={};for(n in t)h(t,n)&&(e=R(n))&&(i[e]=t[n]);return i}var W={};function Y(t,e){W[t]=e}function z(t,e,n){var i=""+Math.abs(t),a=e-i.length;return(t>=0?n?"+":"":"-")+Math.pow(10,Math.max(0,a)).toString().substr(1)+i}var E=/(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g,V=/(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,H={},B={};function j(t,e,n,i){var a=i;"string"==typeof i&&(a=function(){return this[i]()}),t&&(B[t]=a),e&&(B[e[0]]=function(){return z(a.apply(this,arguments),e[1],e[2])}),n&&(B[n]=function(){return this.localeData().ordinal(a.apply(this,arguments),t)})}function U(t,e){return t.isValid()?(e=G(e,t.localeData()),H[e]=H[e]||function(t){var e,n,i,a=t.match(E);for(e=0,n=a.length;e<n;e++)B[a[e]]?a[e]=B[a[e]]:a[e]=(i=a[e]).match(/\[[\s\S]/)?i.replace(/^\[|\]$/g,""):i.replace(/\\/g,"");return function(e){var i,r="";for(i=0;i<n;i++)r+=O(a[i])?a[i].call(e,t):a[i];return r}}(e),H[e](t)):t.localeData().invalidDate()}function G(t,e){var n=5;function i(t){return e.longDateFormat(t)||t}for(V.lastIndex=0;n>=0&&V.test(t);)t=t.replace(V,i),V.lastIndex=0,n-=1;return t}var q=/\d/,Z=/\d\d/,$=/\d{3}/,X=/\d{4}/,K=/[+-]?\d{6}/,J=/\d\d?/,Q=/\d\d\d\d?/,tt=/\d\d\d\d\d\d?/,et=/\d{1,3}/,nt=/\d{1,4}/,it=/[+-]?\d{1,6}/,at=/\d+/,rt=/[+-]?\d+/,ot=/Z|[+-]\d\d:?\d\d/gi,st=/Z|[+-]\d\d(?::?\d\d)?/gi,lt=/[0-9]{0,256}['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFF07\uFF10-\uFFEF]{1,256}|[\u0600-\u06FF\/]{1,256}(\s*?[\u0600-\u06FF]{1,256}){1,2}/i,ut={};function dt(t,e,n){ut[t]=O(e)?e:function(t,i){return t&&n?n:e}}function ht(t,e){return h(ut,t)?ut[t](e._strict,e._locale):new RegExp(ct(t.replace("\\","").replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,(function(t,e,n,i,a){return e||n||i||a}))))}function ct(t){return t.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}var ft={};function gt(t,e){var n,i=e;for("string"==typeof t&&(t=[t]),l(e)&&(i=function(t,n){n[e]=k(t)}),n=0;n<t.length;n++)ft[t[n]]=i}function mt(t,e){gt(t,(function(t,n,i,a){i._w=i._w||{},e(t,i._w,i,a)}))}function pt(t,e,n){null!=e&&h(ft,t)&&ft[t](e,n._a,n,t)}var vt=0,bt=1,yt=2,xt=3,_t=4,wt=5,kt=6,Mt=7,St=8;function Dt(t){return Ct(t)?366:365}function Ct(t){return t%4==0&&t%100!=0||t%400==0}j("Y",0,0,(function(){var t=this.year();return t<=9999?""+t:"+"+t})),j(0,["YY",2],0,(function(){return this.year()%100})),j(0,["YYYY",4],0,"year"),j(0,["YYYYY",5],0,"year"),j(0,["YYYYYY",6,!0],0,"year"),L("year","y"),Y("year",1),dt("Y",rt),dt("YY",J,Z),dt("YYYY",nt,X),dt("YYYYY",it,K),dt("YYYYYY",it,K),gt(["YYYYY","YYYYYY"],vt),gt("YYYY",(function(t,e){e[vt]=2===t.length?a.parseTwoDigitYear(t):k(t)})),gt("YY",(function(t,e){e[vt]=a.parseTwoDigitYear(t)})),gt("Y",(function(t,e){e[vt]=parseInt(t,10)})),a.parseTwoDigitYear=function(t){return k(t)+(k(t)>68?1900:2e3)};var Pt,Tt=Ot("FullYear",!0);function Ot(t,e){return function(n){return null!=n?(Ft(this,t,n),a.updateOffset(this,e),this):At(this,t)}}function At(t,e){return t.isValid()?t._d["get"+(t._isUTC?"UTC":"")+e]():NaN}function Ft(t,e,n){t.isValid()&&!isNaN(n)&&("FullYear"===e&&Ct(t.year())&&1===t.month()&&29===t.date()?t._d["set"+(t._isUTC?"UTC":"")+e](n,t.month(),It(n,t.month())):t._d["set"+(t._isUTC?"UTC":"")+e](n))}function It(t,e){if(isNaN(t)||isNaN(e))return NaN;var n=function(t,e){return(t%e+e)%e}(e,12);return t+=(e-n)/12,1===n?Ct(t)?29:28:31-n%7%2}Pt=Array.prototype.indexOf?Array.prototype.indexOf:function(t){var e;for(e=0;e<this.length;++e)if(this[e]===t)return e;return-1},j("M",["MM",2],"Mo",(function(){return this.month()+1})),j("MMM",0,0,(function(t){return this.localeData().monthsShort(this,t)})),j("MMMM",0,0,(function(t){return this.localeData().months(this,t)})),L("month","M"),Y("month",8),dt("M",J),dt("MM",J,Z),dt("MMM",(function(t,e){return e.monthsShortRegex(t)})),dt("MMMM",(function(t,e){return e.monthsRegex(t)})),gt(["M","MM"],(function(t,e){e[bt]=k(t)-1})),gt(["MMM","MMMM"],(function(t,e,n,i){var a=n._locale.monthsParse(t,i,n._strict);null!=a?e[bt]=a:g(n).invalidMonth=t}));var Lt=/D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/,Rt="January_February_March_April_May_June_July_August_September_October_November_December".split("_"),Nt="Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_");function Wt(t,e,n){var i,a,r,o=t.toLocaleLowerCase();if(!this._monthsParse)for(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[],i=0;i<12;++i)r=f([2e3,i]),this._shortMonthsParse[i]=this.monthsShort(r,"").toLocaleLowerCase(),this._longMonthsParse[i]=this.months(r,"").toLocaleLowerCase();return n?"MMM"===e?-1!==(a=Pt.call(this._shortMonthsParse,o))?a:null:-1!==(a=Pt.call(this._longMonthsParse,o))?a:null:"MMM"===e?-1!==(a=Pt.call(this._shortMonthsParse,o))?a:-1!==(a=Pt.call(this._longMonthsParse,o))?a:null:-1!==(a=Pt.call(this._longMonthsParse,o))?a:-1!==(a=Pt.call(this._shortMonthsParse,o))?a:null}function Yt(t,e){var n;if(!t.isValid())return t;if("string"==typeof e)if(/^\d+$/.test(e))e=k(e);else if(!l(e=t.localeData().monthsParse(e)))return t;return n=Math.min(t.date(),It(t.year(),e)),t._d["set"+(t._isUTC?"UTC":"")+"Month"](e,n),t}function zt(t){return null!=t?(Yt(this,t),a.updateOffset(this,!0),this):At(this,"Month")}var Et=lt,Vt=lt;function Ht(){function t(t,e){return e.length-t.length}var e,n,i=[],a=[],r=[];for(e=0;e<12;e++)n=f([2e3,e]),i.push(this.monthsShort(n,"")),a.push(this.months(n,"")),r.push(this.months(n,"")),r.push(this.monthsShort(n,""));for(i.sort(t),a.sort(t),r.sort(t),e=0;e<12;e++)i[e]=ct(i[e]),a[e]=ct(a[e]);for(e=0;e<24;e++)r[e]=ct(r[e]);this._monthsRegex=new RegExp("^("+r.join("|")+")","i"),this._monthsShortRegex=this._monthsRegex,this._monthsStrictRegex=new RegExp("^("+a.join("|")+")","i"),this._monthsShortStrictRegex=new RegExp("^("+i.join("|")+")","i")}function Bt(t,e,n,i,a,r,o){var s;return t<100&&t>=0?(s=new Date(t+400,e,n,i,a,r,o),isFinite(s.getFullYear())&&s.setFullYear(t)):s=new Date(t,e,n,i,a,r,o),s}function jt(t){var e;if(t<100&&t>=0){var n=Array.prototype.slice.call(arguments);n[0]=t+400,e=new Date(Date.UTC.apply(null,n)),isFinite(e.getUTCFullYear())&&e.setUTCFullYear(t)}else e=new Date(Date.UTC.apply(null,arguments));return e}function Ut(t,e,n){var i=7+e-n;return-(7+jt(t,0,i).getUTCDay()-e)%7+i-1}function Gt(t,e,n,i,a){var r,o,s=1+7*(e-1)+(7+n-i)%7+Ut(t,i,a);return s<=0?o=Dt(r=t-1)+s:s>Dt(t)?(r=t+1,o=s-Dt(t)):(r=t,o=s),{year:r,dayOfYear:o}}function qt(t,e,n){var i,a,r=Ut(t.year(),e,n),o=Math.floor((t.dayOfYear()-r-1)/7)+1;return o<1?i=o+Zt(a=t.year()-1,e,n):o>Zt(t.year(),e,n)?(i=o-Zt(t.year(),e,n),a=t.year()+1):(a=t.year(),i=o),{week:i,year:a}}function Zt(t,e,n){var i=Ut(t,e,n),a=Ut(t+1,e,n);return(Dt(t)-i+a)/7}function $t(t,e){return t.slice(e,7).concat(t.slice(0,e))}j("w",["ww",2],"wo","week"),j("W",["WW",2],"Wo","isoWeek"),L("week","w"),L("isoWeek","W"),Y("week",5),Y("isoWeek",5),dt("w",J),dt("ww",J,Z),dt("W",J),dt("WW",J,Z),mt(["w","ww","W","WW"],(function(t,e,n,i){e[i.substr(0,1)]=k(t)})),j("d",0,"do","day"),j("dd",0,0,(function(t){return this.localeData().weekdaysMin(this,t)})),j("ddd",0,0,(function(t){return this.localeData().weekdaysShort(this,t)})),j("dddd",0,0,(function(t){return this.localeData().weekdays(this,t)})),j("e",0,0,"weekday"),j("E",0,0,"isoWeekday"),L("day","d"),L("weekday","e"),L("isoWeekday","E"),Y("day",11),Y("weekday",11),Y("isoWeekday",11),dt("d",J),dt("e",J),dt("E",J),dt("dd",(function(t,e){return e.weekdaysMinRegex(t)})),dt("ddd",(function(t,e){return e.weekdaysShortRegex(t)})),dt("dddd",(function(t,e){return e.weekdaysRegex(t)})),mt(["dd","ddd","dddd"],(function(t,e,n,i){var a=n._locale.weekdaysParse(t,i,n._strict);null!=a?e.d=a:g(n).invalidWeekday=t})),mt(["d","e","E"],(function(t,e,n,i){e[i]=k(t)}));var Xt="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),Kt="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),Jt="Su_Mo_Tu_We_Th_Fr_Sa".split("_");function Qt(t,e,n){var i,a,r,o=t.toLocaleLowerCase();if(!this._weekdaysParse)for(this._weekdaysParse=[],this._shortWeekdaysParse=[],this._minWeekdaysParse=[],i=0;i<7;++i)r=f([2e3,1]).day(i),this._minWeekdaysParse[i]=this.weekdaysMin(r,"").toLocaleLowerCase(),this._shortWeekdaysParse[i]=this.weekdaysShort(r,"").toLocaleLowerCase(),this._weekdaysParse[i]=this.weekdays(r,"").toLocaleLowerCase();return n?"dddd"===e?-1!==(a=Pt.call(this._weekdaysParse,o))?a:null:"ddd"===e?-1!==(a=Pt.call(this._shortWeekdaysParse,o))?a:null:-1!==(a=Pt.call(this._minWeekdaysParse,o))?a:null:"dddd"===e?-1!==(a=Pt.call(this._weekdaysParse,o))?a:-1!==(a=Pt.call(this._shortWeekdaysParse,o))?a:-1!==(a=Pt.call(this._minWeekdaysParse,o))?a:null:"ddd"===e?-1!==(a=Pt.call(this._shortWeekdaysParse,o))?a:-1!==(a=Pt.call(this._weekdaysParse,o))?a:-1!==(a=Pt.call(this._minWeekdaysParse,o))?a:null:-1!==(a=Pt.call(this._minWeekdaysParse,o))?a:-1!==(a=Pt.call(this._weekdaysParse,o))?a:-1!==(a=Pt.call(this._shortWeekdaysParse,o))?a:null}var te=lt,ee=lt,ne=lt;function ie(){function t(t,e){return e.length-t.length}var e,n,i,a,r,o=[],s=[],l=[],u=[];for(e=0;e<7;e++)n=f([2e3,1]).day(e),i=this.weekdaysMin(n,""),a=this.weekdaysShort(n,""),r=this.weekdays(n,""),o.push(i),s.push(a),l.push(r),u.push(i),u.push(a),u.push(r);for(o.sort(t),s.sort(t),l.sort(t),u.sort(t),e=0;e<7;e++)s[e]=ct(s[e]),l[e]=ct(l[e]),u[e]=ct(u[e]);this._weekdaysRegex=new RegExp("^("+u.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+l.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+s.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+o.join("|")+")","i")}function ae(){return this.hours()%12||12}function re(t,e){j(t,0,0,(function(){return this.localeData().meridiem(this.hours(),this.minutes(),e)}))}function oe(t,e){return e._meridiemParse}j("H",["HH",2],0,"hour"),j("h",["hh",2],0,ae),j("k",["kk",2],0,(function(){return this.hours()||24})),j("hmm",0,0,(function(){return""+ae.apply(this)+z(this.minutes(),2)})),j("hmmss",0,0,(function(){return""+ae.apply(this)+z(this.minutes(),2)+z(this.seconds(),2)})),j("Hmm",0,0,(function(){return""+this.hours()+z(this.minutes(),2)})),j("Hmmss",0,0,(function(){return""+this.hours()+z(this.minutes(),2)+z(this.seconds(),2)})),re("a",!0),re("A",!1),L("hour","h"),Y("hour",13),dt("a",oe),dt("A",oe),dt("H",J),dt("h",J),dt("k",J),dt("HH",J,Z),dt("hh",J,Z),dt("kk",J,Z),dt("hmm",Q),dt("hmmss",tt),dt("Hmm",Q),dt("Hmmss",tt),gt(["H","HH"],xt),gt(["k","kk"],(function(t,e,n){var i=k(t);e[xt]=24===i?0:i})),gt(["a","A"],(function(t,e,n){n._isPm=n._locale.isPM(t),n._meridiem=t})),gt(["h","hh"],(function(t,e,n){e[xt]=k(t),g(n).bigHour=!0})),gt("hmm",(function(t,e,n){var i=t.length-2;e[xt]=k(t.substr(0,i)),e[_t]=k(t.substr(i)),g(n).bigHour=!0})),gt("hmmss",(function(t,e,n){var i=t.length-4,a=t.length-2;e[xt]=k(t.substr(0,i)),e[_t]=k(t.substr(i,2)),e[wt]=k(t.substr(a)),g(n).bigHour=!0})),gt("Hmm",(function(t,e,n){var i=t.length-2;e[xt]=k(t.substr(0,i)),e[_t]=k(t.substr(i))})),gt("Hmmss",(function(t,e,n){var i=t.length-4,a=t.length-2;e[xt]=k(t.substr(0,i)),e[_t]=k(t.substr(i,2)),e[wt]=k(t.substr(a))}));var se,le=Ot("Hours",!0),ue={calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},longDateFormat:{LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},invalidDate:"Invalid date",ordinal:"%d",dayOfMonthOrdinalParse:/\d{1,2}/,relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},months:Rt,monthsShort:Nt,week:{dow:0,doy:6},weekdays:Xt,weekdaysMin:Jt,weekdaysShort:Kt,meridiemParse:/[ap]\.?m?\.?/i},de={},he={};function ce(t){return t?t.toLowerCase().replace("_","-"):t}function fe(n){var i=null;if(!de[n]&&e&&e.exports)try{i=se._abbr,t(),ge(i)}catch(t){}return de[n]}function ge(t,e){var n;return t&&((n=s(e)?pe(t):me(t,e))?se=n:"undefined"!=typeof console&&console.warn&&console.warn("Locale "+t+" not found. Did you forget to load it?")),se._abbr}function me(t,e){if(null!==e){var n,i=ue;if(e.abbr=t,null!=de[t])T("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info."),i=de[t]._config;else if(null!=e.parentLocale)if(null!=de[e.parentLocale])i=de[e.parentLocale]._config;else{if(null==(n=fe(e.parentLocale)))return he[e.parentLocale]||(he[e.parentLocale]=[]),he[e.parentLocale].push({name:t,config:e}),null;i=n._config}return de[t]=new F(A(i,e)),he[t]&&he[t].forEach((function(t){me(t.name,t.config)})),ge(t),de[t]}return delete de[t],null}function pe(t){var e;if(t&&t._locale&&t._locale._abbr&&(t=t._locale._abbr),!t)return se;if(!r(t)){if(e=fe(t))return e;t=[t]}return function(t){for(var e,n,i,a,r=0;r<t.length;){for(e=(a=ce(t[r]).split("-")).length,n=(n=ce(t[r+1]))?n.split("-"):null;e>0;){if(i=fe(a.slice(0,e).join("-")))return i;if(n&&n.length>=e&&M(a,n,!0)>=e-1)break;e--}r++}return se}(t)}function ve(t){var e,n=t._a;return n&&-2===g(t).overflow&&(e=n[bt]<0||n[bt]>11?bt:n[yt]<1||n[yt]>It(n[vt],n[bt])?yt:n[xt]<0||n[xt]>24||24===n[xt]&&(0!==n[_t]||0!==n[wt]||0!==n[kt])?xt:n[_t]<0||n[_t]>59?_t:n[wt]<0||n[wt]>59?wt:n[kt]<0||n[kt]>999?kt:-1,g(t)._overflowDayOfYear&&(e<vt||e>yt)&&(e=yt),g(t)._overflowWeeks&&-1===e&&(e=Mt),g(t)._overflowWeekday&&-1===e&&(e=St),g(t).overflow=e),t}function be(t,e,n){return null!=t?t:null!=e?e:n}function ye(t){var e,n,i,r,o,s=[];if(!t._d){for(i=function(t){var e=new Date(a.now());return t._useUTC?[e.getUTCFullYear(),e.getUTCMonth(),e.getUTCDate()]:[e.getFullYear(),e.getMonth(),e.getDate()]}(t),t._w&&null==t._a[yt]&&null==t._a[bt]&&function(t){var e,n,i,a,r,o,s,l;if(null!=(e=t._w).GG||null!=e.W||null!=e.E)r=1,o=4,n=be(e.GG,t._a[vt],qt(Le(),1,4).year),i=be(e.W,1),((a=be(e.E,1))<1||a>7)&&(l=!0);else{r=t._locale._week.dow,o=t._locale._week.doy;var u=qt(Le(),r,o);n=be(e.gg,t._a[vt],u.year),i=be(e.w,u.week),null!=e.d?((a=e.d)<0||a>6)&&(l=!0):null!=e.e?(a=e.e+r,(e.e<0||e.e>6)&&(l=!0)):a=r}i<1||i>Zt(n,r,o)?g(t)._overflowWeeks=!0:null!=l?g(t)._overflowWeekday=!0:(s=Gt(n,i,a,r,o),t._a[vt]=s.year,t._dayOfYear=s.dayOfYear)}(t),null!=t._dayOfYear&&(o=be(t._a[vt],i[vt]),(t._dayOfYear>Dt(o)||0===t._dayOfYear)&&(g(t)._overflowDayOfYear=!0),n=jt(o,0,t._dayOfYear),t._a[bt]=n.getUTCMonth(),t._a[yt]=n.getUTCDate()),e=0;e<3&&null==t._a[e];++e)t._a[e]=s[e]=i[e];for(;e<7;e++)t._a[e]=s[e]=null==t._a[e]?2===e?1:0:t._a[e];24===t._a[xt]&&0===t._a[_t]&&0===t._a[wt]&&0===t._a[kt]&&(t._nextDay=!0,t._a[xt]=0),t._d=(t._useUTC?jt:Bt).apply(null,s),r=t._useUTC?t._d.getUTCDay():t._d.getDay(),null!=t._tzm&&t._d.setUTCMinutes(t._d.getUTCMinutes()-t._tzm),t._nextDay&&(t._a[xt]=24),t._w&&void 0!==t._w.d&&t._w.d!==r&&(g(t).weekdayMismatch=!0)}}var xe=/^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,_e=/^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,we=/Z|[+-]\d\d(?::?\d\d)?/,ke=[["YYYYYY-MM-DD",/[+-]\d{6}-\d\d-\d\d/],["YYYY-MM-DD",/\d{4}-\d\d-\d\d/],["GGGG-[W]WW-E",/\d{4}-W\d\d-\d/],["GGGG-[W]WW",/\d{4}-W\d\d/,!1],["YYYY-DDD",/\d{4}-\d{3}/],["YYYY-MM",/\d{4}-\d\d/,!1],["YYYYYYMMDD",/[+-]\d{10}/],["YYYYMMDD",/\d{8}/],["GGGG[W]WWE",/\d{4}W\d{3}/],["GGGG[W]WW",/\d{4}W\d{2}/,!1],["YYYYDDD",/\d{7}/]],Me=[["HH:mm:ss.SSSS",/\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss,SSSS",/\d\d:\d\d:\d\d,\d+/],["HH:mm:ss",/\d\d:\d\d:\d\d/],["HH:mm",/\d\d:\d\d/],["HHmmss.SSSS",/\d\d\d\d\d\d\.\d+/],["HHmmss,SSSS",/\d\d\d\d\d\d,\d+/],["HHmmss",/\d\d\d\d\d\d/],["HHmm",/\d\d\d\d/],["HH",/\d\d/]],Se=/^\/?Date\((\-?\d+)/i;function De(t){var e,n,i,a,r,o,s=t._i,l=xe.exec(s)||_e.exec(s);if(l){for(g(t).iso=!0,e=0,n=ke.length;e<n;e++)if(ke[e][1].exec(l[1])){a=ke[e][0],i=!1!==ke[e][2];break}if(null==a)return void(t._isValid=!1);if(l[3]){for(e=0,n=Me.length;e<n;e++)if(Me[e][1].exec(l[3])){r=(l[2]||" ")+Me[e][0];break}if(null==r)return void(t._isValid=!1)}if(!i&&null!=r)return void(t._isValid=!1);if(l[4]){if(!we.exec(l[4]))return void(t._isValid=!1);o="Z"}t._f=a+(r||"")+(o||""),Ae(t)}else t._isValid=!1}var Ce=/^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|([+-]\d{4}))$/;function Pe(t){var e=parseInt(t,10);return e<=49?2e3+e:e<=999?1900+e:e}var Te={UT:0,GMT:0,EDT:-240,EST:-300,CDT:-300,CST:-360,MDT:-360,MST:-420,PDT:-420,PST:-480};function Oe(t){var e,n,i,a,r,o,s,l=Ce.exec(t._i.replace(/\([^)]*\)|[\n\t]/g," ").replace(/(\s\s+)/g," ").replace(/^\s\s*/,"").replace(/\s\s*$/,""));if(l){var u=(e=l[4],n=l[3],i=l[2],a=l[5],r=l[6],o=l[7],s=[Pe(e),Nt.indexOf(n),parseInt(i,10),parseInt(a,10),parseInt(r,10)],o&&s.push(parseInt(o,10)),s);if(!function(t,e,n){return!t||Kt.indexOf(t)===new Date(e[0],e[1],e[2]).getDay()||(g(n).weekdayMismatch=!0,n._isValid=!1,!1)}(l[1],u,t))return;t._a=u,t._tzm=function(t,e,n){if(t)return Te[t];if(e)return 0;var i=parseInt(n,10),a=i%100;return(i-a)/100*60+a}(l[8],l[9],l[10]),t._d=jt.apply(null,t._a),t._d.setUTCMinutes(t._d.getUTCMinutes()-t._tzm),g(t).rfc2822=!0}else t._isValid=!1}function Ae(t){if(t._f!==a.ISO_8601)if(t._f!==a.RFC_2822){t._a=[],g(t).empty=!0;var e,n,i,r,o,s=""+t._i,l=s.length,u=0;for(i=G(t._f,t._locale).match(E)||[],e=0;e<i.length;e++)r=i[e],(n=(s.match(ht(r,t))||[])[0])&&((o=s.substr(0,s.indexOf(n))).length>0&&g(t).unusedInput.push(o),s=s.slice(s.indexOf(n)+n.length),u+=n.length),B[r]?(n?g(t).empty=!1:g(t).unusedTokens.push(r),pt(r,n,t)):t._strict&&!n&&g(t).unusedTokens.push(r);g(t).charsLeftOver=l-u,s.length>0&&g(t).unusedInput.push(s),t._a[xt]<=12&&!0===g(t).bigHour&&t._a[xt]>0&&(g(t).bigHour=void 0),g(t).parsedDateParts=t._a.slice(0),g(t).meridiem=t._meridiem,t._a[xt]=function(t,e,n){var i;return null==n?e:null!=t.meridiemHour?t.meridiemHour(e,n):null!=t.isPM?((i=t.isPM(n))&&e<12&&(e+=12),i||12!==e||(e=0),e):e}(t._locale,t._a[xt],t._meridiem),ye(t),ve(t)}else Oe(t);else De(t)}function Fe(t){var e=t._i,n=t._f;return t._locale=t._locale||pe(t._l),null===e||void 0===n&&""===e?p({nullInput:!0}):("string"==typeof e&&(t._i=e=t._locale.preparse(e)),_(e)?new x(ve(e)):(u(e)?t._d=e:r(n)?function(t){var e,n,i,a,r;if(0===t._f.length)return g(t).invalidFormat=!0,void(t._d=new Date(NaN));for(a=0;a<t._f.length;a++)r=0,e=b({},t),null!=t._useUTC&&(e._useUTC=t._useUTC),e._f=t._f[a],Ae(e),m(e)&&(r+=g(e).charsLeftOver,r+=10*g(e).unusedTokens.length,g(e).score=r,(null==i||r<i)&&(i=r,n=e));c(t,n||e)}(t):n?Ae(t):function(t){var e=t._i;s(e)?t._d=new Date(a.now()):u(e)?t._d=new Date(e.valueOf()):"string"==typeof e?function(t){var e=Se.exec(t._i);null===e?(De(t),!1===t._isValid&&(delete t._isValid,Oe(t),!1===t._isValid&&(delete t._isValid,a.createFromInputFallback(t)))):t._d=new Date(+e[1])}(t):r(e)?(t._a=d(e.slice(0),(function(t){return parseInt(t,10)})),ye(t)):o(e)?function(t){if(!t._d){var e=N(t._i);t._a=d([e.year,e.month,e.day||e.date,e.hour,e.minute,e.second,e.millisecond],(function(t){return t&&parseInt(t,10)})),ye(t)}}(t):l(e)?t._d=new Date(e):a.createFromInputFallback(t)}(t),m(t)||(t._d=null),t))}function Ie(t,e,n,i,a){var s,l={};return!0!==n&&!1!==n||(i=n,n=void 0),(o(t)&&function(t){if(Object.getOwnPropertyNames)return 0===Object.getOwnPropertyNames(t).length;var e;for(e in t)if(t.hasOwnProperty(e))return!1;return!0}(t)||r(t)&&0===t.length)&&(t=void 0),l._isAMomentObject=!0,l._useUTC=l._isUTC=a,l._l=n,l._i=t,l._f=e,l._strict=i,(s=new x(ve(Fe(l))))._nextDay&&(s.add(1,"d"),s._nextDay=void 0),s}function Le(t,e,n,i){return Ie(t,e,n,i,!1)}a.createFromInputFallback=D("value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are discouraged and will be removed in an upcoming major release. Please refer to http://momentjs.com/guides/#/warnings/js-date/ for more info.",(function(t){t._d=new Date(t._i+(t._useUTC?" UTC":""))})),a.ISO_8601=function(){},a.RFC_2822=function(){};var Re=D("moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/",(function(){var t=Le.apply(null,arguments);return this.isValid()&&t.isValid()?t<this?this:t:p()})),Ne=D("moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/",(function(){var t=Le.apply(null,arguments);return this.isValid()&&t.isValid()?t>this?this:t:p()}));function We(t,e){var n,i;if(1===e.length&&r(e[0])&&(e=e[0]),!e.length)return Le();for(n=e[0],i=1;i<e.length;++i)e[i].isValid()&&!e[i][t](n)||(n=e[i]);return n}var Ye=["year","quarter","month","week","day","hour","minute","second","millisecond"];function ze(t){var e=N(t),n=e.year||0,i=e.quarter||0,a=e.month||0,r=e.week||e.isoWeek||0,o=e.day||0,s=e.hour||0,l=e.minute||0,u=e.second||0,d=e.millisecond||0;this._isValid=function(t){for(var e in t)if(-1===Pt.call(Ye,e)||null!=t[e]&&isNaN(t[e]))return!1;for(var n=!1,i=0;i<Ye.length;++i)if(t[Ye[i]]){if(n)return!1;parseFloat(t[Ye[i]])!==k(t[Ye[i]])&&(n=!0)}return!0}(e),this._milliseconds=+d+1e3*u+6e4*l+1e3*s*60*60,this._days=+o+7*r,this._months=+a+3*i+12*n,this._data={},this._locale=pe(),this._bubble()}function Ee(t){return t instanceof ze}function Ve(t){return t<0?-1*Math.round(-1*t):Math.round(t)}function He(t,e){j(t,0,0,(function(){var t=this.utcOffset(),n="+";return t<0&&(t=-t,n="-"),n+z(~~(t/60),2)+e+z(~~t%60,2)}))}He("Z",":"),He("ZZ",""),dt("Z",st),dt("ZZ",st),gt(["Z","ZZ"],(function(t,e,n){n._useUTC=!0,n._tzm=je(st,t)}));var Be=/([\+\-]|\d\d)/gi;function je(t,e){var n=(e||"").match(t);if(null===n)return null;var i=((n[n.length-1]||[])+"").match(Be)||["-",0,0],a=60*i[1]+k(i[2]);return 0===a?0:"+"===i[0]?a:-a}function Ue(t,e){var n,i;return e._isUTC?(n=e.clone(),i=(_(t)||u(t)?t.valueOf():Le(t).valueOf())-n.valueOf(),n._d.setTime(n._d.valueOf()+i),a.updateOffset(n,!1),n):Le(t).local()}function Ge(t){return 15*-Math.round(t._d.getTimezoneOffset()/15)}function qe(){return!!this.isValid()&&this._isUTC&&0===this._offset}a.updateOffset=function(){};var Ze=/^(\-|\+)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/,$e=/^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/;function Xe(t,e){var n,i,a,r,o,s,u=t,d=null;return Ee(t)?u={ms:t._milliseconds,d:t._days,M:t._months}:l(t)?(u={},e?u[e]=t:u.milliseconds=t):(d=Ze.exec(t))?(n="-"===d[1]?-1:1,u={y:0,d:k(d[yt])*n,h:k(d[xt])*n,m:k(d[_t])*n,s:k(d[wt])*n,ms:k(Ve(1e3*d[kt]))*n}):(d=$e.exec(t))?(n="-"===d[1]?-1:1,u={y:Ke(d[2],n),M:Ke(d[3],n),w:Ke(d[4],n),d:Ke(d[5],n),h:Ke(d[6],n),m:Ke(d[7],n),s:Ke(d[8],n)}):null==u?u={}:"object"==typeof u&&("from"in u||"to"in u)&&(r=Le(u.from),o=Le(u.to),a=r.isValid()&&o.isValid()?(o=Ue(o,r),r.isBefore(o)?s=Je(r,o):((s=Je(o,r)).milliseconds=-s.milliseconds,s.months=-s.months),s):{milliseconds:0,months:0},(u={}).ms=a.milliseconds,u.M=a.months),i=new ze(u),Ee(t)&&h(t,"_locale")&&(i._locale=t._locale),i}function Ke(t,e){var n=t&&parseFloat(t.replace(",","."));return(isNaN(n)?0:n)*e}function Je(t,e){var n={};return n.months=e.month()-t.month()+12*(e.year()-t.year()),t.clone().add(n.months,"M").isAfter(e)&&--n.months,n.milliseconds=+e-+t.clone().add(n.months,"M"),n}function Qe(t,e){return function(n,i){var a;return null===i||isNaN(+i)||(T(e,"moment()."+e+"(period, number) is deprecated. Please use moment()."+e+"(number, period). See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info."),a=n,n=i,i=a),tn(this,Xe(n="string"==typeof n?+n:n,i),t),this}}function tn(t,e,n,i){var r=e._milliseconds,o=Ve(e._days),s=Ve(e._months);t.isValid()&&(i=null==i||i,s&&Yt(t,At(t,"Month")+s*n),o&&Ft(t,"Date",At(t,"Date")+o*n),r&&t._d.setTime(t._d.valueOf()+r*n),i&&a.updateOffset(t,o||s))}Xe.fn=ze.prototype,Xe.invalid=function(){return Xe(NaN)};var en=Qe(1,"add"),nn=Qe(-1,"subtract");function an(t,e){var n=12*(e.year()-t.year())+(e.month()-t.month()),i=t.clone().add(n,"months");return-(n+(e-i<0?(e-i)/(i-t.clone().add(n-1,"months")):(e-i)/(t.clone().add(n+1,"months")-i)))||0}function rn(t){var e;return void 0===t?this._locale._abbr:(null!=(e=pe(t))&&(this._locale=e),this)}a.defaultFormat="YYYY-MM-DDTHH:mm:ssZ",a.defaultFormatUtc="YYYY-MM-DDTHH:mm:ss[Z]";var on=D("moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.",(function(t){return void 0===t?this.localeData():this.locale(t)}));function sn(){return this._locale}var ln=1e3,un=60*ln,dn=60*un,hn=3506328*dn;function cn(t,e){return(t%e+e)%e}function fn(t,e,n){return t<100&&t>=0?new Date(t+400,e,n)-hn:new Date(t,e,n).valueOf()}function gn(t,e,n){return t<100&&t>=0?Date.UTC(t+400,e,n)-hn:Date.UTC(t,e,n)}function mn(t,e){j(0,[t,t.length],0,e)}function pn(t,e,n,i,a){var r;return null==t?qt(this,i,a).year:(e>(r=Zt(t,i,a))&&(e=r),vn.call(this,t,e,n,i,a))}function vn(t,e,n,i,a){var r=Gt(t,e,n,i,a),o=jt(r.year,0,r.dayOfYear);return this.year(o.getUTCFullYear()),this.month(o.getUTCMonth()),this.date(o.getUTCDate()),this}j(0,["gg",2],0,(function(){return this.weekYear()%100})),j(0,["GG",2],0,(function(){return this.isoWeekYear()%100})),mn("gggg","weekYear"),mn("ggggg","weekYear"),mn("GGGG","isoWeekYear"),mn("GGGGG","isoWeekYear"),L("weekYear","gg"),L("isoWeekYear","GG"),Y("weekYear",1),Y("isoWeekYear",1),dt("G",rt),dt("g",rt),dt("GG",J,Z),dt("gg",J,Z),dt("GGGG",nt,X),dt("gggg",nt,X),dt("GGGGG",it,K),dt("ggggg",it,K),mt(["gggg","ggggg","GGGG","GGGGG"],(function(t,e,n,i){e[i.substr(0,2)]=k(t)})),mt(["gg","GG"],(function(t,e,n,i){e[i]=a.parseTwoDigitYear(t)})),j("Q",0,"Qo","quarter"),L("quarter","Q"),Y("quarter",7),dt("Q",q),gt("Q",(function(t,e){e[bt]=3*(k(t)-1)})),j("D",["DD",2],"Do","date"),L("date","D"),Y("date",9),dt("D",J),dt("DD",J,Z),dt("Do",(function(t,e){return t?e._dayOfMonthOrdinalParse||e._ordinalParse:e._dayOfMonthOrdinalParseLenient})),gt(["D","DD"],yt),gt("Do",(function(t,e){e[yt]=k(t.match(J)[0])}));var bn=Ot("Date",!0);j("DDD",["DDDD",3],"DDDo","dayOfYear"),L("dayOfYear","DDD"),Y("dayOfYear",4),dt("DDD",et),dt("DDDD",$),gt(["DDD","DDDD"],(function(t,e,n){n._dayOfYear=k(t)})),j("m",["mm",2],0,"minute"),L("minute","m"),Y("minute",14),dt("m",J),dt("mm",J,Z),gt(["m","mm"],_t);var yn=Ot("Minutes",!1);j("s",["ss",2],0,"second"),L("second","s"),Y("second",15),dt("s",J),dt("ss",J,Z),gt(["s","ss"],wt);var xn,_n=Ot("Seconds",!1);for(j("S",0,0,(function(){return~~(this.millisecond()/100)})),j(0,["SS",2],0,(function(){return~~(this.millisecond()/10)})),j(0,["SSS",3],0,"millisecond"),j(0,["SSSS",4],0,(function(){return 10*this.millisecond()})),j(0,["SSSSS",5],0,(function(){return 100*this.millisecond()})),j(0,["SSSSSS",6],0,(function(){return 1e3*this.millisecond()})),j(0,["SSSSSSS",7],0,(function(){return 1e4*this.millisecond()})),j(0,["SSSSSSSS",8],0,(function(){return 1e5*this.millisecond()})),j(0,["SSSSSSSSS",9],0,(function(){return 1e6*this.millisecond()})),L("millisecond","ms"),Y("millisecond",16),dt("S",et,q),dt("SS",et,Z),dt("SSS",et,$),xn="SSSS";xn.length<=9;xn+="S")dt(xn,at);function wn(t,e){e[kt]=k(1e3*("0."+t))}for(xn="S";xn.length<=9;xn+="S")gt(xn,wn);var kn=Ot("Milliseconds",!1);j("z",0,0,"zoneAbbr"),j("zz",0,0,"zoneName");var Mn=x.prototype;function Sn(t){return t}Mn.add=en,Mn.calendar=function(t,e){var n=t||Le(),i=Ue(n,this).startOf("day"),r=a.calendarFormat(this,i)||"sameElse",o=e&&(O(e[r])?e[r].call(this,n):e[r]);return this.format(o||this.localeData().calendar(r,this,Le(n)))},Mn.clone=function(){return new x(this)},Mn.diff=function(t,e,n){var i,a,r;if(!this.isValid())return NaN;if(!(i=Ue(t,this)).isValid())return NaN;switch(a=6e4*(i.utcOffset()-this.utcOffset()),e=R(e)){case"year":r=an(this,i)/12;break;case"month":r=an(this,i);break;case"quarter":r=an(this,i)/3;break;case"second":r=(this-i)/1e3;break;case"minute":r=(this-i)/6e4;break;case"hour":r=(this-i)/36e5;break;case"day":r=(this-i-a)/864e5;break;case"week":r=(this-i-a)/6048e5;break;default:r=this-i}return n?r:w(r)},Mn.endOf=function(t){var e;if(void 0===(t=R(t))||"millisecond"===t||!this.isValid())return this;var n=this._isUTC?gn:fn;switch(t){case"year":e=n(this.year()+1,0,1)-1;break;case"quarter":e=n(this.year(),this.month()-this.month()%3+3,1)-1;break;case"month":e=n(this.year(),this.month()+1,1)-1;break;case"week":e=n(this.year(),this.month(),this.date()-this.weekday()+7)-1;break;case"isoWeek":e=n(this.year(),this.month(),this.date()-(this.isoWeekday()-1)+7)-1;break;case"day":case"date":e=n(this.year(),this.month(),this.date()+1)-1;break;case"hour":e=this._d.valueOf(),e+=dn-cn(e+(this._isUTC?0:this.utcOffset()*un),dn)-1;break;case"minute":e=this._d.valueOf(),e+=un-cn(e,un)-1;break;case"second":e=this._d.valueOf(),e+=ln-cn(e,ln)-1}return this._d.setTime(e),a.updateOffset(this,!0),this},Mn.format=function(t){t||(t=this.isUtc()?a.defaultFormatUtc:a.defaultFormat);var e=U(this,t);return this.localeData().postformat(e)},Mn.from=function(t,e){return this.isValid()&&(_(t)&&t.isValid()||Le(t).isValid())?Xe({to:this,from:t}).locale(this.locale()).humanize(!e):this.localeData().invalidDate()},Mn.fromNow=function(t){return this.from(Le(),t)},Mn.to=function(t,e){return this.isValid()&&(_(t)&&t.isValid()||Le(t).isValid())?Xe({from:this,to:t}).locale(this.locale()).humanize(!e):this.localeData().invalidDate()},Mn.toNow=function(t){return this.to(Le(),t)},Mn.get=function(t){return O(this[t=R(t)])?this[t]():this},Mn.invalidAt=function(){return g(this).overflow},Mn.isAfter=function(t,e){var n=_(t)?t:Le(t);return!(!this.isValid()||!n.isValid())&&("millisecond"===(e=R(e)||"millisecond")?this.valueOf()>n.valueOf():n.valueOf()<this.clone().startOf(e).valueOf())},Mn.isBefore=function(t,e){var n=_(t)?t:Le(t);return!(!this.isValid()||!n.isValid())&&("millisecond"===(e=R(e)||"millisecond")?this.valueOf()<n.valueOf():this.clone().endOf(e).valueOf()<n.valueOf())},Mn.isBetween=function(t,e,n,i){var a=_(t)?t:Le(t),r=_(e)?e:Le(e);return!!(this.isValid()&&a.isValid()&&r.isValid())&&("("===(i=i||"()")[0]?this.isAfter(a,n):!this.isBefore(a,n))&&(")"===i[1]?this.isBefore(r,n):!this.isAfter(r,n))},Mn.isSame=function(t,e){var n,i=_(t)?t:Le(t);return!(!this.isValid()||!i.isValid())&&("millisecond"===(e=R(e)||"millisecond")?this.valueOf()===i.valueOf():(n=i.valueOf(),this.clone().startOf(e).valueOf()<=n&&n<=this.clone().endOf(e).valueOf()))},Mn.isSameOrAfter=function(t,e){return this.isSame(t,e)||this.isAfter(t,e)},Mn.isSameOrBefore=function(t,e){return this.isSame(t,e)||this.isBefore(t,e)},Mn.isValid=function(){return m(this)},Mn.lang=on,Mn.locale=rn,Mn.localeData=sn,Mn.max=Ne,Mn.min=Re,Mn.parsingFlags=function(){return c({},g(this))},Mn.set=function(t,e){if("object"==typeof t)for(var n=function(t){var e=[];for(var n in t)e.push({unit:n,priority:W[n]});return e.sort((function(t,e){return t.priority-e.priority})),e}(t=N(t)),i=0;i<n.length;i++)this[n[i].unit](t[n[i].unit]);else if(O(this[t=R(t)]))return this[t](e);return this},Mn.startOf=function(t){var e;if(void 0===(t=R(t))||"millisecond"===t||!this.isValid())return this;var n=this._isUTC?gn:fn;switch(t){case"year":e=n(this.year(),0,1);break;case"quarter":e=n(this.year(),this.month()-this.month()%3,1);break;case"month":e=n(this.year(),this.month(),1);break;case"week":e=n(this.year(),this.month(),this.date()-this.weekday());break;case"isoWeek":e=n(this.year(),this.month(),this.date()-(this.isoWeekday()-1));break;case"day":case"date":e=n(this.year(),this.month(),this.date());break;case"hour":e=this._d.valueOf(),e-=cn(e+(this._isUTC?0:this.utcOffset()*un),dn);break;case"minute":e=this._d.valueOf(),e-=cn(e,un);break;case"second":e=this._d.valueOf(),e-=cn(e,ln)}return this._d.setTime(e),a.updateOffset(this,!0),this},Mn.subtract=nn,Mn.toArray=function(){var t=this;return[t.year(),t.month(),t.date(),t.hour(),t.minute(),t.second(),t.millisecond()]},Mn.toObject=function(){var t=this;return{years:t.year(),months:t.month(),date:t.date(),hours:t.hours(),minutes:t.minutes(),seconds:t.seconds(),milliseconds:t.milliseconds()}},Mn.toDate=function(){return new Date(this.valueOf())},Mn.toISOString=function(t){if(!this.isValid())return null;var e=!0!==t,n=e?this.clone().utc():this;return n.year()<0||n.year()>9999?U(n,e?"YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]":"YYYYYY-MM-DD[T]HH:mm:ss.SSSZ"):O(Date.prototype.toISOString)?e?this.toDate().toISOString():new Date(this.valueOf()+60*this.utcOffset()*1e3).toISOString().replace("Z",U(n,"Z")):U(n,e?"YYYY-MM-DD[T]HH:mm:ss.SSS[Z]":"YYYY-MM-DD[T]HH:mm:ss.SSSZ")},Mn.inspect=function(){if(!this.isValid())return"moment.invalid(/* "+this._i+" */)";var t="moment",e="";this.isLocal()||(t=0===this.utcOffset()?"moment.utc":"moment.parseZone",e="Z");var n="["+t+'("]',i=0<=this.year()&&this.year()<=9999?"YYYY":"YYYYYY",a=e+'[")]';return this.format(n+i+"-MM-DD[T]HH:mm:ss.SSS"+a)},Mn.toJSON=function(){return this.isValid()?this.toISOString():null},Mn.toString=function(){return this.clone().locale("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")},Mn.unix=function(){return Math.floor(this.valueOf()/1e3)},Mn.valueOf=function(){return this._d.valueOf()-6e4*(this._offset||0)},Mn.creationData=function(){return{input:this._i,format:this._f,locale:this._locale,isUTC:this._isUTC,strict:this._strict}},Mn.year=Tt,Mn.isLeapYear=function(){return Ct(this.year())},Mn.weekYear=function(t){return pn.call(this,t,this.week(),this.weekday(),this.localeData()._week.dow,this.localeData()._week.doy)},Mn.isoWeekYear=function(t){return pn.call(this,t,this.isoWeek(),this.isoWeekday(),1,4)},Mn.quarter=Mn.quarters=function(t){return null==t?Math.ceil((this.month()+1)/3):this.month(3*(t-1)+this.month()%3)},Mn.month=zt,Mn.daysInMonth=function(){return It(this.year(),this.month())},Mn.week=Mn.weeks=function(t){var e=this.localeData().week(this);return null==t?e:this.add(7*(t-e),"d")},Mn.isoWeek=Mn.isoWeeks=function(t){var e=qt(this,1,4).week;return null==t?e:this.add(7*(t-e),"d")},Mn.weeksInYear=function(){var t=this.localeData()._week;return Zt(this.year(),t.dow,t.doy)},Mn.isoWeeksInYear=function(){return Zt(this.year(),1,4)},Mn.date=bn,Mn.day=Mn.days=function(t){if(!this.isValid())return null!=t?this:NaN;var e=this._isUTC?this._d.getUTCDay():this._d.getDay();return null!=t?(t=function(t,e){return"string"!=typeof t?t:isNaN(t)?"number"==typeof(t=e.weekdaysParse(t))?t:null:parseInt(t,10)}(t,this.localeData()),this.add(t-e,"d")):e},Mn.weekday=function(t){if(!this.isValid())return null!=t?this:NaN;var e=(this.day()+7-this.localeData()._week.dow)%7;return null==t?e:this.add(t-e,"d")},Mn.isoWeekday=function(t){if(!this.isValid())return null!=t?this:NaN;if(null!=t){var e=function(t,e){return"string"==typeof t?e.weekdaysParse(t)%7||7:isNaN(t)?null:t}(t,this.localeData());return this.day(this.day()%7?e:e-7)}return this.day()||7},Mn.dayOfYear=function(t){var e=Math.round((this.clone().startOf("day")-this.clone().startOf("year"))/864e5)+1;return null==t?e:this.add(t-e,"d")},Mn.hour=Mn.hours=le,Mn.minute=Mn.minutes=yn,Mn.second=Mn.seconds=_n,Mn.millisecond=Mn.milliseconds=kn,Mn.utcOffset=function(t,e,n){var i,r=this._offset||0;if(!this.isValid())return null!=t?this:NaN;if(null!=t){if("string"==typeof t){if(null===(t=je(st,t)))return this}else Math.abs(t)<16&&!n&&(t*=60);return!this._isUTC&&e&&(i=Ge(this)),this._offset=t,this._isUTC=!0,null!=i&&this.add(i,"m"),r!==t&&(!e||this._changeInProgress?tn(this,Xe(t-r,"m"),1,!1):this._changeInProgress||(this._changeInProgress=!0,a.updateOffset(this,!0),this._changeInProgress=null)),this}return this._isUTC?r:Ge(this)},Mn.utc=function(t){return this.utcOffset(0,t)},Mn.local=function(t){return this._isUTC&&(this.utcOffset(0,t),this._isUTC=!1,t&&this.subtract(Ge(this),"m")),this},Mn.parseZone=function(){if(null!=this._tzm)this.utcOffset(this._tzm,!1,!0);else if("string"==typeof this._i){var t=je(ot,this._i);null!=t?this.utcOffset(t):this.utcOffset(0,!0)}return this},Mn.hasAlignedHourOffset=function(t){return!!this.isValid()&&(t=t?Le(t).utcOffset():0,(this.utcOffset()-t)%60==0)},Mn.isDST=function(){return this.utcOffset()>this.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()},Mn.isLocal=function(){return!!this.isValid()&&!this._isUTC},Mn.isUtcOffset=function(){return!!this.isValid()&&this._isUTC},Mn.isUtc=qe,Mn.isUTC=qe,Mn.zoneAbbr=function(){return this._isUTC?"UTC":""},Mn.zoneName=function(){return this._isUTC?"Coordinated Universal Time":""},Mn.dates=D("dates accessor is deprecated. Use date instead.",bn),Mn.months=D("months accessor is deprecated. Use month instead",zt),Mn.years=D("years accessor is deprecated. Use year instead",Tt),Mn.zone=D("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",(function(t,e){return null!=t?("string"!=typeof t&&(t=-t),this.utcOffset(t,e),this):-this.utcOffset()})),Mn.isDSTShifted=D("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",(function(){if(!s(this._isDSTShifted))return this._isDSTShifted;var t={};if(b(t,this),(t=Fe(t))._a){var e=t._isUTC?f(t._a):Le(t._a);this._isDSTShifted=this.isValid()&&M(t._a,e.toArray())>0}else this._isDSTShifted=!1;return this._isDSTShifted}));var Dn=F.prototype;function Cn(t,e,n,i){var a=pe(),r=f().set(i,e);return a[n](r,t)}function Pn(t,e,n){if(l(t)&&(e=t,t=void 0),t=t||"",null!=e)return Cn(t,e,n,"month");var i,a=[];for(i=0;i<12;i++)a[i]=Cn(t,i,n,"month");return a}function Tn(t,e,n,i){"boolean"==typeof t?(l(e)&&(n=e,e=void 0),e=e||""):(n=e=t,t=!1,l(e)&&(n=e,e=void 0),e=e||"");var a,r=pe(),o=t?r._week.dow:0;if(null!=n)return Cn(e,(n+o)%7,i,"day");var s=[];for(a=0;a<7;a++)s[a]=Cn(e,(a+o)%7,i,"day");return s}Dn.calendar=function(t,e,n){var i=this._calendar[t]||this._calendar.sameElse;return O(i)?i.call(e,n):i},Dn.longDateFormat=function(t){var e=this._longDateFormat[t],n=this._longDateFormat[t.toUpperCase()];return e||!n?e:(this._longDateFormat[t]=n.replace(/MMMM|MM|DD|dddd/g,(function(t){return t.slice(1)})),this._longDateFormat[t])},Dn.invalidDate=function(){return this._invalidDate},Dn.ordinal=function(t){return this._ordinal.replace("%d",t)},Dn.preparse=Sn,Dn.postformat=Sn,Dn.relativeTime=function(t,e,n,i){var a=this._relativeTime[n];return O(a)?a(t,e,n,i):a.replace(/%d/i,t)},Dn.pastFuture=function(t,e){var n=this._relativeTime[t>0?"future":"past"];return O(n)?n(e):n.replace(/%s/i,e)},Dn.set=function(t){var e,n;for(n in t)O(e=t[n])?this[n]=e:this["_"+n]=e;this._config=t,this._dayOfMonthOrdinalParseLenient=new RegExp((this._dayOfMonthOrdinalParse.source||this._ordinalParse.source)+"|"+/\d{1,2}/.source)},Dn.months=function(t,e){return t?r(this._months)?this._months[t.month()]:this._months[(this._months.isFormat||Lt).test(e)?"format":"standalone"][t.month()]:r(this._months)?this._months:this._months.standalone},Dn.monthsShort=function(t,e){return t?r(this._monthsShort)?this._monthsShort[t.month()]:this._monthsShort[Lt.test(e)?"format":"standalone"][t.month()]:r(this._monthsShort)?this._monthsShort:this._monthsShort.standalone},Dn.monthsParse=function(t,e,n){var i,a,r;if(this._monthsParseExact)return Wt.call(this,t,e,n);for(this._monthsParse||(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[]),i=0;i<12;i++){if(a=f([2e3,i]),n&&!this._longMonthsParse[i]&&(this._longMonthsParse[i]=new RegExp("^"+this.months(a,"").replace(".","")+"$","i"),this._shortMonthsParse[i]=new RegExp("^"+this.monthsShort(a,"").replace(".","")+"$","i")),n||this._monthsParse[i]||(r="^"+this.months(a,"")+"|^"+this.monthsShort(a,""),this._monthsParse[i]=new RegExp(r.replace(".",""),"i")),n&&"MMMM"===e&&this._longMonthsParse[i].test(t))return i;if(n&&"MMM"===e&&this._shortMonthsParse[i].test(t))return i;if(!n&&this._monthsParse[i].test(t))return i}},Dn.monthsRegex=function(t){return this._monthsParseExact?(h(this,"_monthsRegex")||Ht.call(this),t?this._monthsStrictRegex:this._monthsRegex):(h(this,"_monthsRegex")||(this._monthsRegex=Vt),this._monthsStrictRegex&&t?this._monthsStrictRegex:this._monthsRegex)},Dn.monthsShortRegex=function(t){return this._monthsParseExact?(h(this,"_monthsRegex")||Ht.call(this),t?this._monthsShortStrictRegex:this._monthsShortRegex):(h(this,"_monthsShortRegex")||(this._monthsShortRegex=Et),this._monthsShortStrictRegex&&t?this._monthsShortStrictRegex:this._monthsShortRegex)},Dn.week=function(t){return qt(t,this._week.dow,this._week.doy).week},Dn.firstDayOfYear=function(){return this._week.doy},Dn.firstDayOfWeek=function(){return this._week.dow},Dn.weekdays=function(t,e){var n=r(this._weekdays)?this._weekdays:this._weekdays[t&&!0!==t&&this._weekdays.isFormat.test(e)?"format":"standalone"];return!0===t?$t(n,this._week.dow):t?n[t.day()]:n},Dn.weekdaysMin=function(t){return!0===t?$t(this._weekdaysMin,this._week.dow):t?this._weekdaysMin[t.day()]:this._weekdaysMin},Dn.weekdaysShort=function(t){return!0===t?$t(this._weekdaysShort,this._week.dow):t?this._weekdaysShort[t.day()]:this._weekdaysShort},Dn.weekdaysParse=function(t,e,n){var i,a,r;if(this._weekdaysParseExact)return Qt.call(this,t,e,n);for(this._weekdaysParse||(this._weekdaysParse=[],this._minWeekdaysParse=[],this._shortWeekdaysParse=[],this._fullWeekdaysParse=[]),i=0;i<7;i++){if(a=f([2e3,1]).day(i),n&&!this._fullWeekdaysParse[i]&&(this._fullWeekdaysParse[i]=new RegExp("^"+this.weekdays(a,"").replace(".","\\.?")+"$","i"),this._shortWeekdaysParse[i]=new RegExp("^"+this.weekdaysShort(a,"").replace(".","\\.?")+"$","i"),this._minWeekdaysParse[i]=new RegExp("^"+this.weekdaysMin(a,"").replace(".","\\.?")+"$","i")),this._weekdaysParse[i]||(r="^"+this.weekdays(a,"")+"|^"+this.weekdaysShort(a,"")+"|^"+this.weekdaysMin(a,""),this._weekdaysParse[i]=new RegExp(r.replace(".",""),"i")),n&&"dddd"===e&&this._fullWeekdaysParse[i].test(t))return i;if(n&&"ddd"===e&&this._shortWeekdaysParse[i].test(t))return i;if(n&&"dd"===e&&this._minWeekdaysParse[i].test(t))return i;if(!n&&this._weekdaysParse[i].test(t))return i}},Dn.weekdaysRegex=function(t){return this._weekdaysParseExact?(h(this,"_weekdaysRegex")||ie.call(this),t?this._weekdaysStrictRegex:this._weekdaysRegex):(h(this,"_weekdaysRegex")||(this._weekdaysRegex=te),this._weekdaysStrictRegex&&t?this._weekdaysStrictRegex:this._weekdaysRegex)},Dn.weekdaysShortRegex=function(t){return this._weekdaysParseExact?(h(this,"_weekdaysRegex")||ie.call(this),t?this._weekdaysShortStrictRegex:this._weekdaysShortRegex):(h(this,"_weekdaysShortRegex")||(this._weekdaysShortRegex=ee),this._weekdaysShortStrictRegex&&t?this._weekdaysShortStrictRegex:this._weekdaysShortRegex)},Dn.weekdaysMinRegex=function(t){return this._weekdaysParseExact?(h(this,"_weekdaysRegex")||ie.call(this),t?this._weekdaysMinStrictRegex:this._weekdaysMinRegex):(h(this,"_weekdaysMinRegex")||(this._weekdaysMinRegex=ne),this._weekdaysMinStrictRegex&&t?this._weekdaysMinStrictRegex:this._weekdaysMinRegex)},Dn.isPM=function(t){return"p"===(t+"").toLowerCase().charAt(0)},Dn.meridiem=function(t,e,n){return t>11?n?"pm":"PM":n?"am":"AM"},ge("en",{dayOfMonthOrdinalParse:/\d{1,2}(th|st|nd|rd)/,ordinal:function(t){var e=t%10;return t+(1===k(t%100/10)?"th":1===e?"st":2===e?"nd":3===e?"rd":"th")}}),a.lang=D("moment.lang is deprecated. Use moment.locale instead.",ge),a.langData=D("moment.langData is deprecated. Use moment.localeData instead.",pe);var On=Math.abs;function An(t,e,n,i){var a=Xe(e,n);return t._milliseconds+=i*a._milliseconds,t._days+=i*a._days,t._months+=i*a._months,t._bubble()}function Fn(t){return t<0?Math.floor(t):Math.ceil(t)}function In(t){return 4800*t/146097}function Ln(t){return 146097*t/4800}function Rn(t){return function(){return this.as(t)}}var Nn=Rn("ms"),Wn=Rn("s"),Yn=Rn("m"),zn=Rn("h"),En=Rn("d"),Vn=Rn("w"),Hn=Rn("M"),Bn=Rn("Q"),jn=Rn("y");function Un(t){return function(){return this.isValid()?this._data[t]:NaN}}var Gn=Un("milliseconds"),qn=Un("seconds"),Zn=Un("minutes"),$n=Un("hours"),Xn=Un("days"),Kn=Un("months"),Jn=Un("years"),Qn=Math.round,ti={ss:44,s:45,m:45,h:22,d:26,M:11};function ei(t,e,n,i,a){return a.relativeTime(e||1,!!n,t,i)}var ni=Math.abs;function ii(t){return(t>0)-(t<0)||+t}function ai(){if(!this.isValid())return this.localeData().invalidDate();var t,e,n=ni(this._milliseconds)/1e3,i=ni(this._days),a=ni(this._months);t=w(n/60),e=w(t/60),n%=60,t%=60;var r=w(a/12),o=a%=12,s=i,l=e,u=t,d=n?n.toFixed(3).replace(/\.?0+$/,""):"",h=this.asSeconds();if(!h)return"P0D";var c=h<0?"-":"",f=ii(this._months)!==ii(h)?"-":"",g=ii(this._days)!==ii(h)?"-":"",m=ii(this._milliseconds)!==ii(h)?"-":"";return c+"P"+(r?f+r+"Y":"")+(o?f+o+"M":"")+(s?g+s+"D":"")+(l||u||d?"T":"")+(l?m+l+"H":"")+(u?m+u+"M":"")+(d?m+d+"S":"")}var ri=ze.prototype;return ri.isValid=function(){return this._isValid},ri.abs=function(){var t=this._data;return this._milliseconds=On(this._milliseconds),this._days=On(this._days),this._months=On(this._months),t.milliseconds=On(t.milliseconds),t.seconds=On(t.seconds),t.minutes=On(t.minutes),t.hours=On(t.hours),t.months=On(t.months),t.years=On(t.years),this},ri.add=function(t,e){return An(this,t,e,1)},ri.subtract=function(t,e){return An(this,t,e,-1)},ri.as=function(t){if(!this.isValid())return NaN;var e,n,i=this._milliseconds;if("month"===(t=R(t))||"quarter"===t||"year"===t)switch(e=this._days+i/864e5,n=this._months+In(e),t){case"month":return n;case"quarter":return n/3;case"year":return n/12}else switch(e=this._days+Math.round(Ln(this._months)),t){case"week":return e/7+i/6048e5;case"day":return e+i/864e5;case"hour":return 24*e+i/36e5;case"minute":return 1440*e+i/6e4;case"second":return 86400*e+i/1e3;case"millisecond":return Math.floor(864e5*e)+i;default:throw new Error("Unknown unit "+t)}},ri.asMilliseconds=Nn,ri.asSeconds=Wn,ri.asMinutes=Yn,ri.asHours=zn,ri.asDays=En,ri.asWeeks=Vn,ri.asMonths=Hn,ri.asQuarters=Bn,ri.asYears=jn,ri.valueOf=function(){return this.isValid()?this._milliseconds+864e5*this._days+this._months%12*2592e6+31536e6*k(this._months/12):NaN},ri._bubble=function(){var t,e,n,i,a,r=this._milliseconds,o=this._days,s=this._months,l=this._data;return r>=0&&o>=0&&s>=0||r<=0&&o<=0&&s<=0||(r+=864e5*Fn(Ln(s)+o),o=0,s=0),l.milliseconds=r%1e3,t=w(r/1e3),l.seconds=t%60,e=w(t/60),l.minutes=e%60,n=w(e/60),l.hours=n%24,o+=w(n/24),a=w(In(o)),s+=a,o-=Fn(Ln(a)),i=w(s/12),s%=12,l.days=o,l.months=s,l.years=i,this},ri.clone=function(){return Xe(this)},ri.get=function(t){return t=R(t),this.isValid()?this[t+"s"]():NaN},ri.milliseconds=Gn,ri.seconds=qn,ri.minutes=Zn,ri.hours=$n,ri.days=Xn,ri.weeks=function(){return w(this.days()/7)},ri.months=Kn,ri.years=Jn,ri.humanize=function(t){if(!this.isValid())return this.localeData().invalidDate();var e=this.localeData(),n=function(t,e,n){var i=Xe(t).abs(),a=Qn(i.as("s")),r=Qn(i.as("m")),o=Qn(i.as("h")),s=Qn(i.as("d")),l=Qn(i.as("M")),u=Qn(i.as("y")),d=a<=ti.ss&&["s",a]||a<ti.s&&["ss",a]||r<=1&&["m"]||r<ti.m&&["mm",r]||o<=1&&["h"]||o<ti.h&&["hh",o]||s<=1&&["d"]||s<ti.d&&["dd",s]||l<=1&&["M"]||l<ti.M&&["MM",l]||u<=1&&["y"]||["yy",u];return d[2]=e,d[3]=+t>0,d[4]=n,ei.apply(null,d)}(this,!t,e);return t&&(n=e.pastFuture(+this,n)),e.postformat(n)},ri.toISOString=ai,ri.toString=ai,ri.toJSON=ai,ri.locale=rn,ri.localeData=sn,ri.toIsoString=D("toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)",ai),ri.lang=on,j("X",0,0,"unix"),j("x",0,0,"valueOf"),dt("x",rt),dt("X",/[+-]?\d+(\.\d{1,3})?/),gt("X",(function(t,e,n){n._d=new Date(1e3*parseFloat(t,10))})),gt("x",(function(t,e,n){n._d=new Date(k(t))})),a.version="2.24.0",n=Le,a.fn=Mn,a.min=function(){return We("isBefore",[].slice.call(arguments,0))},a.max=function(){return We("isAfter",[].slice.call(arguments,0))},a.now=function(){return Date.now?Date.now():+new Date},a.utc=f,a.unix=function(t){return Le(1e3*t)},a.months=function(t,e){return Pn(t,e,"months")},a.isDate=u,a.locale=ge,a.invalid=p,a.duration=Xe,a.isMoment=_,a.weekdays=function(t,e,n){return Tn(t,e,n,"weekdays")},a.parseZone=function(){return Le.apply(null,arguments).parseZone()},a.localeData=pe,a.isDuration=Ee,a.monthsShort=function(t,e){return Pn(t,e,"monthsShort")},a.weekdaysMin=function(t,e,n){return Tn(t,e,n,"weekdaysMin")},a.defineLocale=me,a.updateLocale=function(t,e){if(null!=e){var n,i,a=ue;null!=(i=fe(t))&&(a=i._config),e=A(a,e),(n=new F(e)).parentLocale=de[t],de[t]=n,ge(t)}else null!=de[t]&&(null!=de[t].parentLocale?de[t]=de[t].parentLocale:null!=de[t]&&delete de[t]);return de[t]},a.locales=function(){return C(de)},a.weekdaysShort=function(t,e,n){return Tn(t,e,n,"weekdaysShort")},a.normalizeUnits=R,a.relativeTimeRounding=function(t){return void 0===t?Qn:"function"==typeof t&&(Qn=t,!0)},a.relativeTimeThreshold=function(t,e){return void 0!==ti[t]&&(void 0===e?ti[t]:(ti[t]=e,"s"===t&&(ti.ss=e-1),!0))},a.calendarFormat=function(t,e){var n=t.diff(e,"days",!0);return n<-6?"sameElse":n<-1?"lastWeek":n<0?"lastDay":n<1?"sameDay":n<2?"nextDay":n<7?"nextWeek":"sameElse"},a.prototype=Mn,a.HTML5_FMT={DATETIME_LOCAL:"YYYY-MM-DDTHH:mm",DATETIME_LOCAL_SECONDS:"YYYY-MM-DDTHH:mm:ss",DATETIME_LOCAL_MS:"YYYY-MM-DDTHH:mm:ss.SSS",DATE:"YYYY-MM-DD",TIME:"HH:mm",TIME_SECONDS:"HH:mm:ss",TIME_MS:"HH:mm:ss.SSS",WEEK:"GGGG-[W]WW",MONTH:"YYYY-MM"},a}()})),pi={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"};on._date.override("function"==typeof mi?{_id:"moment",formats:function(){return pi},parse:function(t,e){return"string"==typeof t&&"string"==typeof e?t=mi(t,e):t instanceof mi||(t=mi(t)),t.isValid()?t.valueOf():null},format:function(t,e){return mi(t).format(e)},add:function(t,e,n){return mi(t).add(e,n).valueOf()},diff:function(t,e,n){return mi(t).diff(mi(e),n)},startOf:function(t,e,n){return t=mi(t),"isoWeek"===e?t.isoWeekday(n).valueOf():t.startOf(e).valueOf()},endOf:function(t,e){return mi(t).endOf(e).valueOf()},_create:function(t){return mi(t)}}:{}),Y._set("global",{plugins:{filler:{propagate:!0}}});var vi={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 B.isArray(e)?function(t,n){return e[n]}:function(t){return{x:null===n?t.x:n,y:null===i?t.y:i}}}};function bi(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 yi(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(B.isFinite(r))return{x:(e=i.isHorizontal())?r:null,y:e?null:r}}return null}(t)}function xi(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 _i(t){var e=t.fill,n="dataset";return!1===e?null:(isFinite(e)||(n="boundary"),vi[n](t))}function wi(t){return t&&!t.skip}function ki(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)B.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)B.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 Mi(t,e,n,i,a,r){var o,s,l,u,d,h,c,f,g=e.length,m=i.spanGaps,p=[],v=[],b=0,y=0;for(t.beginPath(),o=0,s=g;o<s;++o)d=n(u=e[l=o%g]._view,l,i),h=wi(u),c=wi(d),r&&void 0===f&&h&&(s=g+(f=o+1)),h&&c?(b=p.push(u),y=v.push(d)):b&&y&&(m?(h&&p.push(u),c&&v.push(d)):(ki(t,p,v,b,y),b=y=0,p=[],v=[]));ki(t,p,v,b,y),t.closePath(),t.fillStyle=a,t.fill()}var Si={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:bi(a,i,o),chart:t,el:a}),n.$filler=r,l.push(r);for(i=0;i<o;++i)(r=l[i])&&(r.fill=xi(l,i,s),r.boundary=yi(r),r.mapper=_i(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||Y.global.defaultColor,o&&s&&r.length&&(B.canvas.clipArea(u,t.chartArea),Mi(u,r,o,a,s,i._loop),B.canvas.unclipArea(u)))}},Di=B.rtl.getRtlAdapter,Ci=B.noop,Pi=B.valueOrDefault;function Ti(t,e){return t.usePointStyle&&t.boxWidth>e?e:t.boxWidth}Y._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 Oi=X.extend({initialize:function(t){B.extend(this,t),this.legendHitBoxes=[],this._hoveredItem=null,this.doughnutMode=!1},beforeUpdate:Ci,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:Ci,beforeSetDimensions:Ci,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:Ci,beforeBuildLabels:Ci,buildLabels:function(){var t=this,e=t.options.labels||{},n=B.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:Ci,beforeFit:Ci,fit:function(){var t=this,e=t.options,n=e.labels,i=e.display,a=t.ctx,r=B.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",B.each(t.legendItems,(function(t,e){var i=Ti(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=[],m=n.padding,p=0,v=0;B.each(t.legendItems,(function(t,e){var i=Ti(n,o)+o/2+a.measureText(t.text).width;e>0&&v+o+2*c>l.height&&(m+=p+n.padding,f.push(p),g.push(v),p=0,v=0),p=Math.max(p,i),v+=o+c,s[e]={left:0,top:0,width:i,height:o}})),m+=p,f.push(p),g.push(v),l.width+=m}t.width=l.width,t.height=l.height}else t.width=l.width=t.height=l.height=0},afterFit:Ci,isHorizontal:function(){return"top"===this.options.position||"bottom"===this.options.position},draw:function(){var t=this,e=t.options,n=e.labels,i=Y.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=Di(e.rtl,t.left,t.minSize.width),c=t.ctx,f=Pi(n.fontColor,i.defaultFontColor),g=B.options._parseFont(n),m=g.size;c.textAlign=h.textAlign("left"),c.textBaseline="middle",c.lineWidth=.5,c.strokeStyle=f,c.fillStyle=f,c.font=g.string;var p=Ti(n,m),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}},y=t.isHorizontal();d=y?{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},B.rtl.overrideTextDirection(t.ctx,e.textDirection);var x=m+n.padding;B.each(t.legendItems,(function(e,i){var f=c.measureText(e.text).width,g=p+m/2+f,_=d.x,w=d.y;h.setWidth(t.minSize.width),y?i>0&&_+g+n.padding>t.left+t.minSize.width&&(w=d.y+=x,d.line++,_=d.x=t.left+b(l,u[d.line])):i>0&&w+x>t.top+t.minSize.height&&(_=d.x=_+t.columnWidths[d.line]+n.padding,d.line++,w=d.y=t.top+b(o,s[d.line]));var k=h.x(_);!function(t,e,i){if(!(isNaN(p)||p<=0)){c.save();var o=Pi(i.lineWidth,r.borderWidth);if(c.fillStyle=Pi(i.fillStyle,a),c.lineCap=Pi(i.lineCap,r.borderCapStyle),c.lineDashOffset=Pi(i.lineDashOffset,r.borderDashOffset),c.lineJoin=Pi(i.lineJoin,r.borderJoinStyle),c.lineWidth=o,c.strokeStyle=Pi(i.strokeStyle,a),c.setLineDash&&c.setLineDash(Pi(i.lineDash,r.borderDash)),n&&n.usePointStyle){var s=p*Math.SQRT2/2,l=h.xPlus(t,p/2),u=e+m/2;B.canvas.drawPoint(c,i.pointStyle,s,l,u,i.rotation)}else c.fillRect(h.leftForLtr(t,p),e,p,m),0!==o&&c.strokeRect(h.leftForLtr(t,p),e,p,m);c.restore()}}(k,w,e),v[i].left=h.leftForLtr(k,v[i].width),v[i].top=w,function(t,e,n,i){var a=m/2,r=h.xPlus(t,p+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())}(k,w,e,f),y?d.x+=g+n.padding:d.y+=x})),B.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 Ai(t,e){var n=new Oi({ctx:t.ctx,options:e,chart:t});pe.configure(t,n,e),pe.addBox(t,n),t.legend=n}var Fi={id:"legend",_element:Oi,beforeInit:function(t){var e=t.options.legend;e&&Ai(t,e)},beforeUpdate:function(t){var e=t.options.legend,n=t.legend;e?(B.mergeIf(e,Y.global.legend),n?(pe.configure(t,n,e),n.options=e):Ai(t,e)):n&&(pe.removeBox(t,n),delete t.legend)},afterEvent:function(t,e){var n=t.legend;n&&n.handleEvent(e)}},Ii=B.noop;Y._set("global",{title:{display:!1,fontStyle:"bold",fullWidth:!0,padding:10,position:"top",text:"",weight:2e3}});var Li=X.extend({initialize:function(t){B.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=(B.isArray(n.text)?n.text.length:1)*B.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=B.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=B.valueOrDefault(n.fontColor,Y.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(B.isArray(g))for(var m=0,p=0;p<g.length;++p)e.fillText(g[p],0,m,i),m+=s;else e.fillText(g,0,0,i);e.restore()}}});function Ri(t,e){var n=new Li({ctx:t.ctx,options:e,chart:t});pe.configure(t,n,e),pe.addBox(t,n),t.titleBlock=n}var Ni={},Wi=Si,Yi=Fi,zi={id:"title",_element:Li,beforeInit:function(t){var e=t.options.title;e&&Ri(t,e)},beforeUpdate:function(t){var e=t.options.title,n=t.titleBlock;e?(B.mergeIf(e,Y.global.title),n?(pe.configure(t,n,e),n.options=e):Ri(t,e)):n&&(pe.removeBox(t,n),delete t.titleBlock)}};for(var Ei in Ni.filler=Wi,Ni.legend=Yi,Ni.title=zi,nn.helpers=B,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=B._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"}B.where=function(t,e){if(B.isArray(t)&&Array.prototype.filter)return t.filter(e);var n=[];return B.each(t,(function(t){e(t)&&n.push(t)})),n},B.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},B.findNextWhere=function(t,e,n){B.isNullOrUndef(n)&&(n=-1);for(var i=n+1;i<t.length;i++){var a=t[i];if(e(a))return a}},B.findPreviousWhere=function(t,e,n){B.isNullOrUndef(n)&&(n=t.length);for(var i=n-1;i>=0;i--){var a=t[i];if(e(a))return a}},B.isNumber=function(t){return!isNaN(parseFloat(t))&&isFinite(t)},B.almostEquals=function(t,e,n){return Math.abs(t-e)<n},B.almostWhole=function(t,e){var n=Math.round(t);return n-e<=t&&n+e>=t},B.max=function(t){return t.reduce((function(t,e){return isNaN(e)?t:Math.max(t,e)}),Number.NEGATIVE_INFINITY)},B.min=function(t){return t.reduce((function(t,e){return isNaN(e)?t:Math.min(t,e)}),Number.POSITIVE_INFINITY)},B.sign=Math.sign?function(t){return Math.sign(t)}:function(t){return 0===(t=+t)||isNaN(t)?t:t>0?1:-1},B.toRadians=function(t){return t*(Math.PI/180)},B.toDegrees=function(t){return t*(180/Math.PI)},B._decimalPlaces=function(t){if(B.isFinite(t)){for(var e=1,n=0;Math.round(t*e)/e!==t;)e*=10,n++;return n}},B.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}},B.distanceBetweenPoints=function(t,e){return Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2))},B.aliasPixel=function(t){return t%2==0?0:.5},B._alignPixel=function(t,e,n){var i=t.currentDevicePixelRatio,a=n/2;return Math.round((e-a)*i)/i+a},B.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)}}},B.EPSILON=Number.EPSILON||1e-14,B.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||(B.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))},B.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]},B.previousItem=function(t,e,n){return n?e<=0?t[t.length-1]:t[e-1]:e<=0?t[0]:t[e-1]},B.niceNum=function(t,e){var n=Math.floor(B.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)},B.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)},B.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(B.getStyle(r,"padding-left")),u=parseFloat(B.getStyle(r,"padding-top")),d=parseFloat(B.getStyle(r,"padding-right")),h=parseFloat(B.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)}},B.getConstraintWidth=function(t){return n(t,"max-width","clientWidth")},B.getConstraintHeight=function(t){return n(t,"max-height","clientHeight")},B._calculatePadding=function(t,e,n){return(e=B.getStyle(t,e)).indexOf("%")>-1?n*parseInt(e,10)/100:parseInt(e,10)},B._getParentNode=function(t){var e=t.parentNode;return e&&"[object ShadowRoot]"===e.toString()&&(e=e.host),e},B.getMaximumWidth=function(t){var e=B._getParentNode(t);if(!e)return t.clientWidth;var n=e.clientWidth,i=n-B._calculatePadding(e,"padding-left",n)-B._calculatePadding(e,"padding-right",n),a=B.getConstraintWidth(t);return isNaN(a)?i:Math.min(i,a)},B.getMaximumHeight=function(t){var e=B._getParentNode(t);if(!e)return t.clientHeight;var n=e.clientHeight,i=n-B._calculatePadding(e,"padding-top",n)-B._calculatePadding(e,"padding-bottom",n),a=B.getConstraintHeight(t);return isNaN(a)?i:Math.min(i,a)},B.getStyle=function(t,e){return t.currentStyle?t.currentStyle[e]:document.defaultView.getComputedStyle(t,null).getPropertyValue(e)},B.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")}},B.fontString=function(t,e,n){return e+" "+t+"px "+n},B.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!==B.isArray(u))h=B.measureText(t,a,r,h,u);else if(B.isArray(u))for(s=0,l=u.length;s<l;s++)null==(d=u[s])||B.isArray(d)||(h=B.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},B.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},B.numberOfLabelLines=function(t){var e=1;return B.each(t,(function(t){B.isArray(t)&&t.length>e&&(e=t.length)})),e},B.color=w?function(t){return t instanceof CanvasGradient&&(t=Y.global.defaultColor),w(t)}:function(t){return console.error("Color.js not found!"),t},B.getHoverColor=function(t){return t instanceof CanvasPattern||t instanceof CanvasGradient?t:B.color(t).saturate(.5).darken(.1).rgbString()}}(),nn._adapters=on,nn.Animation=J,nn.animationService=Q,nn.controllers=Qt,nn.DatasetController=at,nn.defaults=Y,nn.Element=X,nn.elements=kt,nn.Interaction=oe,nn.layouts=pe,nn.platform=Le,nn.plugins=Re,nn.Scale=_n,nn.scaleService=Ne,nn.Ticks=sn,nn.Tooltip=qe,nn.helpers.each(gi,(function(t,e){nn.scaleService.registerScaleType(e,t,t._defaults)})),Ni)Ni.hasOwnProperty(Ei)&&nn.plugins.register(Ni[Ei]);nn.platform.initialize();var Vi=nn;return"undefined"!=typeof window&&(window.Chart=nn),nn.Chart=nn,nn.Legend=Ni.legend._element,nn.Title=Ni.title._element,nn.pluginService=nn.plugins,nn.PluginBase=nn.Element.extend({}),nn.canvasHelpers=nn.helpers.canvas,nn.layoutService=nn.layouts,nn.LinearScaleBase=Cn,nn.helpers.each(["Bar","Bubble","Doughnut","Line","PolarArea","Radar","Scatter"],(function(t){nn[t]=function(e,n){return new nn(e,nn.helpers.merge(n||{},{type:t.charAt(0).toLowerCase()+t.slice(1)}))}})),Vi}));
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"==typeof define&&define.amd?define(e):(t=t||self).Chart=e()}(this,function(){"use strict";function Va(){throw new Error("Dynamic requires are not currently supported by rollup-plugin-commonjs")}function t(t,e){return t(e={exports:{}},e.exports),e.exports}var d={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=t(function(t){var u={};for(var e in d)d.hasOwnProperty(e)&&(u[d[e]]=e);var o=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 n in o)if(o.hasOwnProperty(n)){if(!("channels"in o[n]))throw new Error("missing channels property: "+n);if(!("labels"in o[n]))throw new Error("missing channel labels property: "+n);if(o[n].labels.length!==o[n].channels)throw new Error("channel and label counts mismatch: "+n);var i=o[n].channels,r=o[n].labels;delete o[n].channels,delete o[n].labels,Object.defineProperty(o[n],"channels",{value:i}),Object.defineProperty(o[n],"labels",{value:r})}o.rgb.hsl=function(t){var e,n,i=t[0]/255,r=t[1]/255,a=t[2]/255,o=Math.min(i,r,a),s=Math.max(i,r,a),l=s-o;return s===o?e=0:i===s?e=(r-a)/l:r===s?e=2+(a-i)/l:a===s&&(e=4+(i-r)/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]},o.rgb.hsv=function(t){function e(t){return(d-t)/6/h+.5}var n,i,r,a,o,s=t[0]/255,l=t[1]/255,u=t[2]/255,d=Math.max(s,l,u),h=d-Math.min(s,l,u);return 0==h?a=o=0:(o=h/d,n=e(s),i=e(l),r=e(u),s===d?a=r-i:l===d?a=1/3+n-r:u===d&&(a=2/3+i-n),a<0?a+=1:1<a&&--a),[360*a,100*o,100*d]},o.rgb.hwb=function(t){var e=t[0],n=t[1],i=t[2];return[o.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)))]},o.rgb.cmyk=function(t){var e=t[0]/255,n=t[1]/255,i=t[2]/255,r=Math.min(1-e,1-n,1-i);return[100*((1-e-r)/(1-r)||0),100*((1-n-r)/(1-r)||0),100*((1-i-r)/(1-r)||0),100*r]},o.rgb.keyword=function(t){var e=u[t];if(e)return e;var n,i,r,a,o,s=1/0;for(var l in d){d.hasOwnProperty(l)&&(i=d[l],a=t,o=i,(r=Math.pow(a[0]-o[0],2)+Math.pow(a[1]-o[1],2)+Math.pow(a[2]-o[2],2))<s&&(s=r,n=l))}return n},o.keyword.rgb=function(t){return d[t]},o.rgb.xyz=function(t){var e=t[0]/255,n=t[1]/255,i=t[2]/255;return[100*(.4124*(e=.04045<e?Math.pow((e+.055)/1.055,2.4):e/12.92)+.3576*(n=.04045<n?Math.pow((n+.055)/1.055,2.4):n/12.92)+.1805*(i=.04045<i?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)]},o.rgb.lab=function(t){var e=o.rgb.xyz(t),n=e[0],i=e[1],r=e[2];return i/=100,r/=108.883,n=.008856<(n/=95.047)?Math.pow(n,1/3):7.787*n+16/116,[116*(i=.008856<i?Math.pow(i,1/3):7.787*i+16/116)-16,500*(n-i),200*(i-(r=.008856<r?Math.pow(r,1/3):7.787*r+16/116))]},o.hsl.rgb=function(t){var e,n,i,r,a,o=t[0]/360,s=t[1]/100,l=t[2]/100;if(0==s)return[a=255*l,a,a];e=2*l-(n=l<.5?l*(1+s):l+s-l*s),r=[0,0,0];for(var u=0;u<3;u++)(i=o+1/3*-(u-1))<0&&i++,1<i&&i--,a=6*i<1?e+6*(n-e)*i:2*i<1?n:3*i<2?e+(n-e)*(2/3-i)*6:e,r[u]=255*a;return r},o.hsl.hsv=function(t){var e=t[0],n=t[1]/100,i=t[2]/100,r=n,a=Math.max(i,.01);return n*=(i*=2)<=1?i:2-i,r*=a<=1?a:2-a,[e,100*(0===i?2*r/(a+r):2*n/(i+n)),100*((i+n)/2)]},o.hsv.rgb=function(t){var e=t[0]/60,n=t[1]/100,i=t[2]/100,r=Math.floor(e)%6,a=e-Math.floor(e),o=255*i*(1-n),s=255*i*(1-n*a),l=255*i*(1-n*(1-a));switch(i*=255,r){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]}},o.hsv.hsl=function(t){var e=t[0],n=t[1]/100,i=t[2]/100,r=Math.max(i,.01),a=(2-n)*i,o=(2-n)*r,s=n*r;return[e,100*(s=(s/=o<=1?o:2-o)||0),100*(a/=2)]},o.hwb.rgb=function(t){var e,n,i,r,a,o,s,l=t[0]/360,u=t[1]/100,d=t[2]/100,h=u+d;switch(1<h&&(u/=h,d/=h),i=6*l-(e=Math.floor(6*l)),0!=(1&e)&&(i=1-i),r=u+i*((n=1-d)-u),e){default:case 6:case 0:a=n,o=r,s=u;break;case 1:a=r,o=n,s=u;break;case 2:a=u,o=n,s=r;break;case 3:a=u,o=r,s=n;break;case 4:a=r,o=u,s=n;break;case 5:a=n,o=u,s=r}return[255*a,255*o,255*s]},o.cmyk.rgb=function(t){var e=t[0]/100,n=t[1]/100,i=t[2]/100,r=t[3]/100;return[255*(1-Math.min(1,e*(1-r)+r)),255*(1-Math.min(1,n*(1-r)+r)),255*(1-Math.min(1,i*(1-r)+r))]},o.xyz.rgb=function(t){var e=t[0]/100,n=t[1]/100,i=t[2]/100,r=3.2406*e+-1.5372*n+-.4986*i,a=-.9689*e+1.8758*n+.0415*i,o=.0557*e+-.204*n+1.057*i;return r=.0031308<r?1.055*Math.pow(r,1/2.4)-.055:12.92*r,a=.0031308<a?1.055*Math.pow(a,1/2.4)-.055:12.92*a,o=.0031308<o?1.055*Math.pow(o,1/2.4)-.055:12.92*o,[255*(r=Math.min(Math.max(0,r),1)),255*(a=Math.min(Math.max(0,a),1)),255*(o=Math.min(Math.max(0,o),1))]},o.xyz.lab=function(t){var e=t[0],n=t[1],i=t[2];return n/=100,i/=108.883,e=.008856<(e/=95.047)?Math.pow(e,1/3):7.787*e+16/116,[116*(n=.008856<n?Math.pow(n,1/3):7.787*n+16/116)-16,500*(e-n),200*(n-(i=.008856<i?Math.pow(i,1/3):7.787*i+16/116))]},o.lab.xyz=function(t){var e=(t[0]+16)/116,n=t[1]/500+e,i=e-t[2]/200,r=Math.pow(e,3),a=Math.pow(n,3),o=Math.pow(i,3);return e=.008856<r?r:(e-16/116)/7.787,n=.008856<a?a:(n-16/116)/7.787,i=.008856<o?o:(i-16/116)/7.787,[n*=95.047,e*=100,i*=108.883]},o.lab.lch=function(t){var e=t[0],n=t[1],i=t[2],r=360*Math.atan2(i,n)/2/Math.PI;return r<0&&(r+=360),[e,Math.sqrt(n*n+i*i),r]},o.lch.lab=function(t){var e=t[0],n=t[1],i=t[2]/360*2*Math.PI;return[e,n*Math.cos(i),n*Math.sin(i)]},o.rgb.ansi16=function(t){var e=t[0],n=t[1],i=t[2],r=1 in arguments?arguments[1]:o.rgb.hsv(t)[2];if(0===(r=Math.round(r/50)))return 30;var a=30+(Math.round(i/255)<<2|Math.round(n/255)<<1|Math.round(e/255));return 2===r&&(a+=60),a},o.hsv.ansi16=function(t){return o.rgb.ansi16(o.hsv.rgb(t),t[2])},o.rgb.ansi256=function(t){var e=t[0],n=t[1],i=t[2];return e===n&&n===i?e<8?16:248<e?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)},o.ansi16.rgb=function(t){var e=t%10;if(0===e||7===e)return 50<t&&(e+=3.5),[e=e/10.5*255,e,e];var n=.5*(1+~~(50<t));return[(1&e)*n*255,(e>>1&1)*n*255,(e>>2&1)*n*255]},o.ansi256.rgb=function(t){if(232<=t){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]},o.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},o.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]},o.rgb.hcg=function(t){var e=t[0]/255,n=t[1]/255,i=t[2]/255,r=Math.max(Math.max(e,n),i),a=Math.min(Math.min(e,n),i),o=r-a,s=o<1?a/(1-o):0,l=o<=0?0:r===e?(n-i)/o%6:r===n?2+(i-e)/o:4+(e-n)/o+4;return l/=6,[360*(l%=1),100*o,100*s]},o.hsl.hcg=function(t){var e=t[1]/100,n=t[2]/100,i=1,r=0;return(i=n<.5?2*e*n:2*e*(1-n))<1&&(r=(n-.5*i)/(1-i)),[t[0],100*i,100*r]},o.hsv.hcg=function(t){var e=t[1]/100,n=t[2]/100,i=e*n,r=i<1?(n-i)/(1-i):0;return[t[0],100*i,100*r]},o.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 r,a=[0,0,0],o=e%1*6,s=o%1,l=1-s;switch(Math.floor(o)){case 0:a[0]=1,a[1]=s,a[2]=0;break;case 1:a[0]=l,a[1]=1,a[2]=0;break;case 2:a[0]=0,a[1]=1,a[2]=s;break;case 3:a[0]=0,a[1]=l,a[2]=1;break;case 4:a[0]=s,a[1]=0,a[2]=1;break;default:a[0]=1,a[1]=0,a[2]=l}return r=(1-n)*i,[255*(n*a[0]+r),255*(n*a[1]+r),255*(n*a[2]+r)]},o.hcg.hsv=function(t){var e=t[1]/100,n=e+t[2]/100*(1-e),i=0<n?e/n:0;return[t[0],100*i,100*n]},o.hcg.hsl=function(t){var e=t[1]/100,n=t[2]/100*(1-e)+.5*e,i=0;return 0<n&&n<.5?i=e/(2*n):.5<=n&&n<1&&(i=e/(2*(1-n))),[t[0],100*i,100*n]},o.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)]},o.hwb.hcg=function(t){var e=t[1]/100,n=1-t[2]/100,i=n-e,r=i<1?(n-i)/(1-i):0;return[t[0],100*i,100*r]},o.apple.rgb=function(t){return[t[0]/65535*255,t[1]/65535*255,t[2]/65535*255]},o.rgb.apple=function(t){return[t[0]/255*65535,t[1]/255*65535,t[2]/255*65535]},o.gray.rgb=function(t){return[t[0]/100*255,t[0]/100*255,t[0]/100*255]},o.gray.hsl=o.gray.hsv=function(t){return[0,0,t[0]]},o.gray.hwb=function(t){return[0,100,t[0]]},o.gray.cmyk=function(t){return[0,0,0,t[0]]},o.gray.lab=function(t){return[t[0],0,0]},o.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},o.rgb.gray=function(t){return[(t[0]+t[1]+t[2])/3/255*100]}});u.rgb,u.hsl,u.hsv,u.hwb,u.cmyk,u.xyz,u.lab,u.lch,u.hex,u.keyword,u.ansi16,u.ansi256,u.hcg,u.apple,u.gray;function s(t){var e=function(){for(var t={},e=Object.keys(u),n=e.length,i=0;i<n;i++)t[e[i]]={distance:-1,parent:null};return t}(),n=[t];for(e[t].distance=0;n.length;)for(var i=n.pop(),r=Object.keys(u[i]),a=r.length,o=0;o<a;o++){var s=r[o],l=e[s];-1===l.distance&&(l.distance=e[i].distance+1,l.parent=i,n.unshift(s))}return e}function l(t,e){for(var n=[e[t].parent,t],i=u[e[t].parent][t],r=e[t].parent;e[r].parent;)n.unshift(e[r].parent),i=function(e,n){return function(t){return n(e(t))}}(u[e[r].parent][r],i),r=e[r].parent;return i.conversion=n,i}var r={};function a(e){function t(t){return null==t?t:(1<arguments.length&&(t=Array.prototype.slice.call(arguments)),e(t))}return"conversion"in e&&(t.conversion=e.conversion),t}function o(r){function t(t){if(null==t)return t;1<arguments.length&&(t=Array.prototype.slice.call(arguments));var e=r(t);if("object"==typeof e)for(var n=e.length,i=0;i<n;i++)e[i]=Math.round(e[i]);return e}return"conversion"in r&&(t.conversion=r.conversion),t}Object.keys(u).forEach(function(n){r[n]={},Object.defineProperty(r[n],"channels",{value:u[n].channels}),Object.defineProperty(r[n],"labels",{value:u[n].labels});var i=function(t){for(var e=s(t),n={},i=Object.keys(e),r=i.length,a=0;a<r;a++){var o=i[a];null!==e[o].parent&&(n[o]=l(o,e))}return n}(n);Object.keys(i).forEach(function(t){var e=i[t];r[n][t]=o(e),r[n][t].raw=a(e)})});var h=r,c={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={getRgba:i,getHsla:f,getRgb:function(t){var e=i(t);return e&&e.slice(0,3)},getHsl:function(t){var e=f(t);return e&&e.slice(0,3)},getHwb:g,getAlpha:function(t){var e=i(t);{if(e)return e[3];if(e=f(t))return e[3];if(e=g(t))return e[3]}},hexString:function(t,e){e=void 0!==e&&3===t.length?e:t[3];return"#"+b(t[0])+b(t[1])+b(t[2])+(0<=e&&e<1?b(Math.round(255*e)):"")},rgbString:function(t,e){if(e<1||t[3]&&t[3]<1)return m(t,e);return"rgb("+t[0]+", "+t[1]+", "+t[2]+")"},rgbaString:m,percentString:function(t,e){if(e<1||t[3]&&t[3]<1)return p(t,e);var n=Math.round(t[0]/255*100),i=Math.round(t[1]/255*100),r=Math.round(t[2]/255*100);return"rgb("+n+"%, "+i+"%, "+r+"%)"},percentaString:p,hslString:function(t,e){if(e<1||t[3]&&t[3]<1)return v(t,e);return"hsl("+t[0]+", "+t[1]+"%, "+t[2]+"%)"},hslaString:v,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 e[t.slice(0,3)]}};function i(t){if(t){var e=[0,0,0],n=1,i=t.match(/^#([a-fA-F0-9]{3,4})$/i),r="";if(i){r=(i=i[1])[3];for(var a=0;a<e.length;a++)e[a]=parseInt(i[a]+i[a],16);r&&(n=Math.round(parseInt(r+r,16)/255*100)/100)}else if(i=t.match(/^#([a-fA-F0-9]{6}([a-fA-F0-9]{2})?)$/i)){r=i[2],i=i[1];for(a=0;a<e.length;a++)e[a]=parseInt(i.slice(2*a,2*a+2),16);r&&(n=Math.round(parseInt(r,16)/255*100)/100)}else if(i=t.match(/^rgba?\(\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/i)){for(a=0;a<e.length;a++)e[a]=parseInt(i[a+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(a=0;a<e.length;a++)e[a]=Math.round(2.55*parseFloat(i[a+1]));n=parseFloat(i[4])}else if(i=t.match(/(\w+)/)){if("transparent"==i[1])return[0,0,0,0];if(!(e=c[i[1]]))return}for(a=0;a<e.length;a++)e[a]=y(e[a],0,255);return n=n||0==n?y(n,0,1):1,e[3]=n,e}}function f(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[y(parseInt(e[1]),0,360),y(parseFloat(e[2]),0,100),y(parseFloat(e[3]),0,100),y(isNaN(n)?1:n,0,1)]}}}function g(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[y(parseInt(e[1]),0,360),y(parseFloat(e[2]),0,100),y(parseFloat(e[3]),0,100),y(isNaN(n)?1:n,0,1)]}}}function m(t,e){return void 0===e&&(e=void 0!==t[3]?t[3]:1),"rgba("+t[0]+", "+t[1]+", "+t[2]+", "+e+")"}function p(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 v(t,e){return void 0===e&&(e=void 0!==t[3]?t[3]:1),"hsla("+t[0]+", "+t[1]+"%, "+t[2]+"%, "+e+")"}function y(t,e,n){return Math.min(Math.max(e,t),n)}function b(t){var e=t.toString(16).toUpperCase();return e.length<2?"0"+e:e}var e={};for(var x in c)e[c[x]]=x;var _=function(t){return t instanceof _?t:this instanceof _?(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=n.getRgba(t))?this.setValues("rgb",e):(e=n.getHsla(t))?this.setValues("hsl",e):(e=n.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 _(t);var e};_.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 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=[],n=0;n<t.length;n++){var i=t[n]/255;e[n]=i<=.03928?i/12.92:Math.pow((.055+i)/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 n<e?(e+.05)/(n+.05):(n+.05)/(e+.05)},level:function(t){var e=this.contrast(t);return 7.1<=e?"AAA":4.5<=e?"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=this,i=t,r=void 0===e?.5:e,a=2*r-1,o=n.alpha()-i.alpha(),s=(1+(a*o==-1?a:(a+o)/(1+a*o)))/2,l=1-s;return this.rgb(s*n.red()+l*i.red(),s*n.green()+l*i.green(),s*n.blue()+l*i.blue()).alpha(n.alpha()*r+i.alpha()*(1-r))},toJSON:function(){return this.rgb()},clone:function(){var t,e,n=new _,i=this.values,r=n.values;for(var a in i)i.hasOwnProperty(a)&&(t=i[a],"[object Array]"===(e={}.toString.call(t))?r[a]=t.slice(0):"[object Number]"===e?r[a]=t:console.error("unexpected color value:",t));return n}},_.prototype.spaces={rgb:["red","green","blue"],hsl:["hue","saturation","lightness"],hsv:["hue","saturation","value"],hwb:["hue","whiteness","blackness"],cmyk:["cyan","magenta","yellow","black"]},_.prototype.maxes={rgb:[255,255,255],hsl:[360,100,100],hsv:[360,100,100],hwb:[360,100,100],cmyk:[100,100,100,100]},_.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},_.prototype.setValues=function(t,e){var n,i=this.values,r=this.spaces,a=this.maxes,o=1;if(this.valid=!0,"alpha"===t)o=e;else if(e.length)i[t]=e.slice(0,t.length),o=e[t.length];else if(void 0!==e[t.charAt(0)]){for(l=0;l<t.length;l++)i[t][l]=e[t.charAt(l)];o=e.a}else if(void 0!==e[r[t][0]]){for(var s=r[t],l=0;l<t.length;l++)i[t][l]=e[s[l]];o=e.alpha}if(i.alpha=Math.max(0,Math.min(1,void 0===o?i.alpha:o)),"alpha"===t)return!1;for(l=0;l<t.length;l++)n=Math.max(0,Math.min(a[t][l],i[t][l])),i[t][l]=Math.round(n);for(var u in r)u!==t&&(i[u]=h[t][u](i[t]));return!0},_.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)},_.prototype.setChannel=function(t,e,n){var i=this.values[t];return void 0===n?i[e]:(n===i[e]||(i[e]=n,this.setValues(t,i)),this)},"undefined"!=typeof window&&(window.Chart=window.Chart||{},window.Chart.Color=_,void 0===window.Color&&(window.Color=_));var w=_;function k(t){return-1===["__proto__","prototype","constructor"].indexOf(t)}var M,S={noop:function(){},uid:(M=0,function(){return M++}),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 S.valueOrDefault(S.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 r,a,o;if(S.isArray(t))if(a=t.length,i)for(r=a-1;0<=r;r--)e.call(n,t[r],r);else for(r=0;r<a;r++)e.call(n,t[r],r);else if(S.isObject(t))for(a=(o=Object.keys(t)).length,r=0;r<a;r++)e.call(n,t[o[r]],o[r])},arrayEquals:function(t,e){var n,i,r,a;if(!t||!e||t.length!==e.length)return!1;for(n=0,i=t.length;n<i;++n)if(r=t[n],a=e[n],r instanceof Array&&a instanceof Array){if(!S.arrayEquals(r,a))return!1}else if(r!==a)return!1;return!0},clone:function(t){if(S.isArray(t))return t.map(S.clone);if(S.isObject(t)){for(var e=Object.create(t),n=Object.keys(t),i=n.length,r=0;r<i;++r)e[n[r]]=S.clone(t[n[r]]);return e}return t},_merger:function(t,e,n,i){var r,a;k(t)&&(r=e[t],a=n[t],S.isObject(r)&&S.isObject(a)?S.merge(r,a,i):e[t]=S.clone(a))},_mergerIf:function(t,e,n){var i,r;k(t)&&(i=e[t],r=n[t],S.isObject(i)&&S.isObject(r)?S.mergeIf(i,r):e.hasOwnProperty(t)||(e[t]=S.clone(r)))},merge:function(t,e,n){var i,r,a,o,s,l=S.isArray(e)?e:[e],u=l.length;if(!S.isObject(t))return t;for(i=(n=n||{}).merger||S._merger,r=0;r<u;++r)if(e=l[r],S.isObject(e))for(s=0,o=(a=Object.keys(e)).length;s<o;++s)i(a[s],t,e,n);return t},mergeIf:function(t,e){return S.merge(t,e,{merger:S._mergerIf})},extend:Object.assign||function(t){return S.merge(t,[].slice.call(arguments,1),{merger:function(t,e,n){e[t]=n[t]}})},inherits:function(t){function e(){this.constructor=i}var n=this,i=t&&t.hasOwnProperty("constructor")?t.constructor:function(){return n.apply(this,arguments)};return e.prototype=n.prototype,i.prototype=new e,i.extend=S.inherits,t&&S.extend(i.prototype,t),i.__super__=n.prototype,i},_deprecated:function(t,e,n,i){void 0!==e&&console.warn(t+': "'+n+'" is deprecated. Please use "'+i+'" instead')}},D=S;S.callCallback=S.callback,S.indexOf=function(t,e,n){return Array.prototype.indexOf.call(t,e,n)},S.getValueOrDefault=S.valueOrDefault,S.getValueAtIndexOrDefault=S.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*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*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*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 1<=t?t:-(Math.sqrt(1-t*t)-1)},easeOutCirc:function(t){return Math.sqrt(1- --t*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,e=i<1?(i=1,n/4):n/(2*Math.PI)*Math.asin(1/i),-(i*Math.pow(2,10*--t)*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,e=i<1?(i=1,n/4):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,e=i<1?(i=1,n/4):n/(2*Math.PI)*Math.asin(1/i),t<1?i*Math.pow(2,10*--t)*Math.sin((t-e)*(2*Math.PI)/n)*-.5:i*Math.pow(2,-10*--t)*Math.sin((t-e)*(2*Math.PI)/n)*.5+1)},easeInBack:function(t){return t*t*(2.70158*t-1.70158)},easeOutBack:function(t){return--t*t*(2.70158*t+1.70158)+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};D.easingEffects=C;var T=Math.PI,O=T/180,A=2*T,F=T/2,I=T/4,L=2*T/3,R={clear:function(t){t.ctx.clearRect(0,0,t.width,t.height)},roundedRect:function(t,e,n,i,r,a){var o,s,l,u,d;a?(s=e+(o=Math.min(a,r/2,i/2)),l=n+o,u=e+i-o,d=n+r-o,t.moveTo(e,l),s<u&&l<d?(t.arc(s,l,o,-T,-F),t.arc(u,l,o,-F,0),t.arc(u,d,o,0,F),t.arc(s,d,o,F,T)):s<u?(t.moveTo(s,n),t.arc(u,l,o,-F,F),t.arc(s,l,o,F,T+F)):l<d?(t.arc(s,l,o,-T,0),t.arc(s,d,o,0,T)):t.arc(s,l,o,-T,T),t.closePath(),t.moveTo(e,n)):t.rect(e,n,i,r)},drawPoint:function(t,e,n,i,r,a){var o,s,l,u,d,h=(a||0)*O;if(e&&"object"==typeof e&&("[object HTMLImageElement]"===(o=e.toString())||"[object HTMLCanvasElement]"===o))return t.save(),t.translate(i,r),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,r,n,0,A),t.closePath();break;case"triangle":t.moveTo(i+Math.sin(h)*n,r-Math.cos(h)*n),h+=L,t.lineTo(i+Math.sin(h)*n,r-Math.cos(h)*n),h+=L,t.lineTo(i+Math.sin(h)*n,r-Math.cos(h)*n),t.closePath();break;case"rectRounded":u=n-(d=.516*n),s=Math.cos(h+I)*u,l=Math.sin(h+I)*u,t.arc(i-s,r-l,d,h-T,h-F),t.arc(i+l,r-s,d,h-F,h),t.arc(i+s,r+l,d,h,h+F),t.arc(i-l,r+s,d,h+F,h+T),t.closePath();break;case"rect":if(!a){u=Math.SQRT1_2*n,t.rect(i-u,r-u,2*u,2*u);break}h+=I;case"rectRot":s=Math.cos(h)*n,l=Math.sin(h)*n,t.moveTo(i-s,r-l),t.lineTo(i+l,r-s),t.lineTo(i+s,r+l),t.lineTo(i-l,r+s),t.closePath();break;case"crossRot":h+=I;case"cross":s=Math.cos(h)*n,l=Math.sin(h)*n,t.moveTo(i-s,r-l),t.lineTo(i+s,r+l),t.moveTo(i+l,r-s),t.lineTo(i-l,r+s);break;case"star":s=Math.cos(h)*n,l=Math.sin(h)*n,t.moveTo(i-s,r-l),t.lineTo(i+s,r+l),t.moveTo(i+l,r-s),t.lineTo(i-l,r+s),h+=I,s=Math.cos(h)*n,l=Math.sin(h)*n,t.moveTo(i-s,r-l),t.lineTo(i+s,r+l),t.moveTo(i+l,r-s),t.lineTo(i-l,r+s);break;case"line":s=Math.cos(h)*n,l=Math.sin(h)*n,t.moveTo(i-s,r-l),t.lineTo(i+s,r+l);break;case"dash":t.moveTo(i,r),t.lineTo(i+Math.cos(h)*n,r+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 r,a=n.steppedLine;if(a)return"middle"===a?(r=(e.x+n.x)/2,t.lineTo(r,i?n.y:e.y),t.lineTo(r,i?e.y:n.y)):"after"===a&&!i||"after"!==a&&i?t.lineTo(e.x,n.y):t.lineTo(n.x,e.y),void t.lineTo(n.x,n.y);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)}},N=R;D.clear=R.clear,D.drawRoundedRectangle=function(t){t.beginPath(),R.roundedRect.apply(R,arguments)};var W={_set:function(t,e){return D.merge(this[t]||(this[t]={}),e)}};W._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 Y=W,z=D.valueOrDefault;var V={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,r;return D.isObject(t)?(e=+t.top||0,n=+t.right||0,i=+t.bottom||0,r=+t.left||0):e=n=i=r=+t||0,{top:e,right:n,bottom:i,left:r,height:e+i,width:r+n}},_parseFont:function(t){var e,n=Y.global,i=z(t.fontSize,n.defaultFontSize),r={family:z(t.fontFamily,n.defaultFontFamily),lineHeight:D.options.toLineHeight(z(t.lineHeight,n.defaultLineHeight),i),size:i,style:z(t.fontStyle,n.defaultFontStyle),weight:null,string:""};return r.string=!(e=r)||D.isNullOrUndef(e.size)||D.isNullOrUndef(e.family)?null:(e.style?e.style+" ":"")+(e.weight?e.weight+" ":"")+e.size+"px "+e.family,r},resolve:function(t,e,n,i){for(var r,a=!0,o=0,s=t.length;o<s;++o)if(void 0!==(r=t[o])&&(void 0!==e&&"function"==typeof r&&(r=r(e),a=!1),void 0!==n&&D.isArray(r)&&(r=r[n],a=!1),void 0!==r))return i&&!a&&(i.cacheable=!1),r}},E={_factorize:function(t){for(var e=[],n=Math.sqrt(t),i=1;i<n;i++)t%i==0&&(e.push(i),e.push(t/i));return n===(0|n)&&e.push(n),e.sort(function(t,e){return t-e}).pop(),e},log10:Math.log10||function(t){var e=Math.log(t)*Math.LOG10E,n=Math.round(e);return t===Math.pow(10,n)?n:e}},H=E;D.log10=E.log10;var B=D,j=N,U=V,G=H,q={getRtlAdapter:function(t,e,n){return t?(i=e,r=n,{x:function(t){return i+i+r-t},setWidth:function(t){r=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}}):{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}};var i,r},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]))}};B.easing=P,B.canvas=j,B.options=U,B.math=G,B.rtl=q;function Z(t){B.extend(this,t),this.initialize.apply(this,arguments)}B.extend(Z.prototype,{_type:void 0,initialize:function(){this.hidden=!1},pivot:function(){var t=this;return t._view||(t._view=B.extend({},t._model)),t._start={},t},transition:function(t){var e=this,n=e._model,i=e._start,r=e._view;return n&&1!==t?(r=r||(e._view={}),function(t,e,n,i){for(var r,a,o,s,l,u,d,h=Object.keys(n),c=0,f=h.length;c<f;++c)if(s=n[r=h[c]],e.hasOwnProperty(r)||(e[r]=s),(a=e[r])!==s&&"_"!==r[0]){if(t.hasOwnProperty(r)||(t[r]=a),(l=typeof s)==typeof(o=t[r]))if("string"==l){if((u=w(o)).valid&&(d=w(s)).valid){e[r]=d.mix(u,i).rgbString();continue}}else if(B.isFinite(o)&&B.isFinite(s)){e[r]=o+(s-o)*i;continue}e[r]=s}}(i=i||(e._start={}),r,n,t)):(e._view=B.extend({},n),e._start=null),e},tooltipPosition:function(){return{x:this._model.x,y:this._model.y}},hasValue:function(){return B.isNumber(this._model.x)&&B.isNumber(this._model.y)}}),Z.extend=B.inherits;var $=Z,X=$.extend({chart:null,currentStep:0,numSteps:60,easing:"",render:null,onAnimationProgress:null,onAnimationComplete:null}),K=X;Object.defineProperty(X.prototype,"animationObject",{get:function(){return this}}),Object.defineProperty(X.prototype,"chartInstance",{get:function(){return this.chart},set:function(t){this.chart=t}}),Y._set("global",{animation:{duration:1e3,easing:"easeOutQuart",onProgress:B.noop,onComplete:B.noop}});var J={animations:[],request:null,addAnimation:function(t,e,n,i){var r,a,o=this.animations;for(e.chart=t,e.startTime=Date.now(),e.duration=n,i||(t.animating=!0),r=0,a=o.length;r<a;++r)if(o[r].chart===t)return void(o[r]=e);o.push(e),1===o.length&&this.requestAnimationFrame()},cancelAnimation:function(e){var t=B.findIndex(this.animations,function(t){return t.chart===e});-1!==t&&(this.animations.splice(t,1),e.animating=!1)},requestAnimationFrame:function(){var t=this;null===t.request&&(t.request=B.requestAnimFrame.call(window,function(){t.request=null,t.startDigest()}))},startDigest:function(){this.advance(),0<this.animations.length&&this.requestAnimationFrame()},advance:function(){for(var t,e,n,i,r=this.animations,a=0;a<r.length;)e=(t=r[a]).chart,n=t.numSteps,i=Math.floor((Date.now()-t.startTime)/t.duration*n)+1,t.currentStep=Math.min(i,n),B.callback(t.render,[e,t],e),B.callback(t.onAnimationProgress,[t],e),t.currentStep>=n?(B.callback(t.onAnimationComplete,[t],e),e.animating=!1,r.splice(a,1)):++a}},Q=B.options.resolve,tt=["push","pop","shift","splice","unshift"];function et(e,t){var n,i,r=e._chartjs;r&&(-1!==(i=(n=r.listeners).indexOf(t))&&n.splice(i,1),0<n.length||(tt.forEach(function(t){delete e[t]}),delete e._chartjs))}function nt(t,e){this.initialize(t,e)}B.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(),r=e.options.scales;null!==t.xAxisID&&t.xAxisID in n&&!i.xAxisID||(t.xAxisID=i.xAxisID||r.xAxes[0].id),null!==t.yAxisID&&t.yAxisID in n&&!i.yAxisID||(t.yAxisID=i.yAxisID||r.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(){for(var t=this.getMeta(),e=this.getDataset().data||[],n=t.data,i=0,r=e.length;i<r;++i)n[i]=n[i]||this.createMetaData(i);t.dataset=t.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 r,t,e=this,n=e.getDataset(),i=n.data||(n.data=[]);e._data!==i&&(e._data&&et(e._data,e),i&&Object.isExtensible(i)&&(t=e,(r=i)._chartjs?r._chartjs.listeners.push(t):(Object.defineProperty(r,"_chartjs",{configurable:!0,enumerable:!1,value:{listeners:[t]}}),tt.forEach(function(t){var n="onData"+t.charAt(0).toUpperCase()+t.slice(1),i=r[t];Object.defineProperty(r,t,{configurable:!0,enumerable:!1,value:function(){var e=Array.prototype.slice.call(arguments),t=i.apply(this,e);return B.each(r._chartjs.listeners,function(t){"function"==typeof t[n]&&t[n].apply(t,e)}),t}})}))),e._data=i),e.resyncElements()},_configure:function(){this._config=B.merge(Object.create(null),[this.chart.options.datasets[this._type],this.getDataset()],{merger:function(t,e,n){"_meta"!==t&&"data"!==t&&B._merger(t,e,n)}})},_update:function(t){this._configure(),this._cachedDataOpts=null,this.update(t)},update:B.noop,transition:function(t){for(var e=this.getMeta(),n=e.data||[],i=n.length,r=0;r<i;++r)n[r].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(),!1!==(e=i&&void 0===t?this._resolveDatasetElementOptions(i||{}):(t=t||0,this._resolveDataElementOptions(n.data[t]||{},t))).fill&&null!==e.fill||(e.backgroundColor=e.borderColor),e},_resolveDatasetElementOptions:function(t,e){for(var n,i,r=this,a=r.chart,o=r._config,s=t.custom||{},l=a.options.elements[r.datasetElementType.prototype._type]||{},u=r._datasetElementOptions,d={},h={chart:a,dataset:r.getDataset(),datasetIndex:r.index,hover:e},c=0,f=u.length;c<f;++c)n=u[c],i=e?"hover"+n.charAt(0).toUpperCase()+n.slice(1):n,d[n]=Q([s[i],o[i],l[i]],h);return d},_resolveDataElementOptions:function(t,e){var n=this,i=t&&t.custom,r=n._cachedDataOpts;if(r&&!i)return r;var a,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},m={cacheable:!i},i=i||{};if(B.isArray(c))for(o=0,s=c.length;o<s;++o)f[l=c[o]]=Q([i[l],d[l],h[l]],g,e,m);else for(o=0,s=(a=Object.keys(c)).length;o<s;++o)f[l=a[o]]=Q([i[l],d[c[l]],d[l],h[l]],g,e,m);return m.cacheable&&(n._cachedDataOpts=Object.freeze(f)),f},removeHoverStyle:function(t){B.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||{},r=t._model,a=B.getHoverColor;t.$previousStyle={backgroundColor:r.backgroundColor,borderColor:r.borderColor,borderWidth:r.borderWidth},r.backgroundColor=Q([i.hoverBackgroundColor,e.hoverBackgroundColor,a(r.backgroundColor)],void 0,n),r.borderColor=Q([i.hoverBorderColor,e.hoverBorderColor,a(r.borderColor)],void 0,n),r.borderWidth=Q([i.hoverBorderWidth,e.hoverBorderWidth,r.borderWidth],void 0,n)},_removeDatasetHoverStyle:function(){var t=this.getMeta().dataset;t&&this.removeHoverStyle(t)},_setDatasetHoverStyle:function(){var t,e,n,i,r,a,o=this.getMeta().dataset,s={};if(o){for(a=o._model,r=this._resolveDatasetElementOptions(o,!0),t=0,e=(i=Object.keys(r)).length;t<e;++t)s[n=i[t]]=a[n],a[n]=r[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):n<i&&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=B.inherits;var it=nt,rt=2*Math.PI;function at(t,e){var n=e.startAngle,i=e.endAngle,r=e.pixelMargin,a=r/e.outerRadius,o=e.x,s=e.y;t.beginPath(),t.arc(o,s,e.outerRadius,n-a,i+a),e.innerRadius>r?(a=r/e.innerRadius,t.arc(o,s,e.innerRadius-r,i+a,n-a,!0)):t.arc(o,s,r,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 r,a=n.endAngle;for(i&&(n.endAngle=n.startAngle+rt,at(t,n),n.endAngle=a,n.endAngle===n.startAngle&&n.fullCircles&&(n.endAngle+=rt,n.fullCircles--)),t.beginPath(),t.arc(n.x,n.y,n.innerRadius,n.startAngle+rt,n.startAngle,!0),r=0;r<n.fullCircles;++r)t.stroke();for(t.beginPath(),t.arc(n.x,n.y,e.outerRadius,n.startAngle,n.startAngle+rt),r=0;r<n.fullCircles;++r)t.stroke()}(t,e,n,i),i&&at(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()}Y._set("global",{elements:{arc:{backgroundColor:Y.global.defaultColor,borderColor:"#fff",borderWidth:2,borderAlign:"center"}}});var st=$.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=B.getAngleFromPoint(n,{x:t,y:e}),r=i.angle,a=i.distance,o=n.startAngle,s=n.endAngle;s<o;)s+=rt;for(;s<r;)r-=rt;for(;r<o;)r+=rt;var l=o<=r&&r<=s,u=a>=n.innerRadius&&a<=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,r={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/rt)};if(e.save(),e.fillStyle=n.backgroundColor,e.strokeStyle=n.borderColor,r.fullCircles){for(r.endAngle=r.startAngle+rt,e.beginPath(),e.arc(r.x,r.y,r.outerRadius,r.startAngle,r.endAngle),e.arc(r.x,r.y,r.innerRadius,r.endAngle,r.startAngle,!0),e.closePath(),t=0;t<r.fullCircles;++t)e.fill();r.endAngle=r.startAngle+n.circumference%rt}e.beginPath(),e.arc(r.x,r.y,r.outerRadius,r.startAngle,r.endAngle),e.arc(r.x,r.y,r.innerRadius,r.endAngle,r.startAngle,!0),e.closePath(),e.fill(),n.borderWidth&&ot(e,n,r),e.restore()}}),lt=B.valueOrDefault,ut=Y.global.defaultColor;Y._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=$.extend({_type:"line",draw:function(){var t,e,n,i=this,r=i._view,a=i._chart.ctx,o=r.spanGaps,s=i._children.slice(),l=Y.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=B.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(a.save(),a.lineCap=r.borderCapStyle||u.borderCapStyle,a.setLineDash&&a.setLineDash(r.borderDash||u.borderDash),a.lineDashOffset=lt(r.borderDashOffset,u.borderDashOffset),a.lineJoin=r.borderJoinStyle||u.borderJoinStyle,a.lineWidth=lt(r.borderWidth,u.borderWidth),a.strokeStyle=r.borderColor||l.defaultColor,a.beginPath(),(n=s[0]._view).skip||(a.moveTo(n.x,n.y),d=0),t=1;t<s.length;++t)n=s[t]._view,e=-1===d?B.previousItem(s,t):s[d],n.skip||(d!==t-1&&!o||-1===d?a.moveTo(n.x,n.y):B.canvas.lineTo(a,e._view,n),d=t);h&&a.closePath(),a.stroke(),a.restore()}}}),ht=B.valueOrDefault,ct=Y.global.defaultColor;function ft(t){var e=this._view;return!!e&&Math.abs(t-e.x)<e.radius+e.hitRadius}Y._set("global",{elements:{point:{radius:3,pointStyle:"circle",backgroundColor:ct,borderColor:ct,borderWidth:1,hitRadius:1,hoverRadius:4,hoverBorderWidth:1}}});var gt=$.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,r=e.rotation,a=e.radius,o=e.x,s=e.y,l=Y.global,u=l.defaultColor;e.skip||void 0!==t&&!B.canvas._isPointInArea(e,t)||(n.strokeStyle=e.borderColor||u,n.lineWidth=ht(e.borderWidth,l.elements.point.borderWidth),n.fillStyle=e.backgroundColor||u,B.canvas.drawPoint(n,i,a,o,s,r))}}),mt=Y.global.defaultColor;function pt(t){return t&&void 0!==t.width}function vt(t){var e,n,i,r,a=pt(t)?(r=t.width/2,e=t.x-r,n=t.x+r,i=Math.min(t.y,t.base),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,t.y+r);return{left:e,top:i,right:n,bottom:a}}function yt(t,e,n){return t===e?n:t===n?e:t}function bt(t,e,n){var i,r,a,o,s,l,u,d=t.borderWidth,h=(r=(i=t).borderSkipped,a={},r&&(i.horizontal?i.base>i.x&&(r=yt(r,"left","right")):i.base<i.y&&(r=yt(r,"bottom","top")),a[r]=!0),a);return B.isObject(d)?(o=+d.top||0,s=+d.right||0,l=+d.bottom||0,u=+d.left||0):o=s=l=u=+d||0,{t:h.top||o<0?0:n<o?n:o,r:h.right||s<0?0:e<s?e:s,b:h.bottom||l<0?0:n<l?n:l,l:h.left||u<0?0:e<u?e:u}}function xt(t,e,n){var i=null===e,r=null===n,a=!(!t||i&&r)&&vt(t);return a&&(i||e>=a.left&&e<=a.right)&&(r||n>=a.top&&n<=a.bottom)}Y._set("global",{elements:{rectangle:{backgroundColor:mt,borderColor:mt,borderSkipped:"bottom",borderWidth:0}}});var _t=$.extend({_type:"rectangle",draw:function(){var t,e,n,i,r,a=this._chart.ctx,o=this._view,s=(e=vt(t=o),n=e.right-e.left,i=e.bottom-e.top,r=bt(t,n/2,i/2),{outer:{x:e.left,y:e.top,w:n,h:i},inner:{x:e.left+r.l,y:e.top+r.t,w:n-r.l-r.r,h:i-r.t-r.b}}),l=s.outer,u=s.inner;a.fillStyle=o.backgroundColor,a.fillRect(l.x,l.y,l.w,l.h),l.w===u.w&&l.h===u.h||(a.save(),a.beginPath(),a.rect(l.x,l.y,l.w,l.h),a.clip(),a.fillStyle=o.borderColor,a.rect(u.x,u.y,u.w,u.h),a.fill("evenodd"),a.restore())},height:function(){var t=this._view;return t.base-t.y},inRange:function(t,e){return xt(this._view,t,e)},inLabelRange:function(t,e){var n=this._view;return pt(n)?xt(n,t,null):xt(n,null,e)},inXRange:function(t){return xt(this._view,t,null)},inYRange:function(t){return xt(this._view,null,t)},getCenterPoint:function(){var t,e=this._view,n=pt(e)?(t=e.x,(e.y+e.base)/2):(t=(e.x+e.base)/2,e.y);return{x:t,y:n}},getArea:function(){var t=this._view;return pt(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}}}),wt={},kt=dt,Mt=gt,St=_t;wt.Arc=st,wt.Line=kt,wt.Point=Mt,wt.Rectangle=St;var Dt=B._deprecated,Ct=B.valueOrDefault;function Pt(t,e,n){var i,r=n.barThickness,a=e.stackCount,o=e.pixels[t],s=B.isNullOrUndef(r)?function(t,e){for(var n,i,r=t._length,a=1,o=e.length;a<o;++a)r=Math.min(r,Math.abs(e[a]-e[a-1]));for(a=0,o=t.getTicks().length;a<o;++a)i=t.getPixelForTick(a),r=0<a?Math.min(r,Math.abs(i-n)):r,n=i;return r}(e.scale,e.pixels):-1,l=B.isNullOrUndef(r)?(i=s*n.categoryPercentage,n.barPercentage):(i=r*a,1);return{chunk:i/a,ratio:l,start:o-i/2}}Y._set("bar",{hover:{mode:"label"},scales:{xAxes:[{type:"category",offset:!0,gridLines:{offsetGridLines:!0}}],yAxes:[{type:"linear"}]}}),Y._set("global",{datasets:{bar:{categoryPercentage:.8,barPercentage:.9}}});var Tt=it.extend({dataElementType:wt.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,Dt("bar chart",e.barPercentage,"scales.[x/y]Axes.barPercentage","dataset.barPercentage"),Dt("bar chart",e.barThickness,"scales.[x/y]Axes.barThickness","dataset.barThickness"),Dt("bar chart",e.categoryPercentage,"scales.[x/y]Axes.categoryPercentage","dataset.categoryPercentage"),Dt("bar chart",n._getValueScale().options.minBarLength,"scales.[x/y]Axes.minBarLength","dataset.minBarLength"),Dt("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,r=i.getMeta(),a=i.getDataset(),o=i._resolveDataElementOptions(t,e);t._xScale=i.getScaleForId(r.xAxisID),t._yScale=i.getScaleForId(r.yAxisID),t._datasetIndex=i.index,t._index=e,t._model={backgroundColor:o.backgroundColor,borderColor:o.borderColor,borderSkipped:o.borderSkipped,borderWidth:o.borderWidth,datasetLabel:a.label,label:i.chart.data.labels[e]},B.isArray(a.data[e])&&(t._model.borderSkipped=null),i._updateElementGeometry(t,e,n,o),t.pivot()},_updateElementGeometry:function(t,e,n,i){var r=this,a=t._model,o=r._getValueScale(),s=o.getBasePixel(),l=o.isHorizontal(),u=r._ruler||r.getRuler(),d=r.calculateBarValuePixels(r.index,e,i),h=r.calculateBarIndexPixels(r.index,e,u,i);a.horizontal=l,a.base=n?s:d.base,a.x=l?n?s:d.head:h.center,a.y=l?h.center:n?s:d.head,a.height=l?h.size:void 0,a.width=l?void 0:h.size},_getStacks:function(t){for(var e,n=this._getIndexScale(),i=n._getMatchingVisibleMetas(this._type),r=n.options.stacked,a=i.length,o=[],s=0;s<a&&(e=i[s],(!1===r||-1===o.indexOf(e.stack)||void 0===r&&void 0===e.stack)&&o.push(e.stack),e.index!==t);++s);return o},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(){for(var t=this._getIndexScale(),e=[],n=0,i=this.getMeta().data.length;n<i;++n)e.push(t.getPixelForValue(null,n,this.index));return{pixels:e,start:t._startPixel,end:t._endPixel,stackCount:this.getStackCount(),scale:t}},calculateBarValuePixels:function(t,e,n){var i,r,a,o,s,l,u,d=this.chart,h=this._getValueScale(),c=h.isHorizontal(),f=d.data.datasets,g=h._getMatchingVisibleMetas(this._type),m=h._parseValue(f[t].data[e]),p=n.minBarLength,v=h.options.stacked,y=this.getMeta().stack,b=void 0===m.start?0:0<=m.max&&0<=m.min?m.min:m.max,x=void 0===m.start?m.end:0<=m.max&&0<=m.min?m.max-m.min:m.min-m.max,_=g.length;if(v||void 0===v&&void 0!==y)for(i=0;i<_&&(r=g[i]).index!==t;++i)r.stack===y&&(a=void 0===(u=h._parseValue(f[r.index].data[e])).start?u.end:0<=u.min&&0<=u.max?u.max:u.min,(m.min<0&&a<0||0<=m.max&&0<a)&&(b+=a));return o=h.getPixelForValue(b),l=(s=h.getPixelForValue(b+x))-o,void 0!==p&&Math.abs(l)<p&&(l=p,s=0<=x&&!c||x<0&&c?o-p:o+p),{size:l,base:o,head:s,center:s+l/2}},calculateBarIndexPixels:function(t,e,n,i){var r,a,o,s,l,u,d,h,c,f="flex"===i.barThickness?(r=e,o=i,l=(a=n).pixels,u=l[r],d=0<r?l[r-1]:null,h=r<l.length-1?l[r+1]:null,c=o.categoryPercentage,null===d&&(d=u-(null===h?a.end-a.start:h-u)),null===h&&(h=u+u-d),s=u-(u-Math.min(d,h))/2*c,{chunk:Math.abs(h-d)/2*c/a.stackCount,ratio:o.barPercentage,start:s}):Pt(e,n,i),g=this.getStackIndex(t,this.getMeta().stack),m=f.start+f.chunk*g+f.chunk/2,p=Math.min(Ct(i.maxBarThickness,1/0),f.chunk*f.ratio);return{base:m-p/2,head:m+p/2,center:m,size:p}},draw:function(){var t=this.chart,e=this._getValueScale(),n=this.getMeta().data,i=this.getDataset(),r=n.length,a=0;for(B.canvas.clipArea(t.ctx,t.chartArea);a<r;++a){var o=e._parseValue(i.data[a]);isNaN(o.min)||isNaN(o.max)||n[a].draw()}B.canvas.unclipArea(t.ctx)},_resolveDataElementOptions:function(){var t=B.extend({},it.prototype._resolveDataElementOptions.apply(this,arguments)),e=this._getIndexScale().options,n=this._getValueScale().options;return t.barPercentage=Ct(e.barPercentage,t.barPercentage),t.barThickness=Ct(e.barThickness,t.barThickness),t.categoryPercentage=Ct(e.categoryPercentage,t.categoryPercentage),t.maxBarThickness=Ct(e.maxBarThickness,t.maxBarThickness),t.minBarLength=Ct(n.minBarLength,t.minBarLength),t}}),Ot=B.valueOrDefault,At=B.options.resolve;Y._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 Ft=it.extend({dataElementType:wt.Point,_dataElementOptions:["backgroundColor","borderColor","borderWidth","hoverBackgroundColor","hoverBorderColor","hoverBorderWidth","hoverRadius","hitRadius","pointStyle","rotation"],update:function(n){var i=this,t=i.getMeta().data;B.each(t,function(t,e){i.updateElement(t,e,n)})},updateElement:function(t,e,n){var i=this,r=i.getMeta(),a=t.custom||{},o=i.getScaleForId(r.xAxisID),s=i.getScaleForId(r.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:a.skip||isNaN(h)||isNaN(c),x:h,y:c},t.pivot()},setHoverStyle:function(t){var e=t._model,n=t._options,i=B.getHoverColor;t.$previousStyle={backgroundColor:e.backgroundColor,borderColor:e.borderColor,borderWidth:e.borderWidth,radius:e.radius},e.backgroundColor=Ot(n.hoverBackgroundColor,i(n.backgroundColor)),e.borderColor=Ot(n.hoverBorderColor,i(n.borderColor)),e.borderWidth=Ot(n.hoverBorderWidth,n.borderWidth),e.radius=n.radius+n.hoverRadius},_resolveDataElementOptions:function(t,e){var n=this,i=n.chart,r=n.getDataset(),a=t.custom||{},o=r.data[e]||{},s=it.prototype._resolveDataElementOptions.apply(n,arguments),l={chart:i,dataIndex:e,dataset:r,datasetIndex:n.index};return n._cachedDataOpts===s&&(s=B.extend({},s)),s.radius=At([a.radius,o.r,n._config.radius,i.options.elements.point.radius],l,e),s}}),It=B.valueOrDefault,Lt=Math.PI,Rt=2*Lt,Nt=Lt/2;Y._set("doughnut",{animation:{animateRotate:!0,animateScale:!1},hover:{mode:"single"},legendCallback:function(t){var e,n,i,r=document.createElement("ul"),a=t.data,o=a.datasets,s=a.labels;if(r.setAttribute("class",t.id+"-legend"),o.length)for(n=o[e=0].data.length;e<n;++e)(i=r.appendChild(document.createElement("li"))).appendChild(document.createElement("span")).style.backgroundColor=o[0].backgroundColor[e],s[e]&&i.appendChild(document.createTextNode(s[e]));return r.outerHTML},legend:{labels:{generateLabels:function(r){var a=r.data;return a.labels.length&&a.datasets.length?a.labels.map(function(t,e){var n=r.getDatasetMeta(0),i=n.controller.getStyle(e);return{text:t,fillStyle:i.backgroundColor,strokeStyle:i.borderColor,lineWidth:i.borderWidth,hidden:isNaN(a.datasets[0].data[e])||n.data[e].hidden,index:e}}):[]}},onClick:function(t,e){for(var n,i=e.index,r=this.chart,a=0,o=(r.data.datasets||[]).length;a<o;++a)(n=r.getDatasetMeta(a)).data[i]&&(n.data[i].hidden=!n.data[i].hidden);r.update()}},cutoutPercentage:50,rotation:-Nt,circumference:Rt,tooltips:{callbacks:{title:function(){return""},label:function(t,e){var n=e.labels[t.index],i=": "+e.datasets[t.datasetIndex].data[t.index];return B.isArray(n)?(n=n.slice())[0]+=i:n+=i,n}}}});var Wt=it.extend({dataElementType:wt.Arc,linkScales:B.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,r,a,o,s,l,u,d,h,c,f,g,m,p,v,y=this,b=y.chart,x=b.chartArea,_=b.options,w=1,k=1,M=0,S=0,D=y.getMeta(),C=D.data,P=_.cutoutPercentage/100||0,T=_.circumference,O=y._getRingWeight(y.index);for(T<Rt&&(a=_.rotation%Rt,o=(a+=Lt<=a?-Rt:a<-Lt?Rt:0)+T,s=Math.cos(a),l=Math.sin(a),u=Math.cos(o),d=Math.sin(o),h=a<=0&&0<=o||Rt<=o,c=a<=Nt&&Nt<=o||Rt+Nt<=o,f=a<=-Nt&&-Nt<=o||Lt+Nt<=o,g=a===-Lt||Lt<=o?-1:Math.min(s,s*P,u,u*P),m=f?-1:Math.min(l,l*P,d,d*P),w=((p=h?1:Math.max(s,s*P,u,u*P))-g)/2,k=((v=c?1:Math.max(l,l*P,d,d*P))-m)/2,M=-(p+g)/2,S=-(v+m)/2),i=0,r=C.length;i<r;++i)C[i]._options=y._resolveDataElementOptions(C[i],i);for(b.borderWidth=y.getMaxBorderWidth(),e=(x.right-x.left-b.borderWidth)/w,n=(x.bottom-x.top-b.borderWidth)/k,b.outerRadius=Math.max(Math.min(e,n)/2,0),b.innerRadius=Math.max(b.outerRadius*P,0),b.radiusLength=(b.outerRadius-b.innerRadius)/(y._getVisibleDatasetWeightTotal()||1),b.offsetX=M*b.outerRadius,b.offsetY=S*b.outerRadius,D.total=y.calculateTotal(),y.outerRadius=b.outerRadius-b.radiusLength*y._getRingWeightOffset(y.index),y.innerRadius=Math.max(y.outerRadius-b.radiusLength*O,0),i=0,r=C.length;i<r;++i)y.updateElement(C[i],i,t)},updateElement:function(t,e,n){var i=this,r=i.chart,a=r.chartArea,o=r.options,s=o.animation,l=(a.left+a.right)/2,u=(a.top+a.bottom)/2,d=o.rotation,h=o.rotation,c=i.getDataset(),f=n&&s.animateRotate||t.hidden?0:i.calculateCircumference(c.data[e])*(o.circumference/Rt),g=n&&s.animateScale?0:i.innerRadius,m=n&&s.animateScale?0:i.outerRadius,p=t._options||{};B.extend(t,{_datasetIndex:i.index,_index:e,_model:{backgroundColor:p.backgroundColor,borderColor:p.borderColor,borderWidth:p.borderWidth,borderAlign:p.borderAlign,x:l+r.offsetX,y:u+r.offsetY,startAngle:d,endAngle:h,circumference:f,outerRadius:m,innerRadius:g,label:B.valueAtIndexOrDefault(c.label,e,r.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 n,i=this.getDataset(),t=this.getMeta(),r=0;return B.each(t.data,function(t,e){n=i.data[e],isNaN(n)||t.hidden||(r+=Math.abs(n))}),r},calculateCircumference:function(t){var e=this.getMeta().total;return 0<e&&!isNaN(t)?Rt*(Math.abs(t)/e):0},getMaxBorderWidth:function(t){var e,n,i,r,a,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&&(a=i.controller);break}if(!t)return 0;for(e=0,n=t.length;e<n;++e)r=t[e],"inner"!==(o=a?(a._configure(),a._resolveDataElementOptions(r,e)):r._options).borderAlign&&(u=(u=u<(s=o.borderWidth)?s:u)<(l=o.hoverBorderWidth)?l:u);return u},setHoverStyle:function(t){var e=t._model,n=t._options,i=B.getHoverColor;t.$previousStyle={backgroundColor:e.backgroundColor,borderColor:e.borderColor,borderWidth:e.borderWidth},e.backgroundColor=It(n.hoverBackgroundColor,i(n.backgroundColor)),e.borderColor=It(n.hoverBorderColor,i(n.borderColor)),e.borderWidth=It(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(It(this.chart.data.datasets[t].weight,1),0)},_getVisibleDatasetWeightTotal:function(){return this._getRingWeightOffset(this.chart.data.datasets.length)}});Y._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"}}),Y._set("global",{datasets:{horizontalBar:{categoryPercentage:.8,barPercentage:.9}}});var Yt=Tt.extend({_getValueScaleId:function(){return this.getMeta().xAxisID},_getIndexScaleId:function(){return this.getMeta().yAxisID}}),zt=B.valueOrDefault,Vt=B.options.resolve,Et=B.canvas._isPointInArea;function Ht(t,e){var n=t&&t.options.ticks||{},i=n.reverse,r=void 0===n.min?e:0,a=void 0===n.max?e:0;return{start:i?a:r,end:i?r:a}}Y._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 Bt=it.extend({datasetElementType:wt.Line,dataElementType:wt.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,r=i.getMeta(),a=r.dataset,o=r.data||[],s=i.chart.options,l=i._config,u=i._showLine=zt(l.showLine,s.showLines);for(i._xScale=i.getScaleForId(r.xAxisID),i._yScale=i.getScaleForId(r.yAxisID),u&&(void 0!==l.tension&&void 0===l.lineTension&&(l.lineTension=l.tension),a._scale=i._yScale,a._datasetIndex=i.index,a._children=o,a._model=i._resolveDatasetElementOptions(a),a.pivot()),e=0,n=o.length;e<n;++e)i.updateElement(o[e],e,t);for(u&&0!==a._model.tension&&i.updateBezierControlPoints(),e=0,n=o.length;e<n;++e)o[e].pivot()},updateElement:function(t,e,n){var i=this,r=i.getMeta(),a=t.custom||{},o=i.getDataset(),s=i.index,l=o.data[e],u=i._xScale,d=i._yScale,h=r.dataset._model,c=i._resolveDataElementOptions(t,e),f=u.getPixelForValue("object"==typeof l?l:NaN,e,s),g=n?d.getBasePixel():i.calculatePointY(l,e,s);t._xScale=u,t._yScale=d,t._options=c,t._datasetIndex=s,t._index=e,t._model={x:f,y:g,skip:a.skip||isNaN(f)||isNaN(g),radius:c.radius,pointStyle:c.pointStyle,rotation:c.rotation,backgroundColor:c.backgroundColor,borderColor:c.borderColor,borderWidth:c.borderWidth,tension:zt(a.tension,h?h.tension:0),steppedLine:!!h&&h.steppedLine,hitRadius:c.hitRadius}},_resolveDatasetElementOptions:function(t){var e,n,i,r,a,o,s,l,u,d,h,c=this,f=c._config,g=t.custom||{},m=c.chart.options,p=m.elements.line,v=it.prototype._resolveDatasetElementOptions.apply(c,arguments);return v.spanGaps=zt(f.spanGaps,m.spanGaps),v.tension=zt(f.lineTension,p.tension),v.steppedLine=Vt([g.steppedLine,f.steppedLine,p.stepped]),v.clip=(e=zt(f.clip,(o=c._xScale,s=c._yScale,l=v.borderWidth,d=Ht(o,u=l/2),{top:(h=Ht(s,u)).end,right:d.end,bottom:h.start,left:d.start})),B.isObject(e)?(n=e.top,i=e.right,r=e.bottom,a=e.left):n=i=r=a=e,{top:n,right:i,bottom:r,left:a}),v},calculatePointY:function(t,e,n){var i,r,a,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&&(a=l[i]).index!==n;++i)r=d.data.datasets[a.index],"line"===a.type&&a.yAxisID===h.id&&((o=+h.getRightValue(r.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,r=this.chart,a=this.getMeta(),o=a.dataset._model,s=r.chartArea,l=a.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)B.splineCurveMonotone(l);else for(t=0,e=l.length;t<e;++t)n=l[t]._model,i=B.splineCurve(B.previousItem(l,t)._model,n,B.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(r.options.elements.line.capBezierPoints)for(t=0,e=l.length;t<e;++t)n=l[t]._model,Et(n,s)&&(0<t&&Et(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&&Et(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||[],r=e.chartArea,a=e.canvas,o=0,s=i.length;for(this._showLine&&(t=n.dataset._model.clip,B.canvas.clipArea(e.ctx,{left:!1===t.left?0:r.left-t.left,right:!1===t.right?a.width:r.right+t.right,top:!1===t.top?0:r.top-t.top,bottom:!1===t.bottom?a.height:r.bottom+t.bottom}),n.dataset.draw(),B.canvas.unclipArea(e.ctx));o<s;++o)i[o].draw(r)},setHoverStyle:function(t){var e=t._model,n=t._options,i=B.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)}}),jt=B.options.resolve;Y._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,r=document.createElement("ul"),a=t.data,o=a.datasets,s=a.labels;if(r.setAttribute("class",t.id+"-legend"),o.length)for(n=o[e=0].data.length;e<n;++e)(i=r.appendChild(document.createElement("li"))).appendChild(document.createElement("span")).style.backgroundColor=o[0].backgroundColor[e],s[e]&&i.appendChild(document.createTextNode(s[e]));return r.outerHTML},legend:{labels:{generateLabels:function(r){var a=r.data;return a.labels.length&&a.datasets.length?a.labels.map(function(t,e){var n=r.getDatasetMeta(0),i=n.controller.getStyle(e);return{text:t,fillStyle:i.backgroundColor,strokeStyle:i.borderColor,lineWidth:i.borderWidth,hidden:isNaN(a.datasets[0].data[e])||n.data[e].hidden,index:e}}):[]}},onClick:function(t,e){for(var n,i=e.index,r=this.chart,a=0,o=(r.data.datasets||[]).length;a<o;++a)(n=r.getDatasetMeta(a)).data[i].hidden=!n.data[i].hidden;r.update()}},tooltips:{callbacks:{title:function(){return""},label:function(t,e){return e.labels[t.index]+": "+t.yLabel}}}});var Ut=it.extend({dataElementType:wt.Arc,linkScales:B.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,r=this,a=r.getDataset(),o=r.getMeta(),s=r.chart.options.startAngle||0,l=r._starts=[],u=r._angles=[],d=o.data;for(r._updateRadius(),o.count=r.countVisibleElements(),e=0,n=a.data.length;e<n;e++)l[e]=s,i=r._computeAngle(e),s+=u[e]=i;for(e=0,n=d.length;e<n;++e)d[e]._options=r._resolveDataElementOptions(d[e],e),r.updateElement(d[e],e,t)},_updateRadius:function(){var t=this,e=t.chart,n=e.chartArea,i=e.options,r=Math.min(n.right-n.left,n.bottom-n.top);e.outerRadius=Math.max(r/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,r=i.chart,a=i.getDataset(),o=r.options,s=o.animation,l=r.scale,u=r.data.labels,d=l.xCenter,h=l.yCenter,c=o.startAngle,f=t.hidden?0:l.getDistanceFromCenterForValue(a.data[e]),g=i._starts[e],m=g+(t.hidden?0:i._angles[e]),p=s.animateScale?0:l.getDistanceFromCenterForValue(a.data[e]),v=t._options||{};B.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?p:f,startAngle:n&&s.animateRotate?c:g,endAngle:n&&s.animateRotate?c:m,label:B.valueAtIndexOrDefault(u,e,u[e])}}),t.pivot()},countVisibleElements:function(){var n=this.getDataset(),t=this.getMeta(),i=0;return B.each(t.data,function(t,e){isNaN(n.data[e])||t.hidden||i++}),i},setHoverStyle:function(t){var e=t._model,n=t._options,i=B.getHoverColor,r=B.valueOrDefault;t.$previousStyle={backgroundColor:e.backgroundColor,borderColor:e.borderColor,borderWidth:e.borderWidth},e.backgroundColor=r(n.hoverBackgroundColor,i(n.backgroundColor)),e.borderColor=r(n.hoverBorderColor,i(n.borderColor)),e.borderWidth=r(n.hoverBorderWidth,n.borderWidth)},_computeAngle:function(t){var e=this,n=this.getMeta().count,i=e.getDataset(),r=e.getMeta();if(isNaN(i.data[t])||r.data[t].hidden)return 0;var a={chart:e.chart,dataIndex:t,dataset:i,datasetIndex:e.index};return jt([e.chart.options.elements.arc.angle,2*Math.PI/n],a,t)}});Y._set("pie",B.clone(Y.doughnut)),Y._set("pie",{cutoutPercentage:0});var Gt=Wt,qt=B.valueOrDefault;Y._set("radar",{spanGaps:!1,scale:{type:"radialLinear"},elements:{line:{fill:"start",tension:0}}});var Zt=it.extend({datasetElementType:wt.Line,dataElementType:wt.Point,linkScales:B.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,r=i.getMeta(),a=r.dataset,o=r.data||[],s=i.chart.scale,l=i._config;for(void 0!==l.tension&&void 0===l.lineTension&&(l.lineTension=l.tension),a._scale=s,a._datasetIndex=i.index,a._children=o,a._loop=!0,a._model=i._resolveDatasetElementOptions(a),a.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,r=t.custom||{},a=i.getDataset(),o=i.chart.scale,s=o.getPointPositionForValue(e,a.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:r.skip||isNaN(d)||isNaN(h),radius:l.radius,pointStyle:l.pointStyle,rotation:l.rotation,backgroundColor:l.backgroundColor,borderColor:l.borderColor,borderWidth:l.borderWidth,tension:qt(r.tension,u?u.tension:0),hitRadius:l.hitRadius}},_resolveDatasetElementOptions:function(){var t=this._config,e=this.chart.options,n=it.prototype._resolveDatasetElementOptions.apply(this,arguments);return n.spanGaps=qt(t.spanGaps,e.spanGaps),n.tension=qt(t.lineTension,e.elements.line.tension),n},updateBezierControlPoints:function(){var t,e,n,i,r=this.getMeta(),a=this.chart.chartArea,o=r.data||[];function s(t,e,n){return Math.max(Math.min(t,n),e)}for(r.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=B.splineCurve(B.previousItem(o,t,!0)._model,n,B.nextItem(o,t,!0)._model,n.tension),n.controlPointPreviousX=s(i.previous.x,a.left,a.right),n.controlPointPreviousY=s(i.previous.y,a.top,a.bottom),n.controlPointNextX=s(i.next.x,a.left,a.right),n.controlPointNextY=s(i.next.y,a.top,a.bottom)},setHoverStyle:function(t){var e=t._model,n=t._options,i=B.getHoverColor;t.$previousStyle={backgroundColor:e.backgroundColor,borderColor:e.borderColor,borderWidth:e.borderWidth,radius:e.radius},e.backgroundColor=qt(n.hoverBackgroundColor,i(n.backgroundColor)),e.borderColor=qt(n.hoverBorderColor,i(n.borderColor)),e.borderWidth=qt(n.hoverBorderWidth,n.borderWidth),e.radius=qt(n.hoverRadius,n.radius)}});Y._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+")"}}}}),Y._set("global",{datasets:{scatter:{showLine:!1}}});var $t={bar:Tt,bubble:Ft,doughnut:Wt,horizontalBar:Yt,line:Bt,polarArea:Ut,pie:Gt,radar:Zt,scatter:Bt};function Xt(t,e){return t.native?{x:t.x,y:t.y}:B.getRelativePosition(t,e)}function Kt(t,e){for(var n,i,r,a,o=t._getSortedVisibleDatasetMetas(),s=0,l=o.length;s<l;++s)for(i=0,r=(n=o[s].data).length;i<r;++i)(a=n[i])._view.skip||e(a)}function Jt(t,e){var n=[];return Kt(t,function(t){t.inRange(e.x,e.y)&&n.push(t)}),n}function Qt(t,i,r,a){var o=Number.POSITIVE_INFINITY,s=[];return Kt(t,function(t){var e,n;r&&!t.inRange(i.x,i.y)||(e=t.getCenterPoint(),(n=a(i,e))<o?(s=[t],o=n):n===o&&s.push(t))}),s}function te(t){var r=-1!==t.indexOf("x"),a=-1!==t.indexOf("y");return function(t,e){var n=r?Math.abs(t.x-e.x):0,i=a?Math.abs(t.y-e.y):0;return Math.sqrt(Math.pow(n,2)+Math.pow(i,2))}}function ee(t,e,n){var i=Xt(e,t);n.axis=n.axis||"x";var r=te(n.axis),a=n.intersect?Jt(t,i):Qt(t,i,!1,r),o=[];return a.length?(t._getSortedVisibleDatasetMetas().forEach(function(t){var e=t.data[a[0]._index];e&&!e._view.skip&&o.push(e)}),o):[]}var ne={modes:{single:function(t,e){var n=Xt(e,t),i=[];return Kt(t,function(t){return t.inRange(n.x,n.y)&&(i.push(t),i)}),i.slice(0,1)},label:ee,index:ee,dataset:function(t,e,n){var i=Xt(e,t);n.axis=n.axis||"xy";var r=te(n.axis),a=n.intersect?Jt(t,i):Qt(t,i,!1,r);return 0<a.length&&(a=t.getDatasetMeta(a[0]._datasetIndex).data),a},"x-axis":function(t,e){return ee(t,e,{intersect:!1})},point:function(t,e){return Jt(t,Xt(e,t))},nearest:function(t,e,n){var i=Xt(e,t);n.axis=n.axis||"xy";var r=te(n.axis);return Qt(t,i,n.intersect,r)},x:function(t,e,n){var i=Xt(e,t),r=[],a=!1;return Kt(t,function(t){t.inXRange(i.x)&&r.push(t),t.inRange(i.x,i.y)&&(a=!0)}),n.intersect&&!a&&(r=[]),r},y:function(t,e,n){var i=Xt(e,t),r=[],a=!1;return Kt(t,function(t){t.inYRange(i.y)&&r.push(t),t.inRange(i.x,i.y)&&(a=!0)}),n.intersect&&!a&&(r=[]),r}}},ie=B.extend;function re(t,e){return B.where(t,function(t){return t.pos===e})}function ae(t,r){return t.sort(function(t,e){var n=r?e:t,i=r?t:e;return n.weight===i.weight?n.index-i.index:n.weight-i.weight})}function oe(t){var e=function(t){for(var e,n=[],i=0,r=(t||[]).length;i<r;++i)e=t[i],n.push({index:i,box:e,pos:e.position,horizontal:e.isHorizontal(),weight:e.weight});return n}(t),n=ae(re(e,"left"),!0),i=ae(re(e,"right")),r=ae(re(e,"top"),!0),a=ae(re(e,"bottom"));return{leftAndTop:n.concat(r),rightAndBottom:i.concat(a),chartArea:re(e,"chartArea"),vertical:n.concat(i),horizontal:r.concat(a)}}function se(t,e,n,i){return Math.max(t[n],e[n])+Math.max(t[i],e[i])}function le(t,e,n){for(var i,r,a,o,s=[],l=0,u=t.length;l<u;++l)(r=(i=t[l]).box).update(i.width||e.w,i.height||e.h,function(t,n){var i=n.maxPadding;function e(t){var e={left:0,top:0,right:0,bottom:0};return t.forEach(function(t){e[t]=Math.max(n[t],i[t])}),e}return e(t?["left","right"]:["top","bottom"])}(i.horizontal,e)),function(t,e,n){var i,r,a,o=n.box,s=t.maxPadding;if(n.size&&(t[n.pos]-=n.size),n.size=n.horizontal?o.height:o.width,t[n.pos]+=n.size,o.getPadding&&(a=o.getPadding(),s.top=Math.max(s.top,a.top),s.left=Math.max(s.left,a.left),s.bottom=Math.max(s.bottom,a.bottom),s.right=Math.max(s.right,a.right)),i=e.outerWidth-se(s,t,"left","right"),r=e.outerHeight-se(s,t,"top","bottom"),i!==t.w||r!==t.h){t.w=i,t.h=r;var l=n.horizontal?[i,t.w]:[r,t.h];return!(l[0]===l[1]||isNaN(l[0])&&isNaN(l[1]))}}(e,n,i)&&(o=!0,s.length&&(a=!0)),r.fullWidth||s.push(i);return a&&le(s,e,n)||o}function ue(t,e,n){for(var i,r,a=n.padding,o=e.x,s=e.y,l=0,u=t.length;l<u;++l)r=(i=t[l]).box,i.horizontal?(r.left=r.fullWidth?a.left:e.left,r.right=r.fullWidth?n.outerWidth-a.right:e.left+e.w,r.top=s,r.bottom=s+r.height,r.width=r.right-r.left,s=r.bottom):(r.left=o,r.right=o+r.width,r.top=e.top,r.bottom=e.top+e.h,r.height=r.bottom-r.top,o=r.right);e.x=o,e.y=s}Y._set("global",{layout:{padding:{top:0,right:0,bottom:0,left:0}}});var de,he={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,r=["fullWidth","position","weight"],a=r.length,o=0;o<a;++o)i=r[o],n.hasOwnProperty(i)&&(e[i]=n[i])},update:function(n,t,e){var i,r,a,o,s,l,u,d,h,c,f;function g(t){var e=Math.max(f[t]-c[t],0);return c[t]+=e,e}n&&(i=n.options.layout||{},a=t-(r=B.options.toPadding(i.padding)).width,o=e-r.height,l=(s=oe(n.boxes)).vertical,u=s.horizontal,d=Object.freeze({outerWidth:t,outerHeight:e,padding:r,availableWidth:a,vBoxMaxWidth:a/2/l.length,hBoxMaxHeight:o/2}),h=ie({maxPadding:ie({},r),w:a,h:o,x:r.left,y:r.top},r),function(t,e){for(var n,i=0,r=t.length;i<r;++i)(n=t[i]).width=n.horizontal?n.box.fullWidth&&e.availableWidth:e.vBoxMaxWidth,n.height=n.horizontal&&e.hBoxMaxHeight}(l.concat(u),d),le(l,h,d),le(u,h,d)&&le(l,h,d),f=(c=h).maxPadding,c.y+=g("top"),c.x+=g("left"),g("right"),g("bottom"),ue(s.leftAndTop,h,d),h.x+=h.w,h.y+=h.h,ue(s.rightAndBottom,h,d),n.chartArea={left:h.left,top:h.top,right:h.left+h.w,bottom:h.top+h.h},B.each(s.chartArea,function(t){var e=t.box;ie(e,n.chartArea),e.update(h.w,h.h)}))}},ce=(de=Object.freeze({__proto__:null,default:"/*\r\n * DOM element rendering detection\r\n * https://davidwalsh.name/detect-node-insertion\r\n */\r\n@keyframes chartjs-render-animation {\r\n\tfrom { opacity: 0.99; }\r\n\tto { opacity: 1; }\r\n}\r\n\r\n.chartjs-render-monitor {\r\n\tanimation: chartjs-render-animation 0.001s;\r\n}\r\n\r\n/*\r\n * DOM element resizing detection\r\n * https://github.com/marcj/css-element-queries\r\n */\r\n.chartjs-size-monitor,\r\n.chartjs-size-monitor-expand,\r\n.chartjs-size-monitor-shrink {\r\n\tposition: absolute;\r\n\tdirection: ltr;\r\n\tleft: 0;\r\n\ttop: 0;\r\n\tright: 0;\r\n\tbottom: 0;\r\n\toverflow: hidden;\r\n\tpointer-events: none;\r\n\tvisibility: hidden;\r\n\tz-index: -1;\r\n}\r\n\r\n.chartjs-size-monitor-expand > div {\r\n\tposition: absolute;\r\n\twidth: 1000000px;\r\n\theight: 1000000px;\r\n\tleft: 0;\r\n\ttop: 0;\r\n}\r\n\r\n.chartjs-size-monitor-shrink > div {\r\n\tposition: absolute;\r\n\twidth: 200%;\r\n\theight: 200%;\r\n\tleft: 0;\r\n\ttop: 0;\r\n}\r\n"}))&&de.default||de,fe="$chartjs",ge="chartjs-",me=ge+"size-monitor",pe=ge+"render-monitor",ve=ge+"render-animation",ye=["animationstart","webkitAnimationStart"],be={touchstart:"mousedown",touchmove:"mousemove",touchend:"mouseup",pointerenter:"mouseenter",pointerdown:"mousedown",pointermove:"mousemove",pointerup:"mouseup",pointerleave:"mouseout",pointerout:"mouseout"};function xe(t,e){var n=B.getStyle(t,e),i=n&&n.match(/^(\d+)(\.\d+)?px$/);return i?Number(i[1]):void 0}var _e=!!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 we(t,e,n){t.addEventListener(e,n,_e)}function ke(t,e,n){t.removeEventListener(e,n,_e)}function Me(t,e,n,i,r){return{type:t,chart:e,native:r||null,x:void 0!==n?n:null,y:void 0!==i?i:null}}function Se(t){var e=document.createElement("div");return e.className=t||"",e}function De(n,i,r){var t,e,a,o,s,l,u,d,h,c,f,g,m=n[fe]||(n[fe]={}),p=m.resizer=(u=!(s=function(){var t,e;m.resizer&&(e=(t=r.options.maintainAspectRatio&&n.parentNode)?t.clientWidth:0,i(Me("resize",r)),t&&t.clientWidth<e&&r.canvas&&i(Me("resize",r)))}),d=[],t=function(){d=Array.prototype.slice.call(arguments),l=l||this,u||(u=!0,B.requestAnimFrame.call(window,function(){u=!1,s.apply(l,d)}))},e=Se(me),a=Se(me+"-expand"),o=Se(me+"-shrink"),a.appendChild(Se()),o.appendChild(Se()),e.appendChild(a),e.appendChild(o),e._reset=function(){a.scrollLeft=1e6,a.scrollTop=1e6,o.scrollLeft=1e6,o.scrollTop=1e6},we(a,"scroll",v.bind(a,"expand")),we(o,"scroll",v.bind(o,"shrink")),e);function v(){e._reset(),t()}c=function(){var t;m.resizer&&((t=n.parentNode)&&t!==p.parentNode&&t.insertBefore(p,t.firstChild),p._reset())},f=(h=n)[fe]||(h[fe]={}),g=f.renderProxy=function(t){t.animationName===ve&&c()},B.each(ye,function(t){we(h,t,g)}),f.reflow=!!h.offsetParent,h.classList.add(pe)}function Ce(t){var e,n,i,r=t[fe]||{},a=r.resizer;delete r.resizer,n=(e=t)[fe]||{},(i=n.renderProxy)&&(B.each(ye,function(t){ke(e,t,i)}),delete n.renderProxy),e.classList.remove(pe),a&&a.parentNode&&a.parentNode.removeChild(a)}var Pe={disableCSSInjection:!1,_enabled:"undefined"!=typeof window&&"undefined"!=typeof document,_ensureLoaded:function(t){var e,n,i,r,a,o;this.disableCSSInjection||(n=(e=t.getRootNode?t.getRootNode():document).host?e:document.head,r=ce,(o=(i=n)[fe]||(i[fe]={})).containsStyles||(o.containsStyles=!0,r="/* Chart.js */\n"+r,(a=document.createElement("style")).setAttribute("type","text/css"),a.appendChild(document.createTextNode(r)),i.appendChild(a)))},acquireContext:function(t,e){"string"==typeof t?t=document.getElementById(t):t.length&&(t=t[0]),t&&t.canvas&&(t=t.canvas);var n,i,r,a,o,s,l,u=t&&t.getContext&&t.getContext("2d");return u&&u.canvas===t?(this._ensureLoaded(t),i=e,o=(n=t).style,s=n.getAttribute("height"),l=n.getAttribute("width"),n[fe]={initial:{height:s,width:l,style:{display:o.display,height:o.height,width:o.width}}},o.display=o.display||"block",null!==l&&""!==l||void 0!==(r=xe(n,"width"))&&(n.width=r),null!==s&&""!==s||(""===n.style.height?n.height=n.width/(i.options.aspectRatio||2):(a=xe(n,"height"),void 0!==r&&(n.height=a))),u):null},releaseContext:function(t){var n,i=t.canvas;i[fe]&&(n=i[fe].initial,["height","width"].forEach(function(t){var e=n[t];B.isNullOrUndef(e)?i.removeAttribute(t):i.setAttribute(t,e)}),B.each(n.style||{},function(t,e){i.style[e]=t}),i.width,delete i[fe])},addEventListener:function(a,t,o){var e,n=a.canvas;"resize"!==t?we(n,t,((e=o[fe]||(o[fe]={})).proxies||(e.proxies={}))[a.id+"_"+t]=function(t){var e,n,i,r;o((n=a,i=be[(e=t).type]||e.type,r=B.getRelativePosition(e,n),Me(i,n,r.x,r.y,e)))}):De(n,o,a)},removeEventListener:function(t,e,n){var i,r=t.canvas;"resize"!==e?(i=((n[fe]||{}).proxies||{})[t.id+"_"+e])&&ke(r,e,i):Ce(r)}};B.addEvent=we,B.removeEvent=ke;var Te=Pe._enabled?Pe:{acquireContext:function(t){return t&&t.canvas&&(t=t.canvas),t&&t.getContext("2d")||null}},Oe=B.extend({initialize:function(){},acquireContext:function(){},releaseContext:function(){},addEventListener:function(){},removeEventListener:function(){}},Te);Y._set("global",{plugins:{}});var Ae={_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 n=this._plugins;[].concat(t).forEach(function(t){var e=n.indexOf(t);-1!==e&&n.splice(e,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){for(var i,r,a,o,s=this.descriptors(t),l=s.length,u=0;u<l;++u)if("function"==typeof(o=(r=(i=s[u]).plugin)[e])&&((a=[t].concat(n||[])).push(i.options),!1===o.apply(r,a)))return!1;return!0},descriptors:function(t){var e=t.$plugins||(t.$plugins={});if(e.id===this._cacheId)return e.descriptors;var i=[],r=[],n=t&&t.config||{},a=n.options&&n.options.plugins||{};return this._plugins.concat(n.plugins||[]).forEach(function(t){var e,n;-1===i.indexOf(t)&&(e=t.id,!1!==(n=a[e])&&(!0===n&&(n=B.clone(Y.global.plugins[e])),i.push(t),r.push({plugin:t,options:n||{}})))}),e.descriptors=r,e.id=this._cacheId,r},_invalidate:function(t){delete t.$plugins}},Fe={constructors:{},defaults:{},registerScaleType:function(t,e,n){this.constructors[t]=e,this.defaults[t]=B.clone(n)},getScaleConstructor:function(t){return this.constructors.hasOwnProperty(t)?this.constructors[t]:void 0},getScaleDefaults:function(t){return this.defaults.hasOwnProperty(t)?B.merge(Object.create(null),[Y.scale,this.defaults[t]]):{}},updateScaleDefaults:function(t,e){this.defaults.hasOwnProperty(t)&&(this.defaults[t]=B.extend(this.defaults[t],e))},addScalesToLayout:function(e){B.each(e.scales,function(t){t.fullWidth=t.options.fullWidth,t.position=t.options.position,t.weight=t.options.weight,he.addBox(e,t)})}},Ie=B.valueOrDefault,Le=B.rtl.getRtlAdapter;Y._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:B.noop,title:function(t,e){var n,i="",r=e.labels,a=r?r.length:0;return 0<t.length&&((n=t[0]).label?i=n.label:n.xLabel?i=n.xLabel:0<a&&n.index<a&&(i=r[n.index])),i},afterTitle:B.noop,beforeBody:B.noop,beforeLabel:B.noop,label:function(t,e){var n=e.datasets[t.datasetIndex].label||"";return n&&(n+=": "),B.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:B.noop,afterBody:B.noop,beforeFooter:B.noop,footer:B.noop,afterFooter:B.noop}}});var Re={average:function(t){if(!t.length)return!1;for(var e=0,n=0,i=0,r=0,a=t.length;r<a;++r){var o,s=t[r];s&&s.hasValue()&&(e+=(o=s.tooltipPosition()).x,n+=o.y,++i)}return{x:e/i,y:n/i}},nearest:function(t,e){for(var n,i,r=e.x,a=e.y,o=Number.POSITIVE_INFINITY,s=0,l=t.length;s<l;++s){var u,d,h=t[s];h&&h.hasValue()&&(u=h.getCenterPoint(),(d=B.distanceBetweenPoints(e,u))<o&&(o=d,n=h))}return n&&(r=(i=n.tooltipPosition()).x,a=i.y),{x:r,y:a}}};function Ne(t,e){return e&&(B.isArray(e)?Array.prototype.push.apply(t,e):t.push(e)),t}function We(t){return("string"==typeof t||t instanceof String)&&-1<t.indexOf("\n")?t.split("\n"):t}function Ye(t){var e=Y.global;return{xPadding:t.xPadding,yPadding:t.yPadding,xAlign:t.xAlign,yAlign:t.yAlign,rtl:t.rtl,textDirection:t.textDirection,bodyFontColor:t.bodyFontColor,_bodyFontFamily:Ie(t.bodyFontFamily,e.defaultFontFamily),_bodyFontStyle:Ie(t.bodyFontStyle,e.defaultFontStyle),_bodyAlign:t.bodyAlign,bodyFontSize:Ie(t.bodyFontSize,e.defaultFontSize),bodySpacing:t.bodySpacing,titleFontColor:t.titleFontColor,_titleFontFamily:Ie(t.titleFontFamily,e.defaultFontFamily),_titleFontStyle:Ie(t.titleFontStyle,e.defaultFontStyle),titleFontSize:Ie(t.titleFontSize,e.defaultFontSize),_titleAlign:t.titleAlign,titleSpacing:t.titleSpacing,titleMarginBottom:t.titleMarginBottom,footerFontColor:t.footerFontColor,_footerFontFamily:Ie(t.footerFontFamily,e.defaultFontFamily),_footerFontStyle:Ie(t.footerFontStyle,e.defaultFontStyle),footerFontSize:Ie(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 ze(t,e){var n=t._chart.ctx,i=2*e.yPadding,r=0,a=e.body,o=a.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;function c(t){r=Math.max(r,n.measureText(t).width+f)}var f=0;return n.font=B.fontString(u,e._titleFontStyle,e._titleFontFamily),B.each(e.title,c),n.font=B.fontString(d,e._bodyFontStyle,e._bodyFontFamily),B.each(e.beforeBody.concat(e.afterBody),c),f=e.displayColors?d+2:0,B.each(a,function(t){B.each(t.before,c),B.each(t.lines,c),B.each(t.after,c)}),f=0,n.font=B.fontString(h,e._footerFontStyle,e._footerFontFamily),B.each(e.footer,c),{width:r+=2*e.xPadding,height:i}}function Ve(t,e){return"center"===e?t.x+t.width/2:"right"===e?t.x+t.width-t.xPadding:t.x+t.xPadding}function Ee(t){return Ne([],We(t))}var He=$.extend({initialize:function(){this._model=Ye(this._options),this._lastActive=[]},getTitle:function(){var t=this._options.callbacks,e=t.beforeTitle.apply(this,arguments),n=t.title.apply(this,arguments),i=t.afterTitle.apply(this,arguments),r=Ne(r=[],We(e));return r=Ne(r,We(n)),r=Ne(r,We(i))},getBeforeBody:function(){return Ee(this._options.callbacks.beforeBody.apply(this,arguments))},getBody:function(t,n){var i=this,r=i._options.callbacks,a=[];return B.each(t,function(t){var e={before:[],lines:[],after:[]};Ne(e.before,We(r.beforeLabel.call(i,t,n))),Ne(e.lines,r.label.call(i,t,n)),Ne(e.after,We(r.afterLabel.call(i,t,n))),a.push(e)}),a},getAfterBody:function(){return Ee(this._options.callbacks.afterBody.apply(this,arguments))},getFooter:function(){var t=this._options.callbacks,e=t.beforeFooter.apply(this,arguments),n=t.footer.apply(this,arguments),i=t.afterFooter.apply(this,arguments),r=Ne(r=[],We(e));return r=Ne(r,We(n)),r=Ne(r,We(i))},update:function(t){var e,n,i,r,a,o,s,l,u,d,h,c,f,g,m,p,v,y,b,x,_,w=this,k=w._options,M=w._model,S=w._model=Ye(k),D=w._active,C=w._data,P={xAlign:M.xAlign,yAlign:M.yAlign},T={x:M.x,y:M.y},O={width:M.width,height:M.height},A={x:M.caretX,y:M.caretY};if(D.length){S.opacity=1;for(var F=[],I=[],A=Re[k.position].call(w,D,w._eventPosition),L=[],R=0,N=D.length;R<N;++R)L.push((g=D[R],_=x=b=p=m=void 0,m=g._xScale,p=g._yScale||g._scale,v=g._index,y=g._datasetIndex,b=g._chart.getDatasetMeta(y).controller,x=b._getIndexScale(),_=b._getValueScale(),{xLabel:m?m.getLabelForIndex(v,y):"",yLabel:p?p.getLabelForIndex(v,y):"",label:x?""+x.getLabelForIndex(v,y):"",value:_?""+_.getLabelForIndex(v,y):"",index:v,datasetIndex:y,x:g._model.x,y:g._model.y}));k.filter&&(L=L.filter(function(t){return k.filter(t,C)})),k.itemSort&&(L=L.sort(function(t,e){return k.itemSort(t,e,C)})),B.each(L,function(t){F.push(k.callbacks.labelColor.call(w,t,w._chart)),I.push(k.callbacks.labelTextColor.call(w,t,w._chart))}),S.title=w.getTitle(L,C),S.beforeBody=w.getBeforeBody(L,C),S.body=w.getBody(L,C),S.afterBody=w.getAfterBody(L,C),S.footer=w.getFooter(L,C),S.x=A.x,S.y=A.y,S.caretPadding=k.caretPadding,S.labelColors=F,S.labelTextColors=I,S.dataPoints=L,P=function(t,e){var n,i=t._model,r=t._chart,a=t._chart.chartArea,o="center",s="center";i.y<e.height?s="top":i.y>r.height-e.height&&(s="bottom");var l=(a.left+a.right)/2,u=(a.top+a.bottom)/2,d="center"===s?(n=function(t){return t<=l},function(t){return l<t}):(n=function(t){return t<=e.width/2},function(t){return t>=r.width-e.width/2}),h=function(t){return t+e.width+i.caretSize+i.caretPadding>r.width},c=function(t){return t-e.width-i.caretSize-i.caretPadding<0},f=function(t){return t<=u?"top":"bottom"};n(i.x)?(o="left",h(i.x)&&(o="center",s=f(i.y))):d(i.x)&&(o="right",c(i.x)&&(o="center",s=f(i.y)));var g=t._options;return{xAlign:g.xAlign?g.xAlign:o,yAlign:g.yAlign?g.yAlign:s}}(this,O=ze(this,S)),e=S,n=O,i=P,r=w._chart,a=e.x,o=e.y,s=e.caretSize,l=e.caretPadding,u=e.cornerRadius,d=i.xAlign,h=i.yAlign,c=s+l,f=u+l,"right"===d?a-=n.width:"center"===d&&((a-=n.width/2)+n.width>r.width&&(a=r.width-n.width),a<0&&(a=0)),"top"===h?o+=c:o-="bottom"===h?n.height+c:n.height/2,"center"===h?"left"===d?a+=c:"right"===d&&(a-=c):"left"===d?a-=f:"right"===d&&(a+=f),T={x:a,y:o}}else S.opacity=0;return S.xAlign=P.xAlign,S.yAlign=P.yAlign,S.x=T.x,S.y=T.y,S.width=O.width,S.height=O.height,S.caretX=A.x,S.caretY=A.y,w._model=S,t&&k.custom&&k.custom.call(w,S),w},drawCaret:function(t,e){var n=this._chart.ctx,i=this._view,r=this.getCaretPosition(t,e,i);n.lineTo(r.x1,r.y1),n.lineTo(r.x2,r.y2),n.lineTo(r.x3,r.y3)},getCaretPosition:function(t,e,n){var i,r,a,o,s,l,u,d=n.caretSize,h=n.cornerRadius,c=n.xAlign,f=n.yAlign,g=t.x,m=t.y,p=e.width,v=e.height;return"center"===f?(a=m+v/2,o="left"===c?(i=(u=g)-d,l=u,r=a+d,a-d):(i=(u=g+p)+d,l=u,r=a-d,a+d)):(l=(u="left"===c?(i=g+h+d)-d:"right"===c?(i=g+p-h-d)-d:(i=n.caretX)-d,i+d),"top"===f?(a=(r=m)-d,o=r):(a=(r=m+v)+d,o=r,s=l,l=u,u=s)),{x1:u,x2:i,x3:l,y1:r,y2:a,y3:o}},drawTitle:function(t,e,n){var i,r,a,o=e.title,s=o.length;if(s){var l=Le(e.rtl,e.x,e.width);for(t.x=Ve(e,e._titleAlign),n.textAlign=l.textAlign(e._titleAlign),n.textBaseline="middle",i=e.titleFontSize,r=e.titleSpacing,n.fillStyle=e.titleFontColor,n.font=B.fontString(i,e._titleFontStyle,e._titleFontFamily),a=0;a<s;++a)n.fillText(o[a],l.x(t.x),t.y+i/2),t.y+=i+r,a+1===s&&(t.y+=e.titleMarginBottom-r)}},drawBody:function(e,t,n){function i(t){n.fillText(t,x.x(e.x+y),e.y+f/2),e.y+=f+g}var r,a,o,s,l,u,d,h,c,f=t.bodyFontSize,g=t.bodySpacing,m=t._bodyAlign,p=t.body,v=t.displayColors,y=0,b=v?Ve(t,"left"):0,x=Le(t.rtl,t.x,t.width),_=x.textAlign(m);for(n.textAlign=m,n.textBaseline="middle",n.font=B.fontString(f,t._bodyFontStyle,t._bodyFontFamily),e.x=Ve(t,_),n.fillStyle=t.bodyFontColor,B.each(t.beforeBody,i),y=v&&"right"!==_?"center"===m?f/2+1:f+2:0,l=0,d=p.length;l<d;++l){for(r=p[l],a=t.labelTextColors[l],o=t.labelColors[l],n.fillStyle=a,B.each(r.before,i),u=0,h=(s=r.lines).length;u<h;++u){v&&(c=x.x(b),n.fillStyle=t.legendColorBackground,n.fillRect(x.leftForLtr(c,f),e.y,f,f),n.lineWidth=1,n.strokeStyle=o.borderColor,n.strokeRect(x.leftForLtr(c,f),e.y,f,f),n.fillStyle=o.backgroundColor,n.fillRect(x.leftForLtr(x.xPlus(c,1),f-2),e.y+1,f-2,f-2),n.fillStyle=a),i(s[u])}B.each(r.after,i)}y=0,B.each(t.afterBody,i),e.y-=g},drawFooter:function(t,e,n){var i,r,a=e.footer,o=a.length;if(o){var s=Le(e.rtl,e.x,e.width);for(t.x=Ve(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=B.fontString(i,e._footerFontStyle,e._footerFontFamily),r=0;r<o;++r)n.fillText(a[r],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 r=e.xAlign,a=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"===a&&this.drawCaret(t,i),n.lineTo(o+l-d,s),n.quadraticCurveTo(o+l,s,o+l,s+d),"center"===a&&"right"===r&&this.drawCaret(t,i),n.lineTo(o+l,s+u-d),n.quadraticCurveTo(o+l,s+u,o+l-d,s+u),"bottom"===a&&this.drawCaret(t,i),n.lineTo(o+d,s+u),n.quadraticCurveTo(o,s+u,o,s+u-d),"center"===a&&"left"===r&&this.drawCaret(t,i),n.lineTo(o,s+d),n.quadraticCurveTo(o,s,o+d,s),n.closePath(),n.fill(),0<e.borderWidth&&n.stroke()},draw:function(){var t,e,n,i,r=this._chart.ctx,a=this._view;0!==a.opacity&&(t={width:a.width,height:a.height},e={x:a.x,y:a.y},n=Math.abs(a.opacity<.001)?0:a.opacity,i=a.title.length||a.beforeBody.length||a.body.length||a.afterBody.length||a.footer.length,this._options.enabled&&i&&(r.save(),r.globalAlpha=n,this.drawBackground(e,a,r,t),e.y+=a.yPadding,B.rtl.overrideTextDirection(r,a.textDirection),this.drawTitle(e,a,r),this.drawBody(e,a,r),this.drawFooter(e,a,r),B.rtl.restoreTextDirection(r,a.textDirection),r.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=!B.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}});He.positioners=Re;var Be=B.valueOrDefault;function je(){return B.merge(Object.create(null),[].slice.call(arguments),{merger:function(t,e,n,i){if("xAxes"===t||"yAxes"===t){var r,a,o,s=n[t].length;for(e[t]||(e[t]=[]),r=0;r<s;++r)o=n[t][r],a=Be(o.type,"xAxes"===t?"category":"linear"),r>=e[t].length&&e[t].push({}),!e[t][r].type||o.type&&o.type!==e[t][r].type?B.merge(e[t][r],[Fe.getScaleDefaults(a),o]):B.merge(e[t][r],o)}else B._merger(t,e,n,i)}})}function Ue(){return B.merge(Object.create(null),[].slice.call(arguments),{merger:function(t,e,n,i){var r=e[t]||Object.create(null),a=n[t];"scales"===t?e[t]=je(r,a):"scale"===t?e[t]=B.merge(r,[Fe.getScaleDefaults(a.type),a]):B._merger(t,e,n,i)}})}function Ge(t,e,n){for(var i,r=function(t){return t.id===i};i=e+n++,0<=B.findIndex(t,r););return i}function qe(t){return"top"===t||"bottom"===t}function Ze(n,i){return function(t,e){return t[n]===e[n]?t[i]-e[i]:t[n]-e[n]}}Y._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});function $e(t,e){return this.construct(t,e),this}B.extend($e.prototype,{construct:function(t,e){var n,i,r=this;(i=(n=(n=e)||Object.create(null)).data=n.data||{}).datasets=i.datasets||[],i.labels=i.labels||[],n.options=Ue(Y.global,Y[n.type],n.options||{}),e=n;var a=Oe.acquireContext(t,e),o=a&&a.canvas,s=o&&o.height,l=o&&o.width;r.id=B.uid(),r.ctx=a,r.canvas=o,r.config=e,r.width=l,r.height=s,r.aspectRatio=s?l/s:null,r.options=e.options,r._bufferedRender=!1,r._layers=[],(r.chart=r).controller=r,$e.instances[r.id]=r,Object.defineProperty(r,"data",{get:function(){return r.config.data},set:function(t){r.config.data=t}}),a&&o?(r.initialize(),r.update()):console.error("Failed to create chart: can't acquire context from the given item")},initialize:function(){var t=this;return Ae.notify(t,"beforeInit"),B.retinaScale(t,t.options.devicePixelRatio),t.bindEvents(),t.options.responsive&&t.resize(!0),t.initToolTip(),Ae.notify(t,"afterInit"),t},clear:function(){return B.canvas.clear(this),this},stop:function(){return J.cancelAnimation(this),this},resize:function(t){var e,n=this,i=n.options,r=n.canvas,a=i.maintainAspectRatio&&n.aspectRatio||null,o=Math.max(0,Math.floor(B.getMaximumWidth(r))),s=Math.max(0,Math.floor(a?o/a:B.getMaximumHeight(r)));n.width===o&&n.height===s||(r.width=n.width=o,r.height=n.height=s,r.style.width=o+"px",r.style.height=s+"px",B.retinaScale(n,i.devicePixelRatio),t||(e={width:o,height:s},Ae.notify(n,"resize",[e]),i.onResize&&i.onResize(n,e),n.stop(),n.update({duration:i.responsiveAnimationDuration})))},ensureScalesHaveIDs:function(){var t=this.options,n=t.scales||{},e=t.scale;B.each(n.xAxes,function(t,e){t.id||(t.id=Ge(n.xAxes,"x-axis-",e))}),B.each(n.yAxes,function(t,e){t.id||(t.id=Ge(n.yAxes,"y-axis-",e))}),e&&(e.id=e.id||"scale")},buildOrUpdateScales:function(){var o=this,t=o.options,s=o.scales||{},e=[],l=Object.keys(s).reduce(function(t,e){return t[e]=!1,t},{});t.scales&&(e=e.concat((t.scales.xAxes||[]).map(function(t){return{options:t,dtype:"category",dposition:"bottom"}}),(t.scales.yAxes||[]).map(function(t){return{options:t,dtype:"linear",dposition:"left"}}))),t.scale&&e.push({options:t.scale,dtype:"radialLinear",isDefault:!0,dposition:"chartArea"}),B.each(e,function(t){var e=t.options,n=e.id,i=Be(e.type,t.dtype);qe(e.position)!==qe(t.dposition)&&(e.position=t.dposition),l[n]=!0;var r=null;if(n in s&&s[n].type===i)(r=s[n]).options=e,r.ctx=o.ctx,r.chart=o;else{var a=Fe.getScaleConstructor(i);if(!a)return;r=new a({id:n,type:i,options:e,ctx:o.ctx,chart:o}),s[r.id]=r}r.mergeTicksOptions(),t.isDefault&&(o.scale=r)}),B.each(l,function(t,e){t||delete s[e]}),o.scales=s,Fe.addScalesToLayout(this)},buildOrUpdateControllers:function(){for(var t=this,e=[],n=t.data.datasets,i=0,r=n.length;i<r;i++){var a=n[i],o=t.getDatasetMeta(i),s=a.type||t.config.type;if(o.type&&o.type!==s&&(t.destroyDatasetMeta(i),o=t.getDatasetMeta(i)),o.type=s,o.order=a.order||0,o.index=i,o.controller)o.controller.updateIndex(i),o.controller.linkScales();else{var l=$t[o.type];if(void 0===l)throw new Error('"'+o.type+'" is not a chart type.');o.controller=new l(t,i),e.push(o.controller)}}return e},resetElements:function(){var n=this;B.each(n.data.datasets,function(t,e){n.getDatasetMeta(e).controller.reset()},n)},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]}),n=(e=i).options,B.each(e.scales,function(t){he.removeBox(e,t)}),n=Ue(Y.global,Y[e.config.type],n),e.options=e.config.options=n,e.ensureScalesHaveIDs(),e.buildOrUpdateScales(),e.tooltip._options=n.tooltips,e.tooltip.initialize(),Ae._invalidate(i),!1!==Ae.notify(i,"beforeUpdate")){i.tooltip._data=i.data;for(var r=i.buildOrUpdateControllers(),a=0,o=i.data.datasets.length;a<o;a++)i.getDatasetMeta(a).controller.buildOrUpdateElements();i.updateLayout(),i.options.animation&&i.options.animation.duration&&B.each(r,function(t){t.reset()}),i.updateDatasets(),i.tooltip.initialize(),i.lastActive=[],Ae.notify(i,"afterUpdate"),i._layers.sort(Ze("z","_idx")),i._bufferedRender?i._bufferedRequest={duration:t.duration,easing:t.easing,lazy:t.lazy}:i.render(t)}},updateLayout:function(){var e=this;!1!==Ae.notify(e,"beforeLayout")&&(he.update(this,this.width,this.height),e._layers=[],B.each(e.boxes,function(t){t._configure&&t._configure(),e._layers.push.apply(e._layers,t._layers())},e),e._layers.forEach(function(t,e){t._idx=e}),Ae.notify(e,"afterScaleUpdate"),Ae.notify(e,"afterLayout"))},updateDatasets:function(){if(!1!==Ae.notify(this,"beforeDatasetsUpdate")){for(var t=0,e=this.data.datasets.length;t<e;++t)this.updateDataset(t);Ae.notify(this,"afterDatasetsUpdate")}},updateDataset:function(t){var e=this.getDatasetMeta(t),n={meta:e,index:t};!1!==Ae.notify(this,"beforeDatasetUpdate",[n])&&(e.controller._update(),Ae.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=Be(t.duration,n&&n.duration),r=t.lazy;if(!1!==Ae.notify(e,"beforeRender")){var a,o=function(t){Ae.notify(e,"afterRender"),B.callback(n&&n.onComplete,[t],e)};return n&&i?(a=new K({numSteps:i/16.66,easing:t.easing||n.easing,render:function(t,e){var n=B.easing.effects[e.easing],i=e.currentStep,r=i/e.numSteps;t.draw(n(r),r,i)},onAnimationProgress:n.onProgress,onAnimationComplete:o}),J.addAnimation(e,a,i,r)):(e.draw(),o(new K({numSteps:0,chart:e}))),e}},draw:function(t){var e,n,i=this;if(i.clear(),B.isNullOrUndef(t)&&(t=1),i.transition(t),!(i.width<=0||i.height<=0)&&!1!==Ae.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),Ae.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){for(var e=[],n=0,i=(this.data.datasets||[]).length;n<i;++n)t&&!this.isDatasetVisible(n)||e.push(this.getDatasetMeta(n));return e.sort(Ze("order","index")),e},_getSortedVisibleDatasetMetas:function(){return this._getSortedDatasetMetas(!0)},drawDatasets:function(t){var e,n;if(!1!==Ae.notify(this,"beforeDatasetsDraw",[t])){for(n=(e=this._getSortedVisibleDatasetMetas()).length-1;0<=n;--n)this.drawDataset(e[n],t);Ae.notify(this,"afterDatasetsDraw",[t])}},drawDataset:function(t,e){var n={meta:t,index:t.index,easingValue:e};!1!==Ae.notify(this,"beforeDatasetDraw",[n])&&(t.controller.draw(e),Ae.notify(this,"afterDatasetDraw",[n]))},_drawTooltip:function(t){var e=this.tooltip,n={tooltip:e,easingValue:t};!1!==Ae.notify(this,"beforeTooltipDraw",[n])&&(e.draw(),Ae.notify(this,"afterTooltipDraw",[n]))},getElementAtEvent:function(t){return ne.modes.single(this,t)},getElementsAtEvent:function(t){return ne.modes.label(this,t,{intersect:!0})},getElementsAtXAxis:function(t){return ne.modes["x-axis"](this,t,{intersect:!0})},getElementsAtEventForMode:function(t,e,n){var i=ne.modes[e];return"function"==typeof i?i(this,t,n):[]},getDatasetAtEvent:function(t){return ne.modes.dataset(this,t,{intersect:!0})},getDatasetMeta:function(t){var e=this.data.datasets[t];return e._meta||(e._meta={}),e._meta[this.id]||(e._meta[this.id]={type:null,data:[],dataset:null,controller:null,hidden:null,xAxisID:null,yAxisID:null,order:e.order||0,index:t})},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(),B.canvas.clear(n),Oe.releaseContext(n.ctx),n.canvas=null,n.ctx=null),Ae.notify(n,"destroy"),delete $e.instances[n.id]},toBase64Image:function(){return this.canvas.toDataURL.apply(this.canvas,arguments)},initToolTip:function(){var t=this;t.tooltip=new He({_chart:t,_chartInstance:t,_data:t.data,_options:t.options.tooltips},t)},bindEvents:function(){var e=this,n=e._listeners={},i=function(){e.eventHandler.apply(e,arguments)};B.each(e.options.events,function(t){Oe.addEventListener(e,t,i),n[t]=i}),e.options.responsive&&(i=function(){e.resize()},Oe.addEventListener(e,"resize",i),n.resize=i)},unbindEvents:function(){var n=this,t=n._listeners;t&&(delete n._listeners,B.each(t,function(t,e){Oe.removeEventListener(n,e,t)}))},updateHoverStyle:function(t,e,n){for(var i,r=n?"set":"remove",a=0,o=t.length;a<o;++a)(i=t[a])&&this.getDatasetMeta(i._datasetIndex).controller[r+"HoverStyle"](i);"dataset"===e&&this.getDatasetMeta(t[0]._datasetIndex).controller["_"+r+"DatasetHoverStyle"]()},eventHandler:function(t){var e=this,n=e.tooltip;if(!1!==Ae.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)),Ae.notify(e,"afterEvent",[t]);var r=e._bufferedRequest;return r?e.render(r):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||{},r=i.hover;return n.lastActive=n.lastActive||[],"mouseout"===t.type?n.active=[]:n.active=n.getElementsAtEventForMode(t,r.mode,r),B.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,r.mode,!1),n.active.length&&r.mode&&n.updateHoverStyle(n.active,r.mode,!0),e=!B.arrayEquals(n.active,n.lastActive),n.lastActive=n.active,e}}),$e.instances={};var Xe=$e;($e.Controller=$e).types={},B.configMerge=Ue,B.scaleMerge=je;function Ke(){throw new Error("This method is not implemented: either no adapter can be found or an incomplete integration was provided.")}function Je(t){this.options=t||{}}B.extend(Je.prototype,{formats:Ke,parse:Ke,format:Ke,add:Ke,diff:Ke,startOf:Ke,endOf:Ke,_create:function(t){return t}}),Je.override=function(t){B.extend(Je.prototype,t)};var Qe={_date:Je},tn={formatters:{values:function(t){return B.isArray(t)?t:""+t},linear:function(t,e,n){var i=3<n.length?n[2]-n[1]:n[1]-n[0];1<Math.abs(i)&&t!==Math.floor(t)&&(i=t-Math.floor(t));var r,a,o,s=B.log10(Math.abs(i));return 0!==t?Math.max(Math.abs(n[0]),Math.abs(n[n.length-1]))<1e-4?(r=B.log10(Math.abs(t)),a=Math.floor(r)-Math.floor(s),a=Math.max(Math.min(a,20),0),t.toExponential(a)):(o=-1*Math.floor(s),o=Math.max(Math.min(o,20),0),t.toFixed(o)):"0"},logarithmic:function(t,e,n){var i=t/Math.pow(10,Math.floor(B.log10(t)));return 0===t?"0":1==i||2==i||5==i||0===e||e===n.length-1?t.toExponential():""}}},en=B.isArray,nn=B.isNullOrUndef,rn=B.valueOrDefault,an=B.valueAtIndexOrDefault;function on(t,e,n,i){for(var r,a,o,s,l,u,d,h,c,f,g,m,p,v,y=n.length,b=[],x=[],_=[],w=0,k=0,M=0;M<y;++M){if(o=n[M].label,s=n[M].major?e.major:e.minor,t.font=l=s.string,u=i[l]=i[l]||{data:{},gc:[]},d=s.lineHeight,h=c=0,nn(o)||en(o)){if(en(o))for(r=0,a=o.length;r<a;++r)f=o[r],nn(f)||en(f)||(h=B.measureText(t,u.data,u.gc,h,f),c+=d)}else h=B.measureText(t,u.data,u.gc,h,o),c=d;b.push(h),x.push(c),_.push(d/2),w=Math.max(h,w),k=Math.max(c,k)}function S(t){return{width:b[t]||0,height:x[t]||0,offset:_[t]||0}}return p=i,v=y,B.each(p,function(t){var e,n=t.gc,i=n.length/2;if(v<i){for(e=0;e<i;++e)delete t.data[n[e]];n.splice(0,i)}}),g=b.indexOf(w),m=x.indexOf(k),{first:S(0),last:S(y-1),widest:S(g),highest:S(m)}}function sn(t){return t.drawTicks?t.tickMarkLength:0}function ln(t){var e,n;return t.display?(e=B.options._parseFont(t),n=B.options.toPadding(t.padding),e.lineHeight+n.height):0}function un(t,e){return B.extend(B.options._parseFont({fontFamily:rn(e.fontFamily,t.fontFamily),fontSize:rn(e.fontSize,t.fontSize),fontStyle:rn(e.fontStyle,t.fontStyle),lineHeight:rn(e.lineHeight,t.lineHeight)}),{color:B.options.resolve([e.fontColor,t.fontColor,Y.global.defaultFontColor])})}function dn(t){var e=un(t,t.minor);return{minor:e,major:t.major.enabled?un(t,t.major):e}}function hn(t){for(var e,n=[],i=0,r=t.length;i<r;++i)void 0!==(e=t[i])._index&&n.push(e);return n}function cn(t,e,n,i){var r,a,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=(r=B.math._factorize(l)).length-1;o<s;o++)if(u<(a=r[o]))return a;return Math.max(u,1)}function fn(t,e,n,i){var r,a,o,s,l=rn(n,0),u=Math.min(rn(i,t.length),t.length),d=0;for(e=Math.ceil(e),i&&(e=(r=i-n)/Math.floor(r/e)),s=l;s<0;)d++,s=Math.round(l+d*e);for(a=Math.max(l,0);a<u;a++)o=t[a],a===s?(o._index=a,d++,s=Math.round(l+d*e)):delete o.label}Y._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:tn.formatters.values,minor:{},major:{}}});var gn=$.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(){B.callback(this.options.beforeUpdate,[this])},update:function(t,e,n){var i,r,a,o,s,l=this,u=l.options.ticks,d=u.sampleSize;if(l.beforeUpdate(),l.maxWidth=t,l.maxHeight=e,l.margins=B.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,r=l.ticks.length;i<r;++i)o.push({value:l.ticks[i],major:!1});return s=d<(l._ticks=o).length,a=l._convertTicksToLabels(s?function(t,e){for(var n=[],i=t.length/e,r=0,a=t.length;r<a;r+=i)n.push(t[Math.floor(r)]);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&&(a=l._convertTicksToLabels(l._ticksToDraw)),l.ticks=a,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(){B.callback(this.options.afterUpdate,[this])},beforeSetDimensions:function(){B.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(){B.callback(this.options.afterSetDimensions,[this])},beforeDataLimits:function(){B.callback(this.options.beforeDataLimits,[this])},determineDataLimits:B.noop,afterDataLimits:function(){B.callback(this.options.afterDataLimits,[this])},beforeBuildTicks:function(){B.callback(this.options.beforeBuildTicks,[this])},buildTicks:B.noop,afterBuildTicks:function(t){var e=this;return en(t)&&t.length?B.callback(e.options.afterBuildTicks,[e,t]):(e.ticks=B.callback(e.options.afterBuildTicks,[e,e.ticks])||e.ticks,t)},beforeTickToLabelConversion:function(){B.callback(this.options.beforeTickToLabelConversion,[this])},convertTicksToLabels:function(){var t=this.options.ticks;this.ticks=this.ticks.map(t.userCallback||t.callback,this)},afterTickToLabelConversion:function(){B.callback(this.options.afterTickToLabelConversion,[this])},beforeCalculateTickRotation:function(){B.callback(this.options.beforeCalculateTickRotation,[this])},calculateTickRotation:function(){var t,e,n,i,r,a,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||c<=h||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),(r=l.offset?s.maxWidth/d:i/(d-1))<e+6&&(r=i/(d-(l.offset?.5:1)),a=s.maxHeight-sn(l.gridLines)-u.padding-ln(l.scaleLabel),o=Math.sqrt(e*e+n*n),f=B.toDegrees(Math.min(Math.asin(Math.min((t.highest.height+6)/r,1)),Math.asin(Math.min(a/o,1))-Math.asin(n/o))),f=Math.max(h,Math.min(c,f))),s.labelRotation=f)},afterCalculateTickRotation:function(){B.callback(this.options.afterCalculateTickRotation,[this])},beforeFit:function(){B.callback(this.options.beforeFit,[this])},fit:function(){var t,e,n,i,r,a,o,s,l,u,d,h,c,f,g,m,p,v,y=this,b=y.minSize={width:0,height:0},x=y.chart,_=y.options,w=_.ticks,k=_.scaleLabel,M=_.gridLines,S=y._isVisible(),D="bottom"===_.position,C=y.isHorizontal();C?b.width=y.maxWidth:S&&(b.width=sn(M)+ln(k)),C?S&&(b.height=sn(M)+ln(k)):b.height=y.maxHeight,w.display&&S&&(t=dn(w),n=(e=y._getLabelSizes()).first,i=e.last,r=e.widest,a=e.highest,o=.4*t.minor.lineHeight,s=w.padding,C?(l=0!==y.labelRotation,u=B.toRadians(y.labelRotation),d=Math.cos(u),c=(h=Math.sin(u))*r.width+d*(a.height-(l?a.offset:0))+(l?0:o),b.height=Math.min(y.maxHeight,b.height+c+s),f=y.getPixelForTick(0)-y.left,g=y.right-y.getPixelForTick(y.getTicks().length-1),p=l?(m=D?d*n.width+h*n.offset:h*(n.height-n.offset),D?h*(i.height-i.offset):d*i.width+h*i.offset):(m=n.width/2,i.width/2),y.paddingLeft=Math.max((m-f)*y.width/(y.width-f),0)+3,y.paddingRight=Math.max((p-g)*y.width/(y.width-g),0)+3):(v=w.mirror?0:r.width+s+o,b.width=Math.min(y.maxWidth,b.width+v),y.paddingTop=n.height/2,y.paddingBottom=i.height/2)),y.handleMargins(),C?(y.width=y._length=x.width-y.margins.left-y.margins.right,y.height=b.height):(y.width=b.width,y.height=y._length=x.height-y.margins.top-y.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(){B.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(nn(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,r=this;for(r.ticks=t.map(function(t){return t.value}),r.beforeTickToLabelConversion(),e=r.convertTicksToLabels(t)||r.ticks,r.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=on(t.ctx,dn(t.options.ticks),t.getTicks(),t.longestTextCache),t.longestLabelWidth=e.widest.width),e},_parseValue:function(t){var e,n,i,r=en(t)?(e=+this.getRightValue(t[0]),n=+this.getRightValue(t[1]),i=Math.min(e,n),Math.max(e,n)):(e=void 0,i=n=t=+this.getRightValue(t));return{min:i,max:r,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:B.noop,getPixelForValue:B.noop,getValueForPixel:B.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||n-1<t?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:0<t&&0<e?t:0},_autoSkip:function(t){var e,n,i,r,a=this.options.ticks,o=this._length,s=a.maxTicksLimit||o/this._tickSize()+1,l=a.major.enabled?function(t){for(var e=[],n=0,i=t.length;n<i;n++)t[n].major&&e.push(n);return e}(t):[],u=l.length,d=l[0],h=l[u-1];if(s<u)return function(t,e,n){var i,r,a=0,o=e[0];for(n=Math.ceil(n),i=0;i<t.length;i++)r=t[i],i===o?(r._index=i,o=e[++a*n]):delete r.label}(t,l,u/s),hn(t);if(i=cn(l,t,0,s),0<u){for(e=0,n=u-1;e<n;e++)fn(t,i,l[e],l[e+1]);return r=1<u?(h-d)/(u-1):null,fn(t,i,B.isNullOrUndef(r)?0:d-r,d),fn(t,i,h,B.isNullOrUndef(r)?t.length:h+r),hn(t)}return fn(t,i),hn(t)},_tickSize:function(){var t=this.options.ticks,e=B.toRadians(this.labelRotation),n=Math.abs(Math.cos(e)),i=Math.abs(Math.sin(e)),r=this._getLabelSizes(),a=t.autoSkipPadding||0,o=r?r.widest.width+a:0,s=r?r.highest.height+a:0;return this.isHorizontal()?o*i<s*n?o/n:s/i:s*i<o*n?s/n:o/i},_isVisible:function(){var t,e,n,i=this.chart,r=this.options.display;if("auto"!==r)return!!r;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){function e(t){return F(x,t,O)}var n,i,r,a,o,s,l,u,d,h,c,f,g,m,p,v,y,b=this,x=b.chart,_=b.options,w=_.gridLines,k=_.position,M=w.offsetGridLines,S=b.isHorizontal(),D=b._ticksToDraw,C=D.length+(M?1:0),P=sn(w),T=[],O=w.drawBorder?an(w.lineWidth,0,0):0,A=O/2,F=B._alignPixel;for("top"===k?(n=e(b.bottom),l=b.bottom-P,d=n-A,c=e(t.top)+A,g=t.bottom):"bottom"===k?(n=e(b.top),c=t.top,g=e(t.bottom)-A,l=n+A,d=b.top+P):"left"===k?(n=e(b.right),s=b.right-P,u=n-A,h=e(t.left)+A,f=t.right):(n=e(b.left),h=t.left,f=e(t.right)-A,s=n+A,u=b.left+P),i=0;i<C;++i)r=D[i]||{},nn(r.label)&&i<D.length||(y=i===b.zeroLineIndex&&_.offset===M?(m=w.zeroLineWidth,p=w.zeroLineColor,v=w.zeroLineBorderDash||[],w.zeroLineBorderDashOffset||0):(m=an(w.lineWidth,i,1),p=an(w.color,i,"rgba(0,0,0,0.1)"),v=w.borderDash||[],w.borderDashOffset||0),void 0!==(a=function(t,e,n){var i,r=t.getTicks().length,a=Math.min(e,r-1),o=t.getPixelForTick(a),s=t._startPixel,l=t._endPixel;if(!(n&&(i=1===r?Math.max(o-s,l-o):0===e?(t.getPixelForTick(1)-o)/2:(o-t.getPixelForTick(a-1))/2,(o+=a<e?i:-i)<s-1e-6||l+1e-6<o)))return o}(b,r._index||i,M))&&(o=F(x,a,m),S?s=u=h=f=o:l=d=c=g=o,T.push({tx1:s,ty1:l,tx2:u,ty2:d,x1:h,y1:c,x2:f,y2:g,width:m,color:p,borderDash:v,borderDashOffset:y})));return T.ticksLength=C,T.borderValue=n,T},_computeLabelItems:function(){for(var t,e,n,i,r,a,o,s,l,u=this,d=u.options,h=d.ticks,c=d.position,f=h.mirror,g=u.isHorizontal(),m=u._ticksToDraw,p=dn(h),v=h.padding,y=sn(d.gridLines),b=-B.toRadians(u.labelRotation),x=[],_="top"===c?(i=u.bottom-y-v,b?"left":"center"):"bottom"===c?(i=u.top+y+v,b?"right":"center"):"left"===c?(n=u.right-(f?0:y)-v,f?"left":"right"):(n=u.left+(f?0:y)+v,f?"right":"left"),w=0,k=m.length;w<k;++w)e=(t=m[w]).label,nn(e)||(r=u.getPixelForTick(t._index||w)+h.labelOffset,o=(a=t.major?p.major:p.minor).lineHeight,s=en(e)?e.length:1,l=g?(n=r,"top"===c?((b?1:.5)-s)*o:(b?0:.5)*o):(i=r,(1-s)*o/2),x.push({x:n,y:i,rotation:b,label:e,font:a,textOffset:l,textAlign:_}));return x},_drawGrid:function(t){var e=this,n=e.options.gridLines;if(n.display){for(var i,r,a,o,s,l,u,d,h,c,f=e.ctx,g=e.chart,m=B._alignPixel,p=n.drawBorder?an(n.lineWidth,0,0):0,v=e._gridLineItems||(e._gridLineItems=e._computeGridLineItems(t)),y=0,b=v.length;y<b;++y)i=(a=v[y]).width,r=a.color,i&&r&&(f.save(),f.lineWidth=i,f.strokeStyle=r,f.setLineDash&&(f.setLineDash(a.borderDash),f.lineDashOffset=a.borderDashOffset),f.beginPath(),n.drawTicks&&(f.moveTo(a.tx1,a.ty1),f.lineTo(a.tx2,a.ty2)),n.drawOnChartArea&&(f.moveTo(a.x1,a.y1),f.lineTo(a.x2,a.y2)),f.stroke(),f.restore());p&&(o=p,s=an(n.lineWidth,v.ticksLength-1,1),l=v.borderValue,e.isHorizontal()?(u=m(g,e.left,o)-o/2,d=m(g,e.right,s)+s/2,h=c=l):(h=m(g,e.top,o)-o/2,c=m(g,e.bottom,s)+s/2,u=d=l),f.lineWidth=p,f.strokeStyle=an(n.color,0),f.beginPath(),f.moveTo(u,h),f.lineTo(d,c),f.stroke())}},_drawLabels:function(){var t=this;if(t.options.ticks.display)for(var e,n,i,r,a,o,s=t.ctx,l=t._labelItems||(t._labelItems=t._computeLabelItems()),u=0,d=l.length;u<d;++u){if(r=(i=l[u]).font,s.save(),s.translate(i.x,i.y),s.rotate(i.rotation),s.font=r.string,s.fillStyle=r.color,s.textBaseline="middle",s.textAlign=i.textAlign,a=i.label,o=i.textOffset,en(a))for(e=0,n=a.length;e<n;++e)s.fillText(""+a[e],0,o),o+=r.lineHeight;else s.fillText(a,0,o);s.restore()}},_drawTitle:function(){var t,e,n,i,r,a,o,s,l,u=this,d=u.ctx,h=u.options,c=h.scaleLabel;c.display&&(t=rn(c.fontColor,Y.global.defaultFontColor),e=B.options._parseFont(c),n=B.options.toPadding(c.padding),i=e.lineHeight/2,r=h.position,l=0,u.isHorizontal()?(o=u.left+u.width/2,s="bottom"===r?u.bottom-i-n.bottom:u.top+i+n.top):(o=(a="left"===r)?u.left+i+n.top:u.right-i-n.top,s=u.top+u.height/2,l=a?-.5*Math.PI:.5*Math.PI),d.save(),d.translate(o,s),d.rotate(l),d.textAlign="center",d.textBaseline="middle",d.fillStyle=t,d.font=e.string,d.fillText(c.labelString,0,0),d.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(e){var n=this,i=n.isHorizontal();return n.chart._getSortedVisibleDatasetMetas().filter(function(t){return(!e||t.type===e)&&(i?t.xAxisID===n.id:t.yAxisID===n.id)})}});gn.prototype._draw=gn.prototype.draw;var mn=gn,pn=B.isNullOrUndef,vn=mn.extend({determineDataLimits:function(){var t,e=this,n=e._getLabels(),i=e.options.ticks,r=i.min,a=i.max,o=0,s=n.length-1;void 0!==r&&0<=(t=n.indexOf(r))&&(o=t),void 0!==a&&0<=(t=n.indexOf(a))&&(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;mn.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,r,a,o=this;return pn(e)||pn(n)||(t=o.chart.data.datasets[n].data[e]),pn(t)||(i=o.isHorizontal()?t.x:t.y),(void 0!==i||void 0!==t&&isNaN(e))&&(r=o._getLabels(),t=B.valueOrDefault(i,t),e=-1!==(a=r.indexOf(t))?a: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}}),yn={position:"bottom"};vn._defaults=yn;var bn=B.noop,xn=B.isNullOrUndef;var _n=mn.extend({getRightValue:function(t){return"string"==typeof t?+t:mn.prototype.getRightValue.call(this,t)},handleTickRangeOptions:function(){var t,e,n=this,i=n.options.ticks;i.beginAtZero&&(t=B.sign(n.min),e=B.sign(n.max),t<0&&e<0?n.max=0:0<t&&0<e&&(n.min=0));var r=void 0!==i.min||void 0!==i.suggestedMin,a=void 0!==i.max||void 0!==i.suggestedMax;void 0!==i.min?n.min=i.min:void 0!==i.suggestedMin&&(null===n.min?n.min=i.suggestedMin:n.min=Math.min(n.min,i.suggestedMin)),void 0!==i.max?n.max=i.max:void 0!==i.suggestedMax&&(null===n.max?n.max=i.suggestedMax:n.max=Math.max(n.max,i.suggestedMax)),r!=a&&n.min>=n.max&&(r?n.max=n.min+1:n.min=n.max-1),n.min===n.max&&(n.max++,i.beginAtZero||n.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:bn,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:B.valueOrDefault(e.fixedStepSize,e.stepSize)},r=t.ticks=function(t,e){var n,i,r,a,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,m=B.niceNum((g-f)/u/l)*l;if(m<1e-14&&xn(d)&&xn(h))return[f,g];u<(a=Math.ceil(g/m)-Math.floor(f/m))&&(m=B.niceNum(a*m/u/l)*l),s||xn(c)?n=Math.pow(10,B._decimalPlaces(m)):(n=Math.pow(10,c),m=Math.ceil(m*n)/n),i=Math.floor(f/m)*m,r=Math.ceil(g/m)*m,s&&(!xn(d)&&B.almostWhole(d/m,m/1e3)&&(i=d),!xn(h)&&B.almostWhole(h/m,m/1e3)&&(r=h)),a=(r-i)/m,a=B.almostEquals(a,Math.round(a),m/1e3)?Math.round(a):Math.ceil(a),i=Math.round(i*n)/n,r=Math.round(r*n)/n,o.push(xn(d)?i:d);for(var p=1;p<a;++p)o.push(Math.round((i+p*m)*n)/n);return o.push(xn(h)?r:h),o}(i,t);t.handleDirectionalChanges(),t.max=B.max(r),t.min=B.min(r),e.reverse?(r.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),mn.prototype.convertTicksToLabels.call(t)},_configure:function(){var t,e=this,n=e.getTicks(),i=e.min,r=e.max;mn.prototype._configure.call(e),e.options.offset&&n.length&&(i-=t=(r-i)/Math.max(n.length-1,1)/2,r+=t),e._startValue=i,e._endValue=r,e._valueRange=r-i}}),wn={position:"left",ticks:{callback:tn.formatters.linear}};var kn=_n.extend({determineDataLimits:function(){var t,e,n,i,r=this,a=r.options,o=r.chart.data.datasets,s=r._getMatchingVisibleMetas(),l=a.stacked,u={},d=s.length;if(r.min=Number.POSITIVE_INFINITY,r.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?function(t,e,n,i){for(var r,a,o,s,l,u=t.options,d=u.stacked,h=(r=e,a=d,s=[(o=n).type,void 0===a&&void 0===o.stack?o.index:"",o.stack].join("."),void 0===r[s]&&(r[s]={pos:[],neg:[]}),r[s]),c=h.pos,f=h.neg,g=i.length,m=0;m<g;++m)l=t._parseValue(i[m]),isNaN(l.min)||isNaN(l.max)||n.data[m].hidden||(c[m]=c[m]||0,f[m]=f[m]||0,u.relativePoints?c[m]=100:l.min<0||l.max<0?f[m]+=l.min:c[m]+=l.max)}(r,u,e,n):function(t,e,n){for(var i,r=n.length,a=0;a<r;++a)i=t._parseValue(n[a]),isNaN(i.min)||isNaN(i.max)||e.data[a].hidden||(t.min=Math.min(t.min,i.min),t.max=Math.max(t.max,i.max))}(r,e,n);B.each(u,function(t){i=t.pos.concat(t.neg),r.min=Math.min(r.min,B.min(i)),r.max=Math.max(r.max,B.max(i))}),r.min=B.isFinite(r.min)&&!isNaN(r.min)?r.min:0,r.max=B.isFinite(r.max)&&!isNaN(r.max)?r.max:1,r.handleTickRangeOptions()},_computeTickLimit:function(){var t;return this.isHorizontal()?Math.ceil(this.width/40):(t=B.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])}});kn._defaults=wn;var Mn=B.valueOrDefault,Sn=B.math.log10;var Dn={position:"left",ticks:{callback:tn.formatters.logarithmic}};function Cn(t,e){return B.isFinite(t)&&0<=t?t:e}var Pn=mn.extend({determineDataLimits:function(){var t,e,n,i,r=this,a=r.options,o=r.chart,s=o.data.datasets,l=r.isHorizontal();function u(t){return l?t.xAxisID===r.id:t.yAxisID===r.id}r.min=Number.POSITIVE_INFINITY,r.max=Number.NEGATIVE_INFINITY,r.minNotZero=Number.POSITIVE_INFINITY;var d=a.stacked;if(void 0===d)for(c=0;c<s.length;c++)if(t=o.getDatasetMeta(c),o.isDatasetVisible(c)&&u(t)&&void 0!==t.stack){d=!0;break}if(a.stacked||d){for(var h={},c=0;c<s.length;c++){var f=[(t=o.getDatasetMeta(c)).type,void 0===a.stacked&&void 0===t.stack?c:"",t.stack].join(".");if(o.isDatasetVisible(c)&&u(t))for(void 0===h[f]&&(h[f]=[]),n=0,i=(e=s[c].data).length;n<i;n++){var g=h[f],m=r._parseValue(e[n]);isNaN(m.min)||isNaN(m.max)||t.data[n].hidden||m.min<0||m.max<0||(g[n]=g[n]||0,g[n]+=m.max)}}B.each(h,function(t){var e,n;0<t.length&&(e=B.min(t),n=B.max(t),r.min=Math.min(r.min,e),r.max=Math.max(r.max,n))})}else for(c=0;c<s.length;c++)if(t=o.getDatasetMeta(c),o.isDatasetVisible(c)&&u(t))for(n=0,i=(e=s[c].data).length;n<i;n++)m=r._parseValue(e[n]),isNaN(m.min)||isNaN(m.max)||t.data[n].hidden||m.min<0||m.max<0||(r.min=Math.min(m.min,r.min),r.max=Math.max(m.max,r.max),0!==m.min&&(r.minNotZero=Math.min(m.min,r.minNotZero)));r.min=B.isFinite(r.min)?r.min:null,r.max=B.isFinite(r.max)?r.max:null,r.minNotZero=B.isFinite(r.minNotZero)?r.minNotZero:null,this.handleTickRangeOptions()},handleTickRangeOptions:function(){var t=this,e=t.options.ticks;t.min=Cn(e.min,t.min),t.max=Cn(e.max,t.max),t.min===t.max&&(0!==t.min&&null!==t.min?(t.min=Math.pow(10,Math.floor(Sn(t.min))-1),t.max=Math.pow(10,Math.floor(Sn(t.max))+1)):(t.min=1,t.max=10)),null===t.min&&(t.min=Math.pow(10,Math.floor(Sn(t.max))-1)),null===t.max&&(t.max=0!==t.min?Math.pow(10,Math.floor(Sn(t.min))+1):10),null===t.minNotZero&&(0<t.min?t.minNotZero=t.min:t.max<1?t.minNotZero=Math.pow(10,Math.floor(Sn(t.max))):t.minNotZero=1)},buildTicks:function(){var t=this,e=t.options.ticks,n=!t.isHorizontal(),i={min:Cn(e.min),max:Cn(e.max)},r=t.ticks=function(t,e){var n,i,r=[],a=Mn(t.min,Math.pow(10,Math.floor(Sn(e.min)))),o=Math.floor(Sn(e.max)),s=Math.ceil(e.max/Math.pow(10,o));0===a?(n=Math.floor(Sn(e.minNotZero)),i=Math.floor(e.minNotZero/Math.pow(10,n)),r.push(a),a=i*Math.pow(10,n)):(n=Math.floor(Sn(a)),i=Math.floor(a/Math.pow(10,n)));for(var l=n<0?Math.pow(10,Math.abs(n)):1;r.push(a),10===++i&&(i=1,l=0<=++n?1:l),a=Math.round(i*Math.pow(10,n)*l)/l,n<o||n===o&&i<s;);var u=Mn(t.max,a);return r.push(u),r}(i,t);t.max=B.max(r),t.min=B.min(r),e.reverse?(n=!n,t.start=t.max,t.end=t.min):(t.start=t.min,t.end=t.max),n&&r.reverse()},convertTicksToLabels:function(){this.tickValues=this.ticks.slice(),mn.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(Sn(t));return Math.floor(t/Math.pow(10,e))*Math.pow(10,e)},_configure:function(){var t=this,e=t.min,n=0;mn.prototype._configure.call(t),0===e&&(e=t._getFirstTickValue(t.minNotZero),n=Mn(t.options.ticks.fontSize,Y.global.defaultFontSize)/t._length),t._startValue=Sn(e),t._valueOffset=n,t._valueRange=(Sn(t.max)-Sn(e))/(1-n)},getPixelForValue:function(t){var e=this,n=0;return(t=+e.getRightValue(t))>e.min&&0<t&&(n=(Sn(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)}});Pn._defaults=Dn;var Tn=B.valueOrDefault,On=B.valueAtIndexOrDefault,An=B.options.resolve,Fn={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:tn.formatters.linear},pointLabels:{display:!0,fontSize:10,callback:function(t){return t}}};function In(t){var e=t.ticks;return e.display&&t.display?Tn(e.fontSize,Y.global.defaultFontSize)+2*e.backdropPaddingY:0}function Ln(t,e,n,i,r){return t===i||t===r?{start:e-n/2,end:e+n/2}:t<i||r<t?{start:e-n,end:e}:{start:e,end:e+n}}function Rn(t){var e,n,i=B.options._parseFont(t.options.pointLabels),r={l:0,r:t.width,t:0,b:t.height-t.paddingTop},a={};t.ctx.font=i.string,t._pointLabelSizes=[];for(var o,s,l,u=t.chart.data.labels.length,d=0;d<u;d++){n=t.getPointPosition(d,t.drawingArea+5),o=t.ctx,s=i.lineHeight,l=t.pointLabels[d],e=B.isArray(l)?{w:B.longestText(o,o.font,l),h:l.length*s}:{w:o.measureText(l).width,h:s},t._pointLabelSizes[d]=e;var h=t.getIndexAngle(d),c=B.toDegrees(h)%360,f=Ln(c,n.x,e.w,0,180),g=Ln(c,n.y,e.h,90,270);f.start<r.l&&(r.l=f.start,a.l=h),f.end>r.r&&(r.r=f.end,a.r=h),g.start<r.t&&(r.t=g.start,a.t=h),g.end>r.b&&(r.b=g.end,a.b=h)}t.setReductions(t.drawingArea,r,a)}function Nn(t){var e=t.ctx,n=t.options,i=n.pointLabels,r=In(n),a=t.getDistanceFromCenterForValue(n.ticks.reverse?t.min:t.max),o=B.options._parseFont(i);e.save(),e.font=o.string,e.textBaseline="middle";for(var s,l,u,d,h=t.chart.data.labels.length-1;0<=h;h--){var c=0===h?r/2:0,f=t.getPointPosition(h,a+c+5),g=On(i.fontColor,h,Y.global.defaultFontColor);e.fillStyle=g;var m=t.getIndexAngle(h),p=B.toDegrees(m);e.textAlign=0===(d=p)||180===d?"center":d<180?"left":"right",s=p,l=t._pointLabelSizes[h],u=f,90===s||270===s?u.y-=l.h/2:(270<s||s<90)&&(u.y-=l.h),function(t,e,n,i){var r,a,o=n.y+i/2;if(B.isArray(e))for(r=0,a=e.length;r<a;++r)t.fillText(e[r],n.x,o),o+=i;else t.fillText(e,n.x,o)}(e,t.pointLabels[h],f,o.lineHeight)}e.restore()}function Wn(t){return B.isNumber(t)?t:0}var Yn=_n.extend({setDimensions:function(){var t=this;t.width=t.maxWidth,t.height=t.maxHeight,t.paddingTop=In(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 r=this,n=r.chart,a=Number.POSITIVE_INFINITY,o=Number.NEGATIVE_INFINITY;B.each(n.data.datasets,function(t,e){var i;n.isDatasetVisible(e)&&(i=n.getDatasetMeta(e),B.each(t.data,function(t,e){var n=+r.getRightValue(t);isNaN(n)||i.data[e].hidden||(a=Math.min(n,a),o=Math.max(n,o))}))}),r.min=a===Number.POSITIVE_INFINITY?0:a,r.max=o===Number.NEGATIVE_INFINITY?0:o,r.handleTickRangeOptions()},_computeTickLimit:function(){return Math.ceil(this.drawingArea/In(this.options))},convertTicksToLabels:function(){var e=this;_n.prototype.convertTicksToLabels.call(e),e.pointLabels=e.chart.data.labels.map(function(){var t=B.callback(e.options.pointLabels.callback,arguments,e);return t||0===t?t:""})},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?Rn(this):this.setCenterPoint(0,0,0,0)},setReductions:function(t,e,n){var i=this,r=e.l/Math.sin(n.l),a=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),r=Wn(r),a=Wn(a),o=Wn(o),s=Wn(s);i.drawingArea=Math.min(Math.floor(t-(r+a)/2),Math.floor(t-(o+s)/2)),i.setCenterPoint(r,a,o,s)},setCenterPoint:function(t,e,n,i){var r=this,a=r.width-e-r.drawingArea,o=t+r.drawingArea,s=n+r.drawingArea,l=r.height-r.paddingTop-i-r.drawingArea;r.xCenter=Math.floor((o+a)/2+r.left),r.yCenter=Math.floor((s+l)/2+r.top+r.paddingTop)},getIndexAngle:function(t){var e=this.chart,n=(t*(360/e.data.labels.length)+((e.options||{}).startAngle||0))%360;return(n<0?360+n:n)*Math.PI*2/360},getDistanceFromCenterForValue:function(t){var e=this;if(B.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:0<e&&0<n?e:0)},_drawGrid:function(){var t,n,e,i=this,r=i.ctx,a=i.options,o=a.gridLines,s=a.angleLines,l=Tn(s.lineWidth,o.lineWidth),u=Tn(s.color,o.color);if(a.pointLabels.display&&Nn(i),o.display&&B.each(i.ticks,function(t,e){0!==e&&(n=i.getDistanceFromCenterForValue(i.ticksAsNumbers[e]),function(t,e,n,i){var r,a=t.ctx,o=e.circular,s=t.chart.data.labels.length,l=On(e.color,i-1),u=On(e.lineWidth,i-1);if((o||s)&&l&&u){if(a.save(),a.strokeStyle=l,a.lineWidth=u,a.setLineDash&&(a.setLineDash(e.borderDash||[]),a.lineDashOffset=e.borderDashOffset||0),a.beginPath(),o)a.arc(t.xCenter,t.yCenter,n,0,2*Math.PI);else{r=t.getPointPosition(0,n),a.moveTo(r.x,r.y);for(var d=1;d<s;d++)r=t.getPointPosition(d,n),a.lineTo(r.x,r.y)}a.closePath(),a.stroke(),a.restore()}}(i,o,n,e))}),s.display&&l&&u){for(r.save(),r.lineWidth=l,r.strokeStyle=u,r.setLineDash&&(r.setLineDash(An([s.borderDash,o.borderDash,[]])),r.lineDashOffset=An([s.borderDashOffset,o.borderDashOffset,0])),t=i.chart.data.labels.length-1;0<=t;t--)n=i.getDistanceFromCenterForValue(a.ticks.reverse?i.min:i.max),e=i.getPointPosition(t,n),r.beginPath(),r.moveTo(i.xCenter,i.yCenter),r.lineTo(e.x,e.y),r.stroke();r.restore()}},_drawLabels:function(){var t,n,i,r,a,o=this,s=o.ctx,l=o.options.ticks;l.display&&(t=o.getIndexAngle(0),n=B.options._parseFont(l),i=Tn(l.fontColor,Y.global.defaultFontColor),s.save(),s.font=n.string,s.translate(o.xCenter,o.yCenter),s.rotate(t),s.textAlign="center",s.textBaseline="middle",B.each(o.ticks,function(t,e){0===e&&!l.reverse||(r=o.getDistanceFromCenterForValue(o.ticksAsNumbers[e]),l.showLabelBackdrop&&(a=s.measureText(t).width,s.fillStyle=l.backdropColor,s.fillRect(-a/2-l.backdropPaddingX,-r-n.size/2-l.backdropPaddingY,a+2*l.backdropPaddingX,n.size+2*l.backdropPaddingY)),s.fillStyle=i,s.fillText(t,0,-r))}),s.restore())},_drawTitle:B.noop});Yn._defaults=Fn;var zn=B._deprecated,Vn=B.options.resolve,En=B.valueOrDefault,Hn=Number.MIN_SAFE_INTEGER||-9007199254740991,Bn=Number.MAX_SAFE_INTEGER||9007199254740991,jn={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}},Un=Object.keys(jn);function Gn(t,e){return t-e}function qn(t){return B.valueOrDefault(t.time.min,t.ticks.min)}function Zn(t){return B.valueOrDefault(t.time.max,t.ticks.max)}function $n(t,e,n,i){var r=function(t,e,n){for(var i,r,a,o=0,s=t.length-1;0<=o&&o<=s;){if(r=t[(i=o+s>>1)-1]||null,a=t[i],!r)return{lo:null,hi:a};if(a[e]<n)o=1+i;else{if(!(r[e]>n))return{lo:r,hi:a};s=i-1}}return{lo:a,hi:null}}(t,e,n),a=r.lo?r.hi?r.lo:t[t.length-2]:t[0],o=r.lo?r.hi?r.hi:t[t.length-1]:t[1],s=o[e]-a[e],l=s?(n-a[e])/s:0,u=(o[i]-a[i])*l;return a[i]+u}function Xn(t,e){var n=t._adapter,i=t.options.time,r=i.parser,a=r||i.format,o=e;return"function"==typeof r&&(o=r(o)),B.isFinite(o)||(o="string"==typeof a?n.parse(o,a):n.parse(o)),null!==o?+o:(r||"function"!=typeof a||(o=a(e),B.isFinite(o)||(o=n.parse(o))),o)}function Kn(t,e){if(B.isNullOrUndef(e))return null;var n=t.options.time,i=Xn(t,t.getRightValue(e));return null===i||n.round&&(i=+t._adapter.startOf(i,n.round)),i}function Jn(t,e,n,i){for(var r,a,o=Un.length,s=Un.indexOf(t);s<o-1;++s)if(a=(r=jn[Un[s]]).steps?r.steps:Bn,r.common&&Math.ceil((n-e)/(a*r.size))<=i)return Un[s];return Un[o-1]}function Qn(t,e,n){for(var i,r=[],a={},o=e.length,s=0;s<o;++s)a[i=e[s]]=s,r.push({value:i,major:!1});return 0!==o&&n?function(t,e,n,i){for(var r,a=t._adapter,o=+a.startOf(e[0].value,i),s=e[e.length-1].value,l=o;l<=s;l=+a.add(l,1,i))0<=(r=n[l])&&(e[r].major=!0);return e}(t,r,a,n):r}var ti=mn.extend({initialize:function(){this.mergeTicksOptions(),mn.prototype.initialize.call(this)},update:function(){var t=this.options,e=t.time||(t.time={}),n=this._adapter=new Qe._date(t.adapters.date);return zn("time scale",e.format,"time.format","time.parser"),zn("time scale",e.min,"time.min","ticks.min"),zn("time scale",e.max,"time.max","ticks.max"),B.mergeIf(e.displayFormats,n.formats()),mn.prototype.update.apply(this,arguments)},getRightValue:function(t){return t&&void 0!==t.t&&(t=t.t),mn.prototype.getRightValue.call(this,t)},determineDataLimits:function(){for(var t,e,n,i,r,a=this,o=a.chart,s=a._adapter,l=a.options,u=l.time.unit||"day",d=Bn,h=Hn,c=[],f=[],g=[],m=a._getLabels(),p=0,v=m.length;p<v;++p)g.push(Kn(a,m[p]));for(p=0,v=(o.data.datasets||[]).length;p<v;++p)if(o.isDatasetVisible(p))if(n=o.data.datasets[p].data,B.isObject(n[0]))for(f[p]=[],t=0,e=n.length;t<e;++t)i=Kn(a,n[t]),c.push(i),f[p][t]=i;else f[p]=g.slice(0),r||(c=c.concat(g),r=!0);else f[p]=[];g.length&&(d=Math.min(d,g[0]),h=Math.max(h,g[g.length-1])),c.length&&(c=1<v?function(t){for(var e,n={},i=[],r=0,a=t.length;r<a;++r)n[e=t[r]]||(n[e]=!0,i.push(e));return i}(c).sort(Gn):c.sort(Gn),d=Math.min(d,c[0]),h=Math.max(h,c[c.length-1])),d=Kn(a,qn(l))||d,h=Kn(a,Zn(l))||h,d=d===Bn?+s.startOf(Date.now(),u):d,h=h===Hn?+s.endOf(Date.now(),u)+1:h,a.min=Math.min(d,h),a.max=Math.max(d+1,h),a._table=[],a._timestamps={data:c,datasets:f,labels:g}},buildTicks:function(){var t,e,n,i,r,a,o,s,l,u=this,d=u.min,h=u.max,c=u.options,f=c.ticks,g=c.time,m=u._timestamps,p=[],v=u.getLabelCapacity(d),y=f.source,b=c.distribution,m="data"===y||"auto"===y&&"series"===b?m.data:"labels"===y?m.labels:function(t,e,n,i){var r,a=t._adapter,o=t.options,s=o.time,l=s.unit||Jn(s.minUnit,e,n,i),u=Vn([s.stepSize,s.unitStepSize,1]),d="week"===l&&s.isoWeekday,h=e,c=[];if(d&&(h=+a.startOf(h,"isoWeek",d)),h=+a.startOf(h,d?"day":l),a.diff(n,e,l)>1e5*u)throw e+" and "+n+" are too far apart with stepSize of "+u+" "+l;for(r=h;r<n;r=+a.add(r,u,l))c.push(r);return r!==n&&"ticks"!==o.bounds||c.push(r),c}(u,d,h,v);for("ticks"===c.bounds&&m.length&&(d=m[0],h=m[m.length-1]),d=Kn(u,qn(c))||d,h=Kn(u,Zn(c))||h,t=0,e=m.length;t<e;++t)d<=(n=m[t])&&n<=h&&p.push(n);return u.min=d,u.max=h,u._unit=g.unit||(f.autoSkip?Jn(g.minUnit,u.min,u.max,v):function(t,e,n,i,r){for(var a,o=Un.length-1;o>=Un.indexOf(n);o--)if(a=Un[o],jn[a].common&&t._adapter.diff(r,i,a)>=e-1)return a;return Un[n?Un.indexOf(n):0]}(u,p.length,g.minUnit,u.min,u.max)),u._majorUnit=f.major.enabled&&"year"!==u._unit?function(t){for(var e=Un.indexOf(t)+1,n=Un.length;e<n;++e)if(jn[Un[e]].common)return Un[e]}(u._unit):void 0,u._table=function(t,e,n,i){if("linear"===i||!t.length)return[{time:e,pos:0},{time:n,pos:1}];for(var r,a,o,s=[],l=[e],u=0,d=t.length;u<d;++u)e<(a=t[u])&&a<n&&l.push(a);for(l.push(n),u=0,d=l.length;u<d;++u)o=l[u+1],r=l[u-1],a=l[u],void 0!==r&&void 0!==o&&Math.round((o+r)/2)===a||s.push({time:a,pos:u/(d-1)});return s}(u._timestamps.data,d,h,b),u._offsets=(i=u._table,r=p,l=s=0,c.offset&&r.length&&(a=$n(i,"time",r[0],"pos"),s=1===r.length?1-a:($n(i,"time",r[1],"pos")-a)/2,o=$n(i,"time",r[r.length-1],"pos"),l=1===r.length?o:(o-$n(i,"time",r[r.length-2],"pos"))/2),{start:s,end:l,factor:1/(s+1+l)}),f.reverse&&p.reverse(),Qn(u,p,u._majorUnit)},getLabelForIndex:function(t,e){var n=this,i=n._adapter,r=n.chart.data,a=n.options.time,o=r.labels&&t<r.labels.length?r.labels[t]:"",s=r.datasets[e].data[t];return B.isObject(s)&&(o=n.getRightValue(s)),a.tooltipFormat?i.format(Xn(n,o),a.tooltipFormat):"string"==typeof o?o:i.format(Xn(n,o),a.displayFormats.datetime)},tickFormatFunction:function(t,e,n,i){var r=this._adapter,a=this.options,o=a.time.displayFormats,s=o[this._unit],l=this._majorUnit,u=o[l],d=n[e],h=a.ticks,c=l&&u&&d&&d.major,f=r.format(t,i||(c?u:s)),g=c?h.major:h.minor,m=Vn([g.callback,g.userCallback,h.callback,h.userCallback]);return m?m(f,e,n):f},convertTicksToLabels:function(t){for(var e=[],n=0,i=t.length;n<i;++n)e.push(this.tickFormatFunction(t[n].value,n,t));return e},getPixelForOffset:function(t){var e=this._offsets,n=$n(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=Kn(this,t)),null!==i)return this.getPixelForOffset(i)},getPixelForTick:function(t){var e=this.getTicks();return 0<=t&&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=$n(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=B.toRadians(this.isHorizontal()?e.maxRotation:e.minRotation),r=Math.cos(i),a=Math.sin(i),o=En(e.fontSize,Y.global.defaultFontSize);return{w:n*r+o*a,h:n*a+o*r}},getLabelWidth:function(t){return this._getLabelSize(t).w},getLabelCapacity:function(t){var e=this.options.time,n=e.displayFormats,i=n[e.unit]||n.millisecond,r=this.tickFormatFunction(t,0,Qn(this,[t],this._majorUnit),i),a=this._getLabelSize(r),o=Math.floor(this.isHorizontal()?this.width/a.w:this.height/a.h);return this.options.offset&&o--,0<o?o:1}}),ei={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}}};ti._defaults=ei;var ni={category:vn,linear:kn,logarithmic:Pn,radialLinear:Yn,time:ti},ii=t(function(za,t){za.exports=function(){var e,r;function u(){return e.apply(null,arguments)}function t(t){e=t}function o(t){return t instanceof Array||Object.prototype.toString.call(t)==="[object Array]"}function s(t){return t!=null&&Object.prototype.toString.call(t)==="[object Object]"}function l(t){if(Object.getOwnPropertyNames){return Object.getOwnPropertyNames(t).length===0}else{var e;for(e in t){if(t.hasOwnProperty(e)){return false}}return true}}function a(t){return t===void 0}function d(t){return typeof t==="number"||Object.prototype.toString.call(t)==="[object Number]"}function h(t){return t instanceof Date||Object.prototype.toString.call(t)==="[object Date]"}function n(t,e){var n=[],i;for(i=0;i<t.length;++i){n.push(e(t[i],i))}return n}function c(t,e){return Object.prototype.hasOwnProperty.call(t,e)}function f(t,e){for(var n in e){if(c(e,n)){t[n]=e[n]}}if(c(e,"toString")){t.toString=e.toString}if(c(e,"valueOf")){t.valueOf=e.valueOf}return t}function g(t,e,n,i){return Gn(t,e,n,i,true).utc()}function i(){return{empty:false,unusedTokens:[],unusedInput:[],overflow:-2,charsLeftOver:0,nullInput:false,invalidMonth:null,invalidFormat:false,userInvalidated:false,iso:false,parsedDateParts:[],meridiem:null,rfc2822:false,weekdayMismatch:false}}function m(t){if(t._pf==null){t._pf=i()}return t._pf}if(Array.prototype.some){r=Array.prototype.some}else{r=function(t){var e=Object(this);var n=e.length>>>0;for(var i=0;i<n;i++){if(i in e&&t.call(this,e[i],i,e)){return true}}return false}}function p(t){if(t._isValid==null){var e=m(t);var n=r.call(e.parsedDateParts,function(t){return t!=null});var i=!isNaN(t._d.getTime())&&e.overflow<0&&!e.empty&&!e.invalidMonth&&!e.invalidWeekday&&!e.weekdayMismatch&&!e.nullInput&&!e.invalidFormat&&!e.userInvalidated&&(!e.meridiem||e.meridiem&&n);if(t._strict){i=i&&e.charsLeftOver===0&&e.unusedTokens.length===0&&e.bigHour===undefined}if(Object.isFrozen==null||!Object.isFrozen(t)){t._isValid=i}else{return i}}return t._isValid}function v(t){var e=g(NaN);if(t!=null){f(m(e),t)}else{m(e).userInvalidated=true}return e}var y=u.momentProperties=[];function b(t,e){var n,i,r;if(!a(e._isAMomentObject)){t._isAMomentObject=e._isAMomentObject}if(!a(e._i)){t._i=e._i}if(!a(e._f)){t._f=e._f}if(!a(e._l)){t._l=e._l}if(!a(e._strict)){t._strict=e._strict}if(!a(e._tzm)){t._tzm=e._tzm}if(!a(e._isUTC)){t._isUTC=e._isUTC}if(!a(e._offset)){t._offset=e._offset}if(!a(e._pf)){t._pf=m(e)}if(!a(e._locale)){t._locale=e._locale}if(y.length>0){for(n=0;n<y.length;n++){i=y[n];r=e[i];if(!a(r)){t[i]=r}}}return t}var x=false;function _(t){b(this,t);this._d=new Date(t._d!=null?t._d.getTime():NaN);if(!this.isValid()){this._d=new Date(NaN)}if(x===false){x=true;u.updateOffset(this);x=false}}function w(t){return t instanceof _||t!=null&&t._isAMomentObject!=null}function k(t){if(t<0){return Math.ceil(t)||0}else{return Math.floor(t)}}function M(t){var e=+t,n=0;if(e!==0&&isFinite(e)){n=k(e)}return n}function S(t,e,n){var i=Math.min(t.length,e.length),r=Math.abs(t.length-e.length),a=0,o;for(o=0;o<i;o++){if(n&&t[o]!==e[o]||!n&&M(t[o])!==M(e[o])){a++}}return a+r}function D(t){if(u.suppressDeprecationWarnings===false&&typeof console!=="undefined"&&console.warn){console.warn("Deprecation warning: "+t)}}function C(r,a){var o=true;return f(function(){if(u.deprecationHandler!=null){u.deprecationHandler(null,r)}if(o){var t=[];var e;for(var n=0;n<arguments.length;n++){e="";if(typeof arguments[n]==="object"){e+="\n["+n+"] ";for(var i in arguments[0]){e+=i+": "+arguments[0][i]+", "}e=e.slice(0,-2)}else{e=arguments[n]}t.push(e)}D(r+"\nArguments: "+Array.prototype.slice.call(t).join("")+"\n"+(new Error).stack);o=false}return a.apply(this,arguments)},a)}var P={},T;function O(t,e){if(u.deprecationHandler!=null){u.deprecationHandler(t,e)}if(!P[t]){D(e);P[t]=true}}function A(t){return t instanceof Function||Object.prototype.toString.call(t)==="[object Function]"}function F(t){var e,n;for(n in t){e=t[n];if(A(e)){this[n]=e}else{this["_"+n]=e}}this._config=t;this._dayOfMonthOrdinalParseLenient=new RegExp((this._dayOfMonthOrdinalParse.source||this._ordinalParse.source)+"|"+/\d{1,2}/.source)}function I(t,e){var n=f({},t),i;for(i in e){if(c(e,i)){if(s(t[i])&&s(e[i])){n[i]={};f(n[i],t[i]);f(n[i],e[i])}else if(e[i]!=null){n[i]=e[i]}else{delete n[i]}}}for(i in t){if(c(t,i)&&!c(e,i)&&s(t[i])){n[i]=f({},n[i])}}return n}function L(t){if(t!=null){this.set(t)}}if(u.suppressDeprecationWarnings=false,u.deprecationHandler=null,Object.keys){T=Object.keys}else{T=function(t){var e,n=[];for(e in t){if(c(t,e)){n.push(e)}}return n}}var R={sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"};function N(t,e,n){var i=this._calendar[t]||this._calendar["sameElse"];return A(i)?i.call(e,n):i}var W={LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"};function Y(t){var e=this._longDateFormat[t],n=this._longDateFormat[t.toUpperCase()];if(e||!n){return e}this._longDateFormat[t]=n.replace(/MMMM|MM|DD|dddd/g,function(t){return t.slice(1)});return this._longDateFormat[t]}var z="Invalid date";function V(){return this._invalidDate}var E="%d",H=/\d{1,2}/;function B(t){return this._ordinal.replace("%d",t)}var j={future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"};function U(t,e,n,i){var r=this._relativeTime[n];return A(r)?r(t,e,n,i):r.replace(/%d/i,t)}function G(t,e){var n=this._relativeTime[t>0?"future":"past"];return A(n)?n(e):n.replace(/%s/i,e)}var q={};function Z(t,e){var n=t.toLowerCase();q[n]=q[n+"s"]=q[e]=t}function $(t){return typeof t==="string"?q[t]||q[t.toLowerCase()]:undefined}function X(t){var e={},n,i;for(i in t){if(c(t,i)){n=$(i);if(n){e[n]=t[i]}}}return e}var K={};function J(t,e){K[t]=e}function Q(t){var e=[];for(var n in t){e.push({unit:n,priority:K[n]})}e.sort(function(t,e){return t.priority-e.priority});return e}function tt(t,e,n){var i=""+Math.abs(t),r=e-i.length,a=t>=0;return(a?n?"+":"":"-")+Math.pow(10,Math.max(0,r)).toString().substr(1)+i}var et=/(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g,nt=/(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,it={},rt={};function at(t,e,n,i){var r=i;if(typeof i==="string"){r=function(){return this[i]()}}if(t){rt[t]=r}if(e){rt[e[0]]=function(){return tt(r.apply(this,arguments),e[1],e[2])}}if(n){rt[n]=function(){return this.localeData().ordinal(r.apply(this,arguments),t)}}}function ot(t){if(t.match(/\[[\s\S]/)){return t.replace(/^\[|\]$/g,"")}return t.replace(/\\/g,"")}function st(i){var r=i.match(et),t,a;for(t=0,a=r.length;t<a;t++){if(rt[r[t]]){r[t]=rt[r[t]]}else{r[t]=ot(r[t])}}return function(t){var e="",n;for(n=0;n<a;n++){e+=A(r[n])?r[n].call(t,i):r[n]}return e}}function lt(t,e){if(!t.isValid()){return t.localeData().invalidDate()}e=ut(e,t.localeData());it[e]=it[e]||st(e);return it[e](t)}function ut(t,e){var n=5;function i(t){return e.longDateFormat(t)||t}nt.lastIndex=0;while(n>=0&&nt.test(t)){t=t.replace(nt,i);nt.lastIndex=0;n-=1}return t}var dt=/\d/,ht=/\d\d/,ct=/\d{3}/,ft=/\d{4}/,gt=/[+-]?\d{6}/,mt=/\d\d?/,pt=/\d\d\d\d?/,vt=/\d\d\d\d\d\d?/,yt=/\d{1,3}/,bt=/\d{1,4}/,xt=/[+-]?\d{1,6}/,_t=/\d+/,wt=/[+-]?\d+/,kt=/Z|[+-]\d\d:?\d\d/gi,Mt=/Z|[+-]\d\d(?::?\d\d)?/gi,St=/[+-]?\d+(\.\d{1,3})?/,Dt=/[0-9]{0,256}['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFF07\uFF10-\uFFEF]{1,256}|[\u0600-\u06FF\/]{1,256}(\s*?[\u0600-\u06FF]{1,256}){1,2}/i,Ct={};function Pt(t,n,i){Ct[t]=A(n)?n:function(t,e){return t&&i?i:n}}function Tt(t,e){if(!c(Ct,t)){return new RegExp(Ot(t))}return Ct[t](e._strict,e._locale)}function Ot(t){return At(t.replace("\\","").replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,function(t,e,n,i,r){return e||n||i||r}))}function At(t){return t.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}var Ft={};function It(t,n){var e,i=n;if(typeof t==="string"){t=[t]}if(d(n)){i=function(t,e){e[n]=M(t)}}for(e=0;e<t.length;e++){Ft[t[e]]=i}}function Lt(t,r){It(t,function(t,e,n,i){n._w=n._w||{};r(t,n._w,n,i)})}function Rt(t,e,n){if(e!=null&&c(Ft,t)){Ft[t](e,n._a,n,t)}}var Nt=0,Wt=1,Yt=2,zt=3,Vt=4,Et=5,Ht=6,Bt=7,jt=8;function Ut(t){return Gt(t)?366:365}function Gt(t){return t%4===0&&t%100!==0||t%400===0}at("Y",0,0,function(){var t=this.year();return t<=9999?""+t:"+"+t}),at(0,["YY",2],0,function(){return this.year()%100}),at(0,["YYYY",4],0,"year"),at(0,["YYYYY",5],0,"year"),at(0,["YYYYYY",6,true],0,"year"),Z("year","y"),J("year",1),Pt("Y",wt),Pt("YY",mt,ht),Pt("YYYY",bt,ft),Pt("YYYYY",xt,gt),Pt("YYYYYY",xt,gt),It(["YYYYY","YYYYYY"],Nt),It("YYYY",function(t,e){e[Nt]=t.length===2?u.parseTwoDigitYear(t):M(t)}),It("YY",function(t,e){e[Nt]=u.parseTwoDigitYear(t)}),It("Y",function(t,e){e[Nt]=parseInt(t,10)}),u.parseTwoDigitYear=function(t){return M(t)+(M(t)>68?1900:2e3)};var qt=Xt("FullYear",true),Zt;function $t(){return Gt(this.year())}function Xt(e,n){return function(t){if(t!=null){Jt(this,e,t);u.updateOffset(this,n);return this}else{return Kt(this,e)}}}function Kt(t,e){return t.isValid()?t._d["get"+(t._isUTC?"UTC":"")+e]():NaN}function Jt(t,e,n){if(t.isValid()&&!isNaN(n)){if(e==="FullYear"&&Gt(t.year())&&t.month()===1&&t.date()===29){t._d["set"+(t._isUTC?"UTC":"")+e](n,t.month(),ne(n,t.month()))}else{t._d["set"+(t._isUTC?"UTC":"")+e](n)}}}function Qt(t){t=$(t);if(A(this[t])){return this[t]()}return this}function te(t,e){if(typeof t==="object"){t=X(t);var n=Q(t);for(var i=0;i<n.length;i++){this[n[i].unit](t[n[i].unit])}}else{t=$(t);if(A(this[t])){return this[t](e)}}return this}function ee(t,e){return(t%e+e)%e}if(Array.prototype.indexOf){Zt=Array.prototype.indexOf}else{Zt=function(t){var e;for(e=0;e<this.length;++e){if(this[e]===t){return e}}return-1}}function ne(t,e){if(isNaN(t)||isNaN(e)){return NaN}var n=ee(e,12);t+=(e-n)/12;return n===1?Gt(t)?29:28:31-n%7%2}at("M",["MM",2],"Mo",function(){return this.month()+1}),at("MMM",0,0,function(t){return this.localeData().monthsShort(this,t)}),at("MMMM",0,0,function(t){return this.localeData().months(this,t)}),Z("month","M"),J("month",8),Pt("M",mt),Pt("MM",mt,ht),Pt("MMM",function(t,e){return e.monthsShortRegex(t)}),Pt("MMMM",function(t,e){return e.monthsRegex(t)}),It(["M","MM"],function(t,e){e[Wt]=M(t)-1}),It(["MMM","MMMM"],function(t,e,n,i){var r=n._locale.monthsParse(t,i,n._strict);if(r!=null){e[Wt]=r}else{m(n).invalidMonth=t}});var ie=/D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/,re="January_February_March_April_May_June_July_August_September_October_November_December".split("_");function ae(t,e){if(!t){return o(this._months)?this._months:this._months["standalone"]}return o(this._months)?this._months[t.month()]:this._months[(this._months.isFormat||ie).test(e)?"format":"standalone"][t.month()]}var oe="Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_");function se(t,e){if(!t){return o(this._monthsShort)?this._monthsShort:this._monthsShort["standalone"]}return o(this._monthsShort)?this._monthsShort[t.month()]:this._monthsShort[ie.test(e)?"format":"standalone"][t.month()]}function le(t,e,n){var i,r,a,o=t.toLocaleLowerCase();if(!this._monthsParse){this._monthsParse=[];this._longMonthsParse=[];this._shortMonthsParse=[];for(i=0;i<12;++i){a=g([2e3,i]);this._shortMonthsParse[i]=this.monthsShort(a,"").toLocaleLowerCase();this._longMonthsParse[i]=this.months(a,"").toLocaleLowerCase()}}if(n){if(e==="MMM"){r=Zt.call(this._shortMonthsParse,o);return r!==-1?r:null}else{r=Zt.call(this._longMonthsParse,o);return r!==-1?r:null}}else{if(e==="MMM"){r=Zt.call(this._shortMonthsParse,o);if(r!==-1){return r}r=Zt.call(this._longMonthsParse,o);return r!==-1?r:null}else{r=Zt.call(this._longMonthsParse,o);if(r!==-1){return r}r=Zt.call(this._shortMonthsParse,o);return r!==-1?r:null}}}function ue(t,e,n){var i,r,a;if(this._monthsParseExact){return le.call(this,t,e,n)}if(!this._monthsParse){this._monthsParse=[];this._longMonthsParse=[];this._shortMonthsParse=[]}for(i=0;i<12;i++){r=g([2e3,i]);if(n&&!this._longMonthsParse[i]){this._longMonthsParse[i]=new RegExp("^"+this.months(r,"").replace(".","")+"$","i");this._shortMonthsParse[i]=new RegExp("^"+this.monthsShort(r,"").replace(".","")+"$","i")}if(!n&&!this._monthsParse[i]){a="^"+this.months(r,"")+"|^"+this.monthsShort(r,"");this._monthsParse[i]=new RegExp(a.replace(".",""),"i")}if(n&&e==="MMMM"&&this._longMonthsParse[i].test(t)){return i}else if(n&&e==="MMM"&&this._shortMonthsParse[i].test(t)){return i}else if(!n&&this._monthsParse[i].test(t)){return i}}}function de(t,e){var n;if(!t.isValid()){return t}if(typeof e==="string"){if(/^\d+$/.test(e)){e=M(e)}else{e=t.localeData().monthsParse(e);if(!d(e)){return t}}}n=Math.min(t.date(),ne(t.year(),e));t._d["set"+(t._isUTC?"UTC":"")+"Month"](e,n);return t}function he(t){if(t!=null){de(this,t);u.updateOffset(this,true);return this}else{return Kt(this,"Month")}}function ce(){return ne(this.year(),this.month())}var fe=Dt;function ge(t){if(this._monthsParseExact){if(!c(this,"_monthsRegex")){ve.call(this)}if(t){return this._monthsShortStrictRegex}else{return this._monthsShortRegex}}else{if(!c(this,"_monthsShortRegex")){this._monthsShortRegex=fe}return this._monthsShortStrictRegex&&t?this._monthsShortStrictRegex:this._monthsShortRegex}}var me=Dt;function pe(t){if(this._monthsParseExact){if(!c(this,"_monthsRegex")){ve.call(this)}if(t){return this._monthsStrictRegex}else{return this._monthsRegex}}else{if(!c(this,"_monthsRegex")){this._monthsRegex=me}return this._monthsStrictRegex&&t?this._monthsStrictRegex:this._monthsRegex}}function ve(){function t(t,e){return e.length-t.length}var e=[],n=[],i=[],r,a;for(r=0;r<12;r++){a=g([2e3,r]);e.push(this.monthsShort(a,""));n.push(this.months(a,""));i.push(this.months(a,""));i.push(this.monthsShort(a,""))}e.sort(t);n.sort(t);i.sort(t);for(r=0;r<12;r++){e[r]=At(e[r]);n[r]=At(n[r])}for(r=0;r<24;r++){i[r]=At(i[r])}this._monthsRegex=new RegExp("^("+i.join("|")+")","i");this._monthsShortRegex=this._monthsRegex;this._monthsStrictRegex=new RegExp("^("+n.join("|")+")","i");this._monthsShortStrictRegex=new RegExp("^("+e.join("|")+")","i")}function ye(t,e,n,i,r,a,o){var s;if(t<100&&t>=0){s=new Date(t+400,e,n,i,r,a,o);if(isFinite(s.getFullYear())){s.setFullYear(t)}}else{s=new Date(t,e,n,i,r,a,o)}return s}function be(t){var e;if(t<100&&t>=0){var n=Array.prototype.slice.call(arguments);n[0]=t+400;e=new Date(Date.UTC.apply(null,n));if(isFinite(e.getUTCFullYear())){e.setUTCFullYear(t)}}else{e=new Date(Date.UTC.apply(null,arguments))}return e}function xe(t,e,n){var i=7+e-n,r=(7+be(t,0,i).getUTCDay()-e)%7;return-r+i-1}function _e(t,e,n,i,r){var a=(7+n-i)%7,o=xe(t,i,r),s=1+7*(e-1)+a+o,l,u;if(s<=0){l=t-1;u=Ut(l)+s}else if(s>Ut(t)){l=t+1;u=s-Ut(t)}else{l=t;u=s}return{year:l,dayOfYear:u}}function we(t,e,n){var i=xe(t.year(),e,n),r=Math.floor((t.dayOfYear()-i-1)/7)+1,a,o;if(r<1){o=t.year()-1;a=r+ke(o,e,n)}else if(r>ke(t.year(),e,n)){a=r-ke(t.year(),e,n);o=t.year()+1}else{o=t.year();a=r}return{week:a,year:o}}function ke(t,e,n){var i=xe(t,e,n),r=xe(t+1,e,n);return(Ut(t)-i+r)/7}function Me(t){return we(t,this._week.dow,this._week.doy).week}at("w",["ww",2],"wo","week"),at("W",["WW",2],"Wo","isoWeek"),Z("week","w"),Z("isoWeek","W"),J("week",5),J("isoWeek",5),Pt("w",mt),Pt("ww",mt,ht),Pt("W",mt),Pt("WW",mt,ht),Lt(["w","ww","W","WW"],function(t,e,n,i){e[i.substr(0,1)]=M(t)});var Se={dow:0,doy:6};function De(){return this._week.dow}function Ce(){return this._week.doy}function Pe(t){var e=this.localeData().week(this);return t==null?e:this.add((t-e)*7,"d")}function Te(t){var e=we(this,1,4).week;return t==null?e:this.add((t-e)*7,"d")}function Oe(t,e){if(typeof t!=="string"){return t}if(!isNaN(t)){return parseInt(t,10)}t=e.weekdaysParse(t);if(typeof t==="number"){return t}return null}function Ae(t,e){if(typeof t==="string"){return e.weekdaysParse(t)%7||7}return isNaN(t)?null:t}function Fe(t,e){return t.slice(e,7).concat(t.slice(0,e))}at("d",0,"do","day"),at("dd",0,0,function(t){return this.localeData().weekdaysMin(this,t)}),at("ddd",0,0,function(t){return this.localeData().weekdaysShort(this,t)}),at("dddd",0,0,function(t){return this.localeData().weekdays(this,t)}),at("e",0,0,"weekday"),at("E",0,0,"isoWeekday"),Z("day","d"),Z("weekday","e"),Z("isoWeekday","E"),J("day",11),J("weekday",11),J("isoWeekday",11),Pt("d",mt),Pt("e",mt),Pt("E",mt),Pt("dd",function(t,e){return e.weekdaysMinRegex(t)}),Pt("ddd",function(t,e){return e.weekdaysShortRegex(t)}),Pt("dddd",function(t,e){return e.weekdaysRegex(t)}),Lt(["dd","ddd","dddd"],function(t,e,n,i){var r=n._locale.weekdaysParse(t,i,n._strict);if(r!=null){e.d=r}else{m(n).invalidWeekday=t}}),Lt(["d","e","E"],function(t,e,n,i){e[i]=M(t)});var Ie="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_");function Le(t,e){var n=o(this._weekdays)?this._weekdays:this._weekdays[t&&t!==true&&this._weekdays.isFormat.test(e)?"format":"standalone"];return t===true?Fe(n,this._week.dow):t?n[t.day()]:n}var Re="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_");function Ne(t){return t===true?Fe(this._weekdaysShort,this._week.dow):t?this._weekdaysShort[t.day()]:this._weekdaysShort}var We="Su_Mo_Tu_We_Th_Fr_Sa".split("_");function Ye(t){return t===true?Fe(this._weekdaysMin,this._week.dow):t?this._weekdaysMin[t.day()]:this._weekdaysMin}function ze(t,e,n){var i,r,a,o=t.toLocaleLowerCase();if(!this._weekdaysParse){this._weekdaysParse=[];this._shortWeekdaysParse=[];this._minWeekdaysParse=[];for(i=0;i<7;++i){a=g([2e3,1]).day(i);this._minWeekdaysParse[i]=this.weekdaysMin(a,"").toLocaleLowerCase();this._shortWeekdaysParse[i]=this.weekdaysShort(a,"").toLocaleLowerCase();this._weekdaysParse[i]=this.weekdays(a,"").toLocaleLowerCase()}}if(n){if(e==="dddd"){r=Zt.call(this._weekdaysParse,o);return r!==-1?r:null}else if(e==="ddd"){r=Zt.call(this._shortWeekdaysParse,o);return r!==-1?r:null}else{r=Zt.call(this._minWeekdaysParse,o);return r!==-1?r:null}}else{if(e==="dddd"){r=Zt.call(this._weekdaysParse,o);if(r!==-1){return r}r=Zt.call(this._shortWeekdaysParse,o);if(r!==-1){return r}r=Zt.call(this._minWeekdaysParse,o);return r!==-1?r:null}else if(e==="ddd"){r=Zt.call(this._shortWeekdaysParse,o);if(r!==-1){return r}r=Zt.call(this._weekdaysParse,o);if(r!==-1){return r}r=Zt.call(this._minWeekdaysParse,o);return r!==-1?r:null}else{r=Zt.call(this._minWeekdaysParse,o);if(r!==-1){return r}r=Zt.call(this._weekdaysParse,o);if(r!==-1){return r}r=Zt.call(this._shortWeekdaysParse,o);return r!==-1?r:null}}}function Ve(t,e,n){var i,r,a;if(this._weekdaysParseExact){return ze.call(this,t,e,n)}if(!this._weekdaysParse){this._weekdaysParse=[];this._minWeekdaysParse=[];this._shortWeekdaysParse=[];this._fullWeekdaysParse=[]}for(i=0;i<7;i++){r=g([2e3,1]).day(i);if(n&&!this._fullWeekdaysParse[i]){this._fullWeekdaysParse[i]=new RegExp("^"+this.weekdays(r,"").replace(".","\\.?")+"$","i");this._shortWeekdaysParse[i]=new RegExp("^"+this.weekdaysShort(r,"").replace(".","\\.?")+"$","i");this._minWeekdaysParse[i]=new RegExp("^"+this.weekdaysMin(r,"").replace(".","\\.?")+"$","i")}if(!this._weekdaysParse[i]){a="^"+this.weekdays(r,"")+"|^"+this.weekdaysShort(r,"")+"|^"+this.weekdaysMin(r,"");this._weekdaysParse[i]=new RegExp(a.replace(".",""),"i")}if(n&&e==="dddd"&&this._fullWeekdaysParse[i].test(t)){return i}else if(n&&e==="ddd"&&this._shortWeekdaysParse[i].test(t)){return i}else if(n&&e==="dd"&&this._minWeekdaysParse[i].test(t)){return i}else if(!n&&this._weekdaysParse[i].test(t)){return i}}}function Ee(t){if(!this.isValid()){return t!=null?this:NaN}var e=this._isUTC?this._d.getUTCDay():this._d.getDay();if(t!=null){t=Oe(t,this.localeData());return this.add(t-e,"d")}else{return e}}function He(t){if(!this.isValid()){return t!=null?this:NaN}var e=(this.day()+7-this.localeData()._week.dow)%7;return t==null?e:this.add(t-e,"d")}function Be(t){if(!this.isValid()){return t!=null?this:NaN}if(t!=null){var e=Ae(t,this.localeData());return this.day(this.day()%7?e:e-7)}else{return this.day()||7}}var je=Dt;function Ue(t){if(this._weekdaysParseExact){if(!c(this,"_weekdaysRegex")){Ke.call(this)}if(t){return this._weekdaysStrictRegex}else{return this._weekdaysRegex}}else{if(!c(this,"_weekdaysRegex")){this._weekdaysRegex=je}return this._weekdaysStrictRegex&&t?this._weekdaysStrictRegex:this._weekdaysRegex}}var Ge=Dt;function qe(t){if(this._weekdaysParseExact){if(!c(this,"_weekdaysRegex")){Ke.call(this)}if(t){return this._weekdaysShortStrictRegex}else{return this._weekdaysShortRegex}}else{if(!c(this,"_weekdaysShortRegex")){this._weekdaysShortRegex=Ge}return this._weekdaysShortStrictRegex&&t?this._weekdaysShortStrictRegex:this._weekdaysShortRegex}}var Ze=Dt,$e;function Xe(t){if(this._weekdaysParseExact){if(!c(this,"_weekdaysRegex")){Ke.call(this)}if(t){return this._weekdaysMinStrictRegex}else{return this._weekdaysMinRegex}}else{if(!c(this,"_weekdaysMinRegex")){this._weekdaysMinRegex=Ze}return this._weekdaysMinStrictRegex&&t?this._weekdaysMinStrictRegex:this._weekdaysMinRegex}}function Ke(){function t(t,e){return e.length-t.length}var e=[],n=[],i=[],r=[],a,o,s,l,u;for(a=0;a<7;a++){o=g([2e3,1]).day(a);s=this.weekdaysMin(o,"");l=this.weekdaysShort(o,"");u=this.weekdays(o,"");e.push(s);n.push(l);i.push(u);r.push(s);r.push(l);r.push(u)}e.sort(t);n.sort(t);i.sort(t);r.sort(t);for(a=0;a<7;a++){n[a]=At(n[a]);i[a]=At(i[a]);r[a]=At(r[a])}this._weekdaysRegex=new RegExp("^("+r.join("|")+")","i");this._weekdaysShortRegex=this._weekdaysRegex;this._weekdaysMinRegex=this._weekdaysRegex;this._weekdaysStrictRegex=new RegExp("^("+i.join("|")+")","i");this._weekdaysShortStrictRegex=new RegExp("^("+n.join("|")+")","i");this._weekdaysMinStrictRegex=new RegExp("^("+e.join("|")+")","i")}function Je(){return this.hours()%12||12}function Qe(){return this.hours()||24}function tn(t,e){at(t,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),e)})}function en(t,e){return e._meridiemParse}function nn(t){return(t+"").toLowerCase().charAt(0)==="p"}function rn(t,e,n){if(t>11){return n?"pm":"PM"}else{return n?"am":"AM"}}at("H",["HH",2],0,"hour"),at("h",["hh",2],0,Je),at("k",["kk",2],0,Qe),at("hmm",0,0,function(){return""+Je.apply(this)+tt(this.minutes(),2)}),at("hmmss",0,0,function(){return""+Je.apply(this)+tt(this.minutes(),2)+tt(this.seconds(),2)}),at("Hmm",0,0,function(){return""+this.hours()+tt(this.minutes(),2)}),at("Hmmss",0,0,function(){return""+this.hours()+tt(this.minutes(),2)+tt(this.seconds(),2)}),tn("a",true),tn("A",false),Z("hour","h"),J("hour",13),Pt("a",en),Pt("A",en),Pt("H",mt),Pt("h",mt),Pt("k",mt),Pt("HH",mt,ht),Pt("hh",mt,ht),Pt("kk",mt,ht),Pt("hmm",pt),Pt("hmmss",vt),Pt("Hmm",pt),Pt("Hmmss",vt),It(["H","HH"],zt),It(["k","kk"],function(t,e,n){var i=M(t);e[zt]=i===24?0:i}),It(["a","A"],function(t,e,n){n._isPm=n._locale.isPM(t);n._meridiem=t}),It(["h","hh"],function(t,e,n){e[zt]=M(t);m(n).bigHour=true}),It("hmm",function(t,e,n){var i=t.length-2;e[zt]=M(t.substr(0,i));e[Vt]=M(t.substr(i));m(n).bigHour=true}),It("hmmss",function(t,e,n){var i=t.length-4;var r=t.length-2;e[zt]=M(t.substr(0,i));e[Vt]=M(t.substr(i,2));e[Et]=M(t.substr(r));m(n).bigHour=true}),It("Hmm",function(t,e,n){var i=t.length-2;e[zt]=M(t.substr(0,i));e[Vt]=M(t.substr(i))}),It("Hmmss",function(t,e,n){var i=t.length-4;var r=t.length-2;e[zt]=M(t.substr(0,i));e[Vt]=M(t.substr(i,2));e[Et]=M(t.substr(r))});var an=Xt("Hours",true),on={calendar:R,longDateFormat:W,invalidDate:z,ordinal:E,dayOfMonthOrdinalParse:H,relativeTime:j,months:re,monthsShort:oe,week:Se,weekdays:Ie,weekdaysMin:We,weekdaysShort:Re,meridiemParse:/[ap]\.?m?\.?/i},sn={},ln={},un;function dn(t){return t?t.toLowerCase().replace("_","-"):t}function hn(t){var e=0,n,i,r,a;while(e<t.length){a=dn(t[e]).split("-");n=a.length;i=dn(t[e+1]);i=i?i.split("-"):null;while(n>0){r=cn(a.slice(0,n).join("-"));if(r){return r}if(i&&i.length>=n&&S(a,i,true)>=n-1){break}n--}e++}return un}function cn(t){var e=null;if(!sn[t]&&"object"!=="undefined"&&za&&za.exports){try{e=un._abbr;var n=Va;n("./locale/"+t);fn(e)}catch(t){}}return sn[t]}function fn(t,e){var n;if(t){if(a(e)){n=pn(t)}else{n=gn(t,e)}if(n){un=n}else{if(typeof console!=="undefined"&&console.warn){console.warn("Locale "+t+" not found. Did you forget to load it?")}}}return un._abbr}function gn(t,e){if(e!==null){var n,i=on;e.abbr=t;if(sn[t]!=null){O("defineLocaleOverride","use moment.updateLocale(localeName, config) to change "+"an existing locale. moment.defineLocale(localeName, "+"config) should only be used for creating a new locale "+"See http://momentjs.com/guides/#/warnings/define-locale/ for more info.");i=sn[t]._config}else if(e.parentLocale!=null){if(sn[e.parentLocale]!=null){i=sn[e.parentLocale]._config}else{n=cn(e.parentLocale);if(n!=null){i=n._config}else{if(!ln[e.parentLocale]){ln[e.parentLocale]=[]}ln[e.parentLocale].push({name:t,config:e});return null}}}sn[t]=new L(I(i,e));if(ln[t]){ln[t].forEach(function(t){gn(t.name,t.config)})}fn(t);return sn[t]}else{delete sn[t];return null}}function mn(t,e){if(null!=e){var n,i,r=on;null!=(i=cn(t))&&(r=i._config),e=I(r,e),(n=new L(e)).parentLocale=sn[t],sn[t]=n,fn(t)}else null!=sn[t]&&(null!=sn[t].parentLocale?sn[t]=sn[t].parentLocale:null!=sn[t]&&delete sn[t]);return sn[t]}function pn(t){var e;if(t&&t._locale&&t._locale._abbr){t=t._locale._abbr}if(!t){return un}if(!o(t)){e=cn(t);if(e){return e}t=[t]}return hn(t)}function vn(){return T(sn)}function yn(t){var e;var n=t._a;if(n&&m(t).overflow===-2){e=n[Wt]<0||n[Wt]>11?Wt:n[Yt]<1||n[Yt]>ne(n[Nt],n[Wt])?Yt:n[zt]<0||n[zt]>24||n[zt]===24&&(n[Vt]!==0||n[Et]!==0||n[Ht]!==0)?zt:n[Vt]<0||n[Vt]>59?Vt:n[Et]<0||n[Et]>59?Et:n[Ht]<0||n[Ht]>999?Ht:-1;if(m(t)._overflowDayOfYear&&(e<Nt||e>Yt)){e=Yt}if(m(t)._overflowWeeks&&e===-1){e=Bt}if(m(t)._overflowWeekday&&e===-1){e=jt}m(t).overflow=e}return t}function bn(t,e,n){if(t!=null){return t}if(e!=null){return e}return n}function xn(t){var e=new Date(u.now());if(t._useUTC){return[e.getUTCFullYear(),e.getUTCMonth(),e.getUTCDate()]}return[e.getFullYear(),e.getMonth(),e.getDate()]}function _n(t){var e,n,i=[],r,a,o;if(t._d){return}r=xn(t);if(t._w&&t._a[Yt]==null&&t._a[Wt]==null){wn(t)}if(t._dayOfYear!=null){o=bn(t._a[Nt],r[Nt]);if(t._dayOfYear>Ut(o)||t._dayOfYear===0){m(t)._overflowDayOfYear=true}n=be(o,0,t._dayOfYear);t._a[Wt]=n.getUTCMonth();t._a[Yt]=n.getUTCDate()}for(e=0;e<3&&t._a[e]==null;++e){t._a[e]=i[e]=r[e]}for(;e<7;e++){t._a[e]=i[e]=t._a[e]==null?e===2?1:0:t._a[e]}if(t._a[zt]===24&&t._a[Vt]===0&&t._a[Et]===0&&t._a[Ht]===0){t._nextDay=true;t._a[zt]=0}t._d=(t._useUTC?be:ye).apply(null,i);a=t._useUTC?t._d.getUTCDay():t._d.getDay();if(t._tzm!=null){t._d.setUTCMinutes(t._d.getUTCMinutes()-t._tzm)}if(t._nextDay){t._a[zt]=24}if(t._w&&typeof t._w.d!=="undefined"&&t._w.d!==a){m(t).weekdayMismatch=true}}function wn(t){var e,n,i,r,a,o,s,l;e=t._w;if(e.GG!=null||e.W!=null||e.E!=null){a=1;o=4;n=bn(e.GG,t._a[Nt],we(qn(),1,4).year);i=bn(e.W,1);r=bn(e.E,1);if(r<1||r>7){l=true}}else{a=t._locale._week.dow;o=t._locale._week.doy;var u=we(qn(),a,o);n=bn(e.gg,t._a[Nt],u.year);i=bn(e.w,u.week);if(e.d!=null){r=e.d;if(r<0||r>6){l=true}}else if(e.e!=null){r=e.e+a;if(e.e<0||e.e>6){l=true}}else{r=a}}if(i<1||i>ke(n,a,o)){m(t)._overflowWeeks=true}else if(l!=null){m(t)._overflowWeekday=true}else{s=_e(n,i,r,a,o);t._a[Nt]=s.year;t._dayOfYear=s.dayOfYear}}var kn=/^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,Mn=/^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,Sn=/Z|[+-]\d\d(?::?\d\d)?/,Dn=[["YYYYYY-MM-DD",/[+-]\d{6}-\d\d-\d\d/],["YYYY-MM-DD",/\d{4}-\d\d-\d\d/],["GGGG-[W]WW-E",/\d{4}-W\d\d-\d/],["GGGG-[W]WW",/\d{4}-W\d\d/,false],["YYYY-DDD",/\d{4}-\d{3}/],["YYYY-MM",/\d{4}-\d\d/,false],["YYYYYYMMDD",/[+-]\d{10}/],["YYYYMMDD",/\d{8}/],["GGGG[W]WWE",/\d{4}W\d{3}/],["GGGG[W]WW",/\d{4}W\d{2}/,false],["YYYYDDD",/\d{7}/]],Cn=[["HH:mm:ss.SSSS",/\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss,SSSS",/\d\d:\d\d:\d\d,\d+/],["HH:mm:ss",/\d\d:\d\d:\d\d/],["HH:mm",/\d\d:\d\d/],["HHmmss.SSSS",/\d\d\d\d\d\d\.\d+/],["HHmmss,SSSS",/\d\d\d\d\d\d,\d+/],["HHmmss",/\d\d\d\d\d\d/],["HHmm",/\d\d\d\d/],["HH",/\d\d/]],Pn=/^\/?Date\((\-?\d+)/i;function Tn(t){var e,n,i=t._i,r=kn.exec(i)||Mn.exec(i),a,o,s,l;if(r){m(t).iso=true;for(e=0,n=Dn.length;e<n;e++){if(Dn[e][1].exec(r[1])){o=Dn[e][0];a=Dn[e][2]!==false;break}}if(o==null){t._isValid=false;return}if(r[3]){for(e=0,n=Cn.length;e<n;e++){if(Cn[e][1].exec(r[3])){s=(r[2]||" ")+Cn[e][0];break}}if(s==null){t._isValid=false;return}}if(!a&&s!=null){t._isValid=false;return}if(r[4]){if(Sn.exec(r[4])){l="Z"}else{t._isValid=false;return}}t._f=o+(s||"")+(l||"");zn(t)}else{t._isValid=false}}var On=/^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|([+-]\d{4}))$/;function An(t,e,n,i,r,a){var o=[Fn(t),oe.indexOf(e),parseInt(n,10),parseInt(i,10),parseInt(r,10)];if(a){o.push(parseInt(a,10))}return o}function Fn(t){var e=parseInt(t,10);if(e<=49){return 2e3+e}else if(e<=999){return 1900+e}return e}function In(t){return t.replace(/\([^)]*\)|[\n\t]/g," ").replace(/(\s\s+)/g," ").replace(/^\s\s*/,"").replace(/\s\s*$/,"")}function Ln(t,e,n){if(t){var i=Re.indexOf(t),r=new Date(e[0],e[1],e[2]).getDay();if(i!==r){m(n).weekdayMismatch=true;n._isValid=false;return false}}return true}var Rn={UT:0,GMT:0,EDT:-4*60,EST:-5*60,CDT:-5*60,CST:-6*60,MDT:-6*60,MST:-7*60,PDT:-7*60,PST:-8*60};function Nn(t,e,n){if(t){return Rn[t]}else if(e){return 0}else{var i=parseInt(n,10);var r=i%100,a=(i-r)/100;return a*60+r}}function Wn(t){var e=On.exec(In(t._i));if(e){var n=An(e[4],e[3],e[2],e[5],e[6],e[7]);if(!Ln(e[1],n,t)){return}t._a=n;t._tzm=Nn(e[8],e[9],e[10]);t._d=be.apply(null,t._a);t._d.setUTCMinutes(t._d.getUTCMinutes()-t._tzm);m(t).rfc2822=true}else{t._isValid=false}}function Yn(t){var e=Pn.exec(t._i);if(e!==null){t._d=new Date(+e[1]);return}Tn(t);if(t._isValid===false){delete t._isValid}else{return}Wn(t);if(t._isValid===false){delete t._isValid}else{return}u.createFromInputFallback(t)}function zn(t){if(t._f===u.ISO_8601){Tn(t);return}if(t._f===u.RFC_2822){Wn(t);return}t._a=[];m(t).empty=true;var e=""+t._i,n,i,r,a,o,s=e.length,l=0;r=ut(t._f,t._locale).match(et)||[];for(n=0;n<r.length;n++){a=r[n];i=(e.match(Tt(a,t))||[])[0];if(i){o=e.substr(0,e.indexOf(i));if(o.length>0){m(t).unusedInput.push(o)}e=e.slice(e.indexOf(i)+i.length);l+=i.length}if(rt[a]){if(i){m(t).empty=false}else{m(t).unusedTokens.push(a)}Rt(a,i,t)}else if(t._strict&&!i){m(t).unusedTokens.push(a)}}m(t).charsLeftOver=s-l;if(e.length>0){m(t).unusedInput.push(e)}if(t._a[zt]<=12&&m(t).bigHour===true&&t._a[zt]>0){m(t).bigHour=undefined}m(t).parsedDateParts=t._a.slice(0);m(t).meridiem=t._meridiem;t._a[zt]=Vn(t._locale,t._a[zt],t._meridiem);_n(t);yn(t)}function Vn(t,e,n){var i;if(n==null){return e}if(t.meridiemHour!=null){return t.meridiemHour(e,n)}else if(t.isPM!=null){i=t.isPM(n);if(i&&e<12){e+=12}if(!i&&e===12){e=0}return e}else{return e}}function En(t){var e,n,i,r,a;if(t._f.length===0){m(t).invalidFormat=true;t._d=new Date(NaN);return}for(r=0;r<t._f.length;r++){a=0;e=b({},t);if(t._useUTC!=null){e._useUTC=t._useUTC}e._f=t._f[r];zn(e);if(!p(e)){continue}a+=m(e).charsLeftOver;a+=m(e).unusedTokens.length*10;m(e).score=a;if(i==null||a<i){i=a;n=e}}f(t,n||e)}function Hn(t){if(t._d){return}var e=X(t._i);t._a=n([e.year,e.month,e.day||e.date,e.hour,e.minute,e.second,e.millisecond],function(t){return t&&parseInt(t,10)});_n(t)}function Bn(t){var e=new _(yn(jn(t)));if(e._nextDay){e.add(1,"d");e._nextDay=undefined}return e}function jn(t){var e=t._i,n=t._f;t._locale=t._locale||pn(t._l);if(e===null||n===undefined&&e===""){return v({nullInput:true})}if(typeof e==="string"){t._i=e=t._locale.preparse(e)}if(w(e)){return new _(yn(e))}else if(h(e)){t._d=e}else if(o(n)){En(t)}else if(n){zn(t)}else{Un(t)}if(!p(t)){t._d=null}return t}function Un(t){var e=t._i;if(a(e)){t._d=new Date(u.now())}else if(h(e)){t._d=new Date(e.valueOf())}else if(typeof e==="string"){Yn(t)}else if(o(e)){t._a=n(e.slice(0),function(t){return parseInt(t,10)});_n(t)}else if(s(e)){Hn(t)}else if(d(e)){t._d=new Date(e)}else{u.createFromInputFallback(t)}}function Gn(t,e,n,i,r){var a={};if(n===true||n===false){i=n;n=undefined}if(s(t)&&l(t)||o(t)&&t.length===0){t=undefined}a._isAMomentObject=true;a._useUTC=a._isUTC=r;a._l=n;a._i=t;a._f=e;a._strict=i;return Bn(a)}function qn(t,e,n,i){return Gn(t,e,n,i,false)}u.createFromInputFallback=C("value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), "+"which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are "+"discouraged and will be removed in an upcoming major release. Please refer to "+"http://momentjs.com/guides/#/warnings/js-date/ for more info.",function(t){t._d=new Date(t._i+(t._useUTC?" UTC":""))}),u.ISO_8601=function(){},u.RFC_2822=function(){};var Zn=C("moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/",function(){var t=qn.apply(null,arguments);if(this.isValid()&&t.isValid()){return t<this?this:t}else{return v()}}),$n=C("moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/",function(){var t=qn.apply(null,arguments);if(this.isValid()&&t.isValid()){return t>this?this:t}else{return v()}});function Xn(t,e){var n,i;if(e.length===1&&o(e[0])){e=e[0]}if(!e.length){return qn()}n=e[0];for(i=1;i<e.length;++i){if(!e[i].isValid()||e[i][t](n)){n=e[i]}}return n}function Kn(){var t;return Xn("isBefore",[].slice.call(arguments,0))}function Jn(){var t;return Xn("isAfter",[].slice.call(arguments,0))}var Qn=function(){return Date.now?Date.now():+new Date},ti=["year","quarter","month","week","day","hour","minute","second","millisecond"];function ei(t){for(var e in t){if(!(Zt.call(ti,e)!==-1&&(t[e]==null||!isNaN(t[e])))){return false}}var n=false;for(var i=0;i<ti.length;++i){if(t[ti[i]]){if(n){return false}if(parseFloat(t[ti[i]])!==M(t[ti[i]])){n=true}}}return true}function ni(){return this._isValid}function ii(){return Si(NaN)}function ri(t){var e=X(t),n=e.year||0,i=e.quarter||0,r=e.month||0,a=e.week||e.isoWeek||0,o=e.day||0,s=e.hour||0,l=e.minute||0,u=e.second||0,d=e.millisecond||0;this._isValid=ei(e);this._milliseconds=+d+u*1e3+l*6e4+s*1e3*60*60;this._days=+o+a*7;this._months=+r+i*3+n*12;this._data={};this._locale=pn();this._bubble()}function ai(t){return t instanceof ri}function oi(t){if(t<0){return Math.round(-1*t)*-1}else{return Math.round(t)}}function si(t,n){at(t,0,0,function(){var t=this.utcOffset();var e="+";if(t<0){t=-t;e="-"}return e+tt(~~(t/60),2)+n+tt(~~t%60,2)})}si("Z",":"),si("ZZ",""),Pt("Z",Mt),Pt("ZZ",Mt),It(["Z","ZZ"],function(t,e,n){n._useUTC=true;n._tzm=ui(Mt,t)});var li=/([\+\-]|\d\d)/gi;function ui(t,e){var n=(e||"").match(t);if(n===null){return null}var i=n[n.length-1]||[];var r=(i+"").match(li)||["-",0,0];var a=+(r[1]*60)+M(r[2]);return a===0?0:r[0]==="+"?a:-a}function di(t,e){var n,i;if(e._isUTC){n=e.clone();i=(w(t)||h(t)?t.valueOf():qn(t).valueOf())-n.valueOf();n._d.setTime(n._d.valueOf()+i);u.updateOffset(n,false);return n}else{return qn(t).local()}}function hi(t){return-Math.round(t._d.getTimezoneOffset()/15)*15}function ci(t,e,n){var i=this._offset||0,r;if(!this.isValid()){return t!=null?this:NaN}if(t!=null){if(typeof t==="string"){t=ui(Mt,t);if(t===null){return this}}else if(Math.abs(t)<16&&!n){t=t*60}if(!this._isUTC&&e){r=hi(this)}this._offset=t;this._isUTC=true;if(r!=null){this.add(r,"m")}if(i!==t){if(!e||this._changeInProgress){Oi(this,Si(t-i,"m"),1,false)}else if(!this._changeInProgress){this._changeInProgress=true;u.updateOffset(this,true);this._changeInProgress=null}}return this}else{return this._isUTC?i:hi(this)}}function fi(t,e){if(t!=null){if(typeof t!=="string"){t=-t}this.utcOffset(t,e);return this}else{return-this.utcOffset()}}function gi(t){return this.utcOffset(0,t)}function mi(t){if(this._isUTC){this.utcOffset(0,t);this._isUTC=false;if(t){this.subtract(hi(this),"m")}}return this}function pi(){if(this._tzm!=null){this.utcOffset(this._tzm,false,true)}else if(typeof this._i==="string"){var t=ui(kt,this._i);if(t!=null){this.utcOffset(t)}else{this.utcOffset(0,true)}}return this}function vi(t){if(!this.isValid()){return false}t=t?qn(t).utcOffset():0;return(this.utcOffset()-t)%60===0}function yi(){return this.utcOffset()>this.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()}function bi(){if(!a(this._isDSTShifted)){return this._isDSTShifted}var t={};b(t,this);t=jn(t);if(t._a){var e=t._isUTC?g(t._a):qn(t._a);this._isDSTShifted=this.isValid()&&S(t._a,e.toArray())>0}else{this._isDSTShifted=false}return this._isDSTShifted}function xi(){return this.isValid()?!this._isUTC:false}function _i(){return this.isValid()?this._isUTC:false}function wi(){return this.isValid()?this._isUTC&&this._offset===0:false}u.updateOffset=function(){};var ki=/^(\-|\+)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/,Mi=/^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/;function Si(t,e){var n=t,i=null,r,a,o;if(ai(t)){n={ms:t._milliseconds,d:t._days,M:t._months}}else if(d(t)){n={};if(e){n[e]=t}else{n.milliseconds=t}}else if(!!(i=ki.exec(t))){r=i[1]==="-"?-1:1;n={y:0,d:M(i[Yt])*r,h:M(i[zt])*r,m:M(i[Vt])*r,s:M(i[Et])*r,ms:M(oi(i[Ht]*1e3))*r}}else if(!!(i=Mi.exec(t))){r=i[1]==="-"?-1:1;n={y:Di(i[2],r),M:Di(i[3],r),w:Di(i[4],r),d:Di(i[5],r),h:Di(i[6],r),m:Di(i[7],r),s:Di(i[8],r)}}else if(n==null){n={}}else if(typeof n==="object"&&("from"in n||"to"in n)){o=Pi(qn(n.from),qn(n.to));n={};n.ms=o.milliseconds;n.M=o.months}a=new ri(n);if(ai(t)&&c(t,"_locale")){a._locale=t._locale}return a}function Di(t,e){var n=t&&parseFloat(t.replace(",","."));return(isNaN(n)?0:n)*e}function Ci(t,e){var n={};n.months=e.month()-t.month()+(e.year()-t.year())*12;if(t.clone().add(n.months,"M").isAfter(e)){--n.months}n.milliseconds=+e-+t.clone().add(n.months,"M");return n}function Pi(t,e){var n;if(!(t.isValid()&&e.isValid())){return{milliseconds:0,months:0}}e=di(e,t);if(t.isBefore(e)){n=Ci(t,e)}else{n=Ci(e,t);n.milliseconds=-n.milliseconds;n.months=-n.months}return n}function Ti(r,a){return function(t,e){var n,i;if(e!==null&&!isNaN(+e)){O(a,"moment()."+a+"(period, number) is deprecated. Please use moment()."+a+"(number, period). "+"See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info.");i=t;t=e;e=i}t=typeof t==="string"?+t:t;n=Si(t,e);Oi(this,n,r);return this}}function Oi(t,e,n,i){var r=e._milliseconds,a=oi(e._days),o=oi(e._months);if(!t.isValid()){return}i=i==null?true:i;if(o){de(t,Kt(t,"Month")+o*n)}if(a){Jt(t,"Date",Kt(t,"Date")+a*n)}if(r){t._d.setTime(t._d.valueOf()+r*n)}if(i){u.updateOffset(t,a||o)}}Si.fn=ri.prototype,Si.invalid=ii;var Ai=Ti(1,"add"),Fi=Ti(-1,"subtract");function Ii(t,e){var n=t.diff(e,"days",!0);return n<-6?"sameElse":n<-1?"lastWeek":n<0?"lastDay":n<1?"sameDay":n<2?"nextDay":n<7?"nextWeek":"sameElse"}function Li(t,e){var n=t||qn(),i=di(n,this).startOf("day"),r=u.calendarFormat(this,i)||"sameElse";var a=e&&(A(e[r])?e[r].call(this,n):e[r]);return this.format(a||this.localeData().calendar(r,this,qn(n)))}function Ri(){return new _(this)}function Ni(t,e){var n=w(t)?t:qn(t);if(!(this.isValid()&&n.isValid())){return false}e=$(e)||"millisecond";if(e==="millisecond"){return this.valueOf()>n.valueOf()}else{return n.valueOf()<this.clone().startOf(e).valueOf()}}function Wi(t,e){var n=w(t)?t:qn(t);if(!(this.isValid()&&n.isValid())){return false}e=$(e)||"millisecond";if(e==="millisecond"){return this.valueOf()<n.valueOf()}else{return this.clone().endOf(e).valueOf()<n.valueOf()}}function Yi(t,e,n,i){var r=w(t)?t:qn(t),a=w(e)?e:qn(e);if(!(this.isValid()&&r.isValid()&&a.isValid())){return false}i=i||"()";return(i[0]==="("?this.isAfter(r,n):!this.isBefore(r,n))&&(i[1]===")"?this.isBefore(a,n):!this.isAfter(a,n))}function zi(t,e){var n=w(t)?t:qn(t),i;if(!(this.isValid()&&n.isValid())){return false}e=$(e)||"millisecond";if(e==="millisecond"){return this.valueOf()===n.valueOf()}else{i=n.valueOf();return this.clone().startOf(e).valueOf()<=i&&i<=this.clone().endOf(e).valueOf()}}function Vi(t,e){return this.isSame(t,e)||this.isAfter(t,e)}function Ei(t,e){return this.isSame(t,e)||this.isBefore(t,e)}function Hi(t,e,n){var i,r,a;if(!this.isValid()){return NaN}i=di(t,this);if(!i.isValid()){return NaN}r=(i.utcOffset()-this.utcOffset())*6e4;e=$(e);switch(e){case"year":a=Bi(this,i)/12;break;case"month":a=Bi(this,i);break;case"quarter":a=Bi(this,i)/3;break;case"second":a=(this-i)/1e3;break;case"minute":a=(this-i)/6e4;break;case"hour":a=(this-i)/36e5;break;case"day":a=(this-i-r)/864e5;break;case"week":a=(this-i-r)/6048e5;break;default:a=this-i}return n?a:k(a)}function Bi(t,e){var n=(e.year()-t.year())*12+(e.month()-t.month()),i=t.clone().add(n,"months"),r,a;if(e-i<0){r=t.clone().add(n-1,"months");a=(e-i)/(i-r)}else{r=t.clone().add(n+1,"months");a=(e-i)/(r-i)}return-(n+a)||0}function ji(){return this.clone().locale("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")}function Ui(t){if(!this.isValid()){return null}var e=t!==true;var n=e?this.clone().utc():this;if(n.year()<0||n.year()>9999){return lt(n,e?"YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]":"YYYYYY-MM-DD[T]HH:mm:ss.SSSZ")}if(A(Date.prototype.toISOString)){if(e){return this.toDate().toISOString()}else{return new Date(this.valueOf()+this.utcOffset()*60*1e3).toISOString().replace("Z",lt(n,"Z"))}}return lt(n,e?"YYYY-MM-DD[T]HH:mm:ss.SSS[Z]":"YYYY-MM-DD[T]HH:mm:ss.SSSZ")}function Gi(){if(!this.isValid()){return"moment.invalid(/* "+this._i+" */)"}var t="moment";var e="";if(!this.isLocal()){t=this.utcOffset()===0?"moment.utc":"moment.parseZone";e="Z"}var n="["+t+'("]';var i=0<=this.year()&&this.year()<=9999?"YYYY":"YYYYYY";var r="-MM-DD[T]HH:mm:ss.SSS";var a=e+'[")]';return this.format(n+i+r+a)}function qi(t){if(!t){t=this.isUtc()?u.defaultFormatUtc:u.defaultFormat}var e=lt(this,t);return this.localeData().postformat(e)}function Zi(t,e){if(this.isValid()&&(w(t)&&t.isValid()||qn(t).isValid())){return Si({to:this,from:t}).locale(this.locale()).humanize(!e)}else{return this.localeData().invalidDate()}}function $i(t){return this.from(qn(),t)}function Xi(t,e){if(this.isValid()&&(w(t)&&t.isValid()||qn(t).isValid())){return Si({from:this,to:t}).locale(this.locale()).humanize(!e)}else{return this.localeData().invalidDate()}}function Ki(t){return this.to(qn(),t)}function Ji(t){var e;if(t===undefined){return this._locale._abbr}else{e=pn(t);if(e!=null){this._locale=e}return this}}u.defaultFormat="YYYY-MM-DDTHH:mm:ssZ",u.defaultFormatUtc="YYYY-MM-DDTHH:mm:ss[Z]";var Qi=C("moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.",function(t){if(t===undefined){return this.localeData()}else{return this.locale(t)}});function tr(){return this._locale}var er=1e3,nr=60*er,ir=60*nr,rr=(365*400+97)*24*ir;function ar(t,e){return(t%e+e)%e}function or(t,e,n){if(t<100&&t>=0){return new Date(t+400,e,n)-rr}else{return new Date(t,e,n).valueOf()}}function sr(t,e,n){if(t<100&&t>=0){return Date.UTC(t+400,e,n)-rr}else{return Date.UTC(t,e,n)}}function lr(t){var e;t=$(t);if(t===undefined||t==="millisecond"||!this.isValid()){return this}var n=this._isUTC?sr:or;switch(t){case"year":e=n(this.year(),0,1);break;case"quarter":e=n(this.year(),this.month()-this.month()%3,1);break;case"month":e=n(this.year(),this.month(),1);break;case"week":e=n(this.year(),this.month(),this.date()-this.weekday());break;case"isoWeek":e=n(this.year(),this.month(),this.date()-(this.isoWeekday()-1));break;case"day":case"date":e=n(this.year(),this.month(),this.date());break;case"hour":e=this._d.valueOf();e-=ar(e+(this._isUTC?0:this.utcOffset()*nr),ir);break;case"minute":e=this._d.valueOf();e-=ar(e,nr);break;case"second":e=this._d.valueOf();e-=ar(e,er);break}this._d.setTime(e);u.updateOffset(this,true);return this}function ur(t){var e;t=$(t);if(t===undefined||t==="millisecond"||!this.isValid()){return this}var n=this._isUTC?sr:or;switch(t){case"year":e=n(this.year()+1,0,1)-1;break;case"quarter":e=n(this.year(),this.month()-this.month()%3+3,1)-1;break;case"month":e=n(this.year(),this.month()+1,1)-1;break;case"week":e=n(this.year(),this.month(),this.date()-this.weekday()+7)-1;break;case"isoWeek":e=n(this.year(),this.month(),this.date()-(this.isoWeekday()-1)+7)-1;break;case"day":case"date":e=n(this.year(),this.month(),this.date()+1)-1;break;case"hour":e=this._d.valueOf();e+=ir-ar(e+(this._isUTC?0:this.utcOffset()*nr),ir)-1;break;case"minute":e=this._d.valueOf();e+=nr-ar(e,nr)-1;break;case"second":e=this._d.valueOf();e+=er-ar(e,er)-1;break}this._d.setTime(e);u.updateOffset(this,true);return this}function dr(){return this._d.valueOf()-(this._offset||0)*6e4}function hr(){return Math.floor(this.valueOf()/1e3)}function cr(){return new Date(this.valueOf())}function fr(){var t=this;return[t.year(),t.month(),t.date(),t.hour(),t.minute(),t.second(),t.millisecond()]}function gr(){var t=this;return{years:t.year(),months:t.month(),date:t.date(),hours:t.hours(),minutes:t.minutes(),seconds:t.seconds(),milliseconds:t.milliseconds()}}function mr(){return this.isValid()?this.toISOString():null}function pr(){return p(this)}function vr(){return f({},m(this))}function yr(){return m(this).overflow}function br(){return{input:this._i,format:this._f,locale:this._locale,isUTC:this._isUTC,strict:this._strict}}function xr(t,e){at(0,[t,t.length],0,e)}function _r(t){return Sr.call(this,t,this.week(),this.weekday(),this.localeData()._week.dow,this.localeData()._week.doy)}function wr(t){return Sr.call(this,t,this.isoWeek(),this.isoWeekday(),1,4)}function kr(){return ke(this.year(),1,4)}function Mr(){var t=this.localeData()._week;return ke(this.year(),t.dow,t.doy)}function Sr(t,e,n,i,r){var a;if(t==null){return we(this,i,r).year}else{a=ke(t,i,r);if(e>a){e=a}return Dr.call(this,t,e,n,i,r)}}function Dr(t,e,n,i,r){var a=_e(t,e,n,i,r),o=be(a.year,0,a.dayOfYear);this.year(o.getUTCFullYear());this.month(o.getUTCMonth());this.date(o.getUTCDate());return this}function Cr(t){return t==null?Math.ceil((this.month()+1)/3):this.month((t-1)*3+this.month()%3)}at(0,["gg",2],0,function(){return this.weekYear()%100}),at(0,["GG",2],0,function(){return this.isoWeekYear()%100}),xr("gggg","weekYear"),xr("ggggg","weekYear"),xr("GGGG","isoWeekYear"),xr("GGGGG","isoWeekYear"),Z("weekYear","gg"),Z("isoWeekYear","GG"),J("weekYear",1),J("isoWeekYear",1),Pt("G",wt),Pt("g",wt),Pt("GG",mt,ht),Pt("gg",mt,ht),Pt("GGGG",bt,ft),Pt("gggg",bt,ft),Pt("GGGGG",xt,gt),Pt("ggggg",xt,gt),Lt(["gggg","ggggg","GGGG","GGGGG"],function(t,e,n,i){e[i.substr(0,2)]=M(t)}),Lt(["gg","GG"],function(t,e,n,i){e[i]=u.parseTwoDigitYear(t)}),at("Q",0,"Qo","quarter"),Z("quarter","Q"),J("quarter",7),Pt("Q",dt),It("Q",function(t,e){e[Wt]=(M(t)-1)*3}),at("D",["DD",2],"Do","date"),Z("date","D"),J("date",9),Pt("D",mt),Pt("DD",mt,ht),Pt("Do",function(t,e){return t?e._dayOfMonthOrdinalParse||e._ordinalParse:e._dayOfMonthOrdinalParseLenient}),It(["D","DD"],Yt),It("Do",function(t,e){e[Yt]=M(t.match(mt)[0])});var Pr=Xt("Date",true);function Tr(t){var e=Math.round((this.clone().startOf("day")-this.clone().startOf("year"))/864e5)+1;return t==null?e:this.add(t-e,"d")}at("DDD",["DDDD",3],"DDDo","dayOfYear"),Z("dayOfYear","DDD"),J("dayOfYear",4),Pt("DDD",yt),Pt("DDDD",ct),It(["DDD","DDDD"],function(t,e,n){n._dayOfYear=M(t)}),at("m",["mm",2],0,"minute"),Z("minute","m"),J("minute",14),Pt("m",mt),Pt("mm",mt,ht),It(["m","mm"],Vt);var Or=Xt("Minutes",false);at("s",["ss",2],0,"second"),Z("second","s"),J("second",15),Pt("s",mt),Pt("ss",mt,ht),It(["s","ss"],Et);var Ar=Xt("Seconds",false),Fr;for(at("S",0,0,function(){return~~(this.millisecond()/100)}),at(0,["SS",2],0,function(){return~~(this.millisecond()/10)}),at(0,["SSS",3],0,"millisecond"),at(0,["SSSS",4],0,function(){return this.millisecond()*10}),at(0,["SSSSS",5],0,function(){return this.millisecond()*100}),at(0,["SSSSSS",6],0,function(){return this.millisecond()*1e3}),at(0,["SSSSSSS",7],0,function(){return this.millisecond()*1e4}),at(0,["SSSSSSSS",8],0,function(){return this.millisecond()*1e5}),at(0,["SSSSSSSSS",9],0,function(){return this.millisecond()*1e6}),Z("millisecond","ms"),J("millisecond",16),Pt("S",yt,dt),Pt("SS",yt,ht),Pt("SSS",yt,ct),Fr="SSSS";Fr.length<=9;Fr+="S"){Pt(Fr,_t)}function Ir(t,e){e[Ht]=M(("0."+t)*1e3)}for(Fr="S";Fr.length<=9;Fr+="S"){It(Fr,Ir)}var Lr=Xt("Milliseconds",false);function Rr(){return this._isUTC?"UTC":""}function Nr(){return this._isUTC?"Coordinated Universal Time":""}at("z",0,0,"zoneAbbr"),at("zz",0,0,"zoneName");var Wr=_.prototype;function Yr(t){return qn(1e3*t)}function zr(){return qn.apply(null,arguments).parseZone()}function Vr(t){return t}Wr.add=Ai,Wr.calendar=Li,Wr.clone=Ri,Wr.diff=Hi,Wr.endOf=ur,Wr.format=qi,Wr.from=Zi,Wr.fromNow=$i,Wr.to=Xi,Wr.toNow=Ki,Wr.get=Qt,Wr.invalidAt=yr,Wr.isAfter=Ni,Wr.isBefore=Wi,Wr.isBetween=Yi,Wr.isSame=zi,Wr.isSameOrAfter=Vi,Wr.isSameOrBefore=Ei,Wr.isValid=pr,Wr.lang=Qi,Wr.locale=Ji,Wr.localeData=tr,Wr.max=$n,Wr.min=Zn,Wr.parsingFlags=vr,Wr.set=te,Wr.startOf=lr,Wr.subtract=Fi,Wr.toArray=fr,Wr.toObject=gr,Wr.toDate=cr,Wr.toISOString=Ui,Wr.inspect=Gi,Wr.toJSON=mr,Wr.toString=ji,Wr.unix=hr,Wr.valueOf=dr,Wr.creationData=br,Wr.year=qt,Wr.isLeapYear=$t,Wr.weekYear=_r,Wr.isoWeekYear=wr,Wr.quarter=Wr.quarters=Cr,Wr.month=he,Wr.daysInMonth=ce,Wr.week=Wr.weeks=Pe,Wr.isoWeek=Wr.isoWeeks=Te,Wr.weeksInYear=Mr,Wr.isoWeeksInYear=kr,Wr.date=Pr,Wr.day=Wr.days=Ee,Wr.weekday=He,Wr.isoWeekday=Be,Wr.dayOfYear=Tr,Wr.hour=Wr.hours=an,Wr.minute=Wr.minutes=Or,Wr.second=Wr.seconds=Ar,Wr.millisecond=Wr.milliseconds=Lr,Wr.utcOffset=ci,Wr.utc=gi,Wr.local=mi,Wr.parseZone=pi,Wr.hasAlignedHourOffset=vi,Wr.isDST=yi,Wr.isLocal=xi,Wr.isUtcOffset=_i,Wr.isUtc=wi,Wr.isUTC=wi,Wr.zoneAbbr=Rr,Wr.zoneName=Nr,Wr.dates=C("dates accessor is deprecated. Use date instead.",Pr),Wr.months=C("months accessor is deprecated. Use month instead",he),Wr.years=C("years accessor is deprecated. Use year instead",qt),Wr.zone=C("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",fi),Wr.isDSTShifted=C("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",bi);var Er=L.prototype;function Hr(t,e,n,i){var r=pn();var a=g().set(i,e);return r[n](a,t)}function Br(t,e,n){if(d(t)){e=t;t=undefined}t=t||"";if(e!=null){return Hr(t,e,n,"month")}var i;var r=[];for(i=0;i<12;i++){r[i]=Hr(t,i,n,"month")}return r}function jr(t,e,n,i){if(typeof t==="boolean"){if(d(e)){n=e;e=undefined}e=e||""}else{e=t;n=e;t=false;if(d(e)){n=e;e=undefined}e=e||""}var r=pn(),a=t?r._week.dow:0;if(n!=null){return Hr(e,(n+a)%7,i,"day")}var o;var s=[];for(o=0;o<7;o++){s[o]=Hr(e,(o+a)%7,i,"day")}return s}function Ur(t,e){return Br(t,e,"months")}function Gr(t,e){return Br(t,e,"monthsShort")}function qr(t,e,n){return jr(t,e,n,"weekdays")}function Zr(t,e,n){return jr(t,e,n,"weekdaysShort")}function $r(t,e,n){return jr(t,e,n,"weekdaysMin")}Er.calendar=N,Er.longDateFormat=Y,Er.invalidDate=V,Er.ordinal=B,Er.preparse=Vr,Er.postformat=Vr,Er.relativeTime=U,Er.pastFuture=G,Er.set=F,Er.months=ae,Er.monthsShort=se,Er.monthsParse=ue,Er.monthsRegex=pe,Er.monthsShortRegex=ge,Er.week=Me,Er.firstDayOfYear=Ce,Er.firstDayOfWeek=De,Er.weekdays=Le,Er.weekdaysMin=Ye,Er.weekdaysShort=Ne,Er.weekdaysParse=Ve,Er.weekdaysRegex=Ue,Er.weekdaysShortRegex=qe,Er.weekdaysMinRegex=Xe,Er.isPM=nn,Er.meridiem=rn,fn("en",{dayOfMonthOrdinalParse:/\d{1,2}(th|st|nd|rd)/,ordinal:function(t){var e=t%10,n=M(t%100/10)===1?"th":e===1?"st":e===2?"nd":e===3?"rd":"th";return t+n}}),u.lang=C("moment.lang is deprecated. Use moment.locale instead.",fn),u.langData=C("moment.langData is deprecated. Use moment.localeData instead.",pn);var Xr=Math.abs;function Kr(){var t=this._data;return this._milliseconds=Xr(this._milliseconds),this._days=Xr(this._days),this._months=Xr(this._months),t.milliseconds=Xr(t.milliseconds),t.seconds=Xr(t.seconds),t.minutes=Xr(t.minutes),t.hours=Xr(t.hours),t.months=Xr(t.months),t.years=Xr(t.years),this}function Jr(t,e,n,i){var r=Si(e,n);t._milliseconds+=i*r._milliseconds;t._days+=i*r._days;t._months+=i*r._months;return t._bubble()}function Qr(t,e){return Jr(this,t,e,1)}function ta(t,e){return Jr(this,t,e,-1)}function ea(t){if(t<0){return Math.floor(t)}else{return Math.ceil(t)}}function na(){var t,e,n,i,r,a=this._milliseconds,o=this._days,s=this._months,l=this._data;if(!(0<=a&&0<=o&&0<=s||a<=0&&o<=0&&s<=0))a+=864e5*ea(ra(s)+o),s=o=0;return l.milliseconds=a%1e3,t=k(a/1e3),l.seconds=t%60,e=k(t/60),l.minutes=e%60,n=k(e/60),l.hours=n%24,o+=k(n/24),r=k(ia(o)),s+=r,o-=ea(ra(r)),i=k(s/12),s%=12,l.days=o,l.months=s,l.years=i,this}function ia(t){return t*4800/146097}function ra(t){return t*146097/4800}function aa(t){if(!this.isValid())return NaN;var e,n,i=this._milliseconds;if("month"===(t=$(t))||"quarter"===t||"year"===t)switch(e=this._days+i/864e5,n=this._months+ia(e),t){case"month":return n;case"quarter":return n/3;case"year":return n/12}else switch(e=this._days+Math.round(ra(this._months)),t){case"week":return e/7+i/6048e5;case"day":return e+i/864e5;case"hour":return 24*e+i/36e5;case"minute":return 1440*e+i/6e4;case"second":return 86400*e+i/1e3;case"millisecond":return Math.floor(864e5*e)+i;default:throw new Error("Unknown unit "+t)}}function oa(){return this.isValid()?this._milliseconds+864e5*this._days+this._months%12*2592e6+31536e6*M(this._months/12):NaN}function sa(t){return function(){return this.as(t)}}var la=sa("ms"),ua=sa("s"),da=sa("m"),ha=sa("h"),ca=sa("d"),fa=sa("w"),ga=sa("M"),ma=sa("Q"),pa=sa("y");function va(){return Si(this)}function ya(t){return t=$(t),this.isValid()?this[t+"s"]():NaN}function ba(t){return function(){return this.isValid()?this._data[t]:NaN}}var xa=ba("milliseconds"),_a=ba("seconds"),wa=ba("minutes"),ka=ba("hours"),Ma=ba("days"),Sa=ba("months"),Da=ba("years");function Ca(){return k(this.days()/7)}var Pa=Math.round,Ta={ss:44,s:45,m:45,h:22,d:26,M:11};function Oa(t,e,n,i,r){return r.relativeTime(e||1,!!n,t,i)}function Aa(t,e,n){var i=Si(t).abs(),r=Pa(i.as("s")),a=Pa(i.as("m")),o=Pa(i.as("h")),s=Pa(i.as("d")),l=Pa(i.as("M")),u=Pa(i.as("y")),d=(r<=Ta.ss?["s",r]:r<Ta.s&&["ss",r])||a<=1&&["m"]||a<Ta.m&&["mm",a]||o<=1&&["h"]||o<Ta.h&&["hh",o]||s<=1&&["d"]||s<Ta.d&&["dd",s]||l<=1&&["M"]||l<Ta.M&&["MM",l]||u<=1&&["y"]||["yy",u];return d[2]=e,d[3]=0<+t,d[4]=n,function(t,e,n,i,r){return r.relativeTime(e||1,!!n,t,i)}.apply(null,d)}function Fa(t){return void 0!==t?"function"==typeof t&&(Pa=t,!0):Pa}function Ia(t,e){if(void 0===Ta[t])return!1;if(void 0===e)return Ta[t];if(Ta[t]=e,"s"===t)Ta.ss=e-1;return!0}function La(t){if(!this.isValid())return this.localeData().invalidDate();var e=this.localeData(),n=function(t,e,n){var i=Si(t).abs(),r=Pa(i.as("s")),a=Pa(i.as("m")),o=Pa(i.as("h")),s=Pa(i.as("d")),l=Pa(i.as("M")),u=Pa(i.as("y")),d=(r<=Ta.ss?["s",r]:r<Ta.s&&["ss",r])||a<=1&&["m"]||a<Ta.m&&["mm",a]||o<=1&&["h"]||o<Ta.h&&["hh",o]||s<=1&&["d"]||s<Ta.d&&["dd",s]||l<=1&&["M"]||l<Ta.M&&["MM",l]||u<=1&&["y"]||["yy",u];return d[2]=e,d[3]=0<+t,d[4]=n,function(t,e,n,i,r){return r.relativeTime(e||1,!!n,t,i)}.apply(null,d)}(this,!t,e);if(t)n=e.pastFuture(+this,n);return e.postformat(n)}var Ra=Math.abs;function Na(t){return(t>0)-(t<0)||+t}function Wa(){if(!this.isValid()){return this.localeData().invalidDate()}var t=Ra(this._milliseconds)/1e3;var e=Ra(this._days);var n=Ra(this._months);var i,r,a;i=k(t/60);r=k(i/60);t%=60;i%=60;a=k(n/12);n%=12;var o=a;var s=n;var l=e;var u=r;var d=i;var h=t?t.toFixed(3).replace(/\.?0+$/,""):"";var c=this.asSeconds();if(!c){return"P0D"}var f=c<0?"-":"";var g=Na(this._months)!==Na(c)?"-":"";var m=Na(this._days)!==Na(c)?"-":"";var p=Na(this._milliseconds)!==Na(c)?"-":"";return f+"P"+(o?g+o+"Y":"")+(s?g+s+"M":"")+(l?m+l+"D":"")+(u||d||h?"T":"")+(u?p+u+"H":"")+(d?p+d+"M":"")+(h?p+h+"S":"")}var Ya=ri.prototype;return Ya.isValid=function(){return this._isValid},Ya.abs=function(){var t=this._data;return this._milliseconds=Xr(this._milliseconds),this._days=Xr(this._days),this._months=Xr(this._months),t.milliseconds=Xr(t.milliseconds),t.seconds=Xr(t.seconds),t.minutes=Xr(t.minutes),t.hours=Xr(t.hours),t.months=Xr(t.months),t.years=Xr(t.years),this},Ya.add=function(t,e){return Jr(this,t,e,1)},Ya.subtract=function(t,e){return Jr(this,t,e,-1)},Ya.as=function(t){if(!this.isValid())return NaN;var e,n,i=this._milliseconds;if("month"===(t=$(t))||"quarter"===t||"year"===t)switch(e=this._days+i/864e5,n=this._months+ia(e),t){case"month":return n;case"quarter":return n/3;case"year":return n/12}else switch(e=this._days+Math.round(ra(this._months)),t){case"week":return e/7+i/6048e5;case"day":return e+i/864e5;case"hour":return 24*e+i/36e5;case"minute":return 1440*e+i/6e4;case"second":return 86400*e+i/1e3;case"millisecond":return Math.floor(864e5*e)+i;default:throw new Error("Unknown unit "+t)}},Ya.asMilliseconds=la,Ya.asSeconds=ua,Ya.asMinutes=da,Ya.asHours=ha,Ya.asDays=ca,Ya.asWeeks=fa,Ya.asMonths=ga,Ya.asQuarters=ma,Ya.asYears=pa,Ya.valueOf=function(){return this.isValid()?this._milliseconds+864e5*this._days+this._months%12*2592e6+31536e6*M(this._months/12):NaN},Ya._bubble=function(){var t,e,n,i,r,a=this._milliseconds,o=this._days,s=this._months,l=this._data;0<=a&&0<=o&&0<=s||a<=0&&o<=0&&s<=0||(a+=864e5*ea(ra(s)+o),s=o=0);return l.milliseconds=a%1e3,t=k(a/1e3),l.seconds=t%60,e=k(t/60),l.minutes=e%60,n=k(e/60),l.hours=n%24,o+=k(n/24),r=k(ia(o)),s+=r,o-=ea(ra(r)),i=k(s/12),s%=12,l.days=o,l.months=s,l.years=i,this},Ya.clone=function(){return Si(this)},Ya.get=function(t){return t=$(t),this.isValid()?this[t+"s"]():NaN},Ya.milliseconds=xa,Ya.seconds=_a,Ya.minutes=wa,Ya.hours=ka,Ya.days=Ma,Ya.weeks=function(){return k(this.days()/7)},Ya.months=Sa,Ya.years=Da,Ya.humanize=function(t){if(!this.isValid())return this.localeData().invalidDate();var e=this.localeData(),n=function(t,e,n){var i=Si(t).abs(),r=Pa(i.as("s")),a=Pa(i.as("m")),o=Pa(i.as("h")),s=Pa(i.as("d")),l=Pa(i.as("M")),u=Pa(i.as("y")),d=(r<=Ta.ss?["s",r]:r<Ta.s&&["ss",r])||a<=1&&["m"]||a<Ta.m&&["mm",a]||o<=1&&["h"]||o<Ta.h&&["hh",o]||s<=1&&["d"]||s<Ta.d&&["dd",s]||l<=1&&["M"]||l<Ta.M&&["MM",l]||u<=1&&["y"]||["yy",u];return d[2]=e,d[3]=0<+t,d[4]=n,function(t,e,n,i,r){return r.relativeTime(e||1,!!n,t,i)}.apply(null,d)}(this,!t,e);t&&(n=e.pastFuture(+this,n));return e.postformat(n)},Ya.toISOString=Wa,Ya.toString=Wa,Ya.toJSON=Wa,Ya.locale=Ji,Ya.localeData=tr,Ya.toIsoString=C("toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)",Wa),Ya.lang=Qi,at("X",0,0,"unix"),at("x",0,0,"valueOf"),Pt("x",wt),Pt("X",/[+-]?\d+(\.\d{1,3})?/),It("X",function(t,e,n){n._d=new Date(1e3*parseFloat(t,10))}),It("x",function(t,e,n){n._d=new Date(M(t))}),u.version="2.24.0",function(t){e=t}(qn),u.fn=Wr,u.min=function(){return Xn("isBefore",[].slice.call(arguments,0))},u.max=function(){return Xn("isAfter",[].slice.call(arguments,0))},u.now=function(){return Date.now?Date.now():+new Date},u.utc=g,u.unix=function(t){return qn(1e3*t)},u.months=function(t,e){return Br(t,e,"months")},u.isDate=h,u.locale=fn,u.invalid=v,u.duration=Si,u.isMoment=w,u.weekdays=function(t,e,n){return jr(t,e,n,"weekdays")},u.parseZone=function(){return qn.apply(null,arguments).parseZone()},u.localeData=pn,u.isDuration=ai,u.monthsShort=function(t,e){return Br(t,e,"monthsShort")},u.weekdaysMin=function(t,e,n){return jr(t,e,n,"weekdaysMin")},u.defineLocale=gn,u.updateLocale=function(t,e){{var n,i,r;null!=e?(r=on,null!=(i=cn(t))&&(r=i._config),e=I(r,e),(n=new L(e)).parentLocale=sn[t],sn[t]=n,fn(t)):null!=sn[t]&&(null!=sn[t].parentLocale?sn[t]=sn[t].parentLocale:null!=sn[t]&&delete sn[t])}return sn[t]},u.locales=function(){return T(sn)},u.weekdaysShort=function(t,e,n){return jr(t,e,n,"weekdaysShort")},u.normalizeUnits=$,u.relativeTimeRounding=function(t){return void 0!==t?"function"==typeof t&&(Pa=t,!0):Pa},u.relativeTimeThreshold=function(t,e){if(void 0===Ta[t])return!1;if(void 0===e)return Ta[t];Ta[t]=e,"s"===t&&(Ta.ss=e-1);return!0},u.calendarFormat=function(t,e){var n=t.diff(e,"days",!0);return n<-6?"sameElse":n<-1?"lastWeek":n<0?"lastDay":n<1?"sameDay":n<2?"nextDay":n<7?"nextWeek":"sameElse"},u.prototype=Wr,u.HTML5_FMT={DATETIME_LOCAL:"YYYY-MM-DDTHH:mm",DATETIME_LOCAL_SECONDS:"YYYY-MM-DDTHH:mm:ss",DATETIME_LOCAL_MS:"YYYY-MM-DDTHH:mm:ss.SSS",DATE:"YYYY-MM-DD",TIME:"HH:mm",TIME_SECONDS:"HH:mm:ss",TIME_MS:"HH:mm:ss.SSS",WEEK:"GGGG-[W]WW",MONTH:"YYYY-MM"},u}()}),ri={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"};Qe._date.override("function"==typeof ii?{_id:"moment",formats:function(){return ri},parse:function(t,e){return"string"==typeof t&&"string"==typeof e?t=ii(t,e):t instanceof ii||(t=ii(t)),t.isValid()?t.valueOf():null},format:function(t,e){return ii(t).format(e)},add:function(t,e,n){return ii(t).add(e,n).valueOf()},diff:function(t,e,n){return ii(t).diff(ii(e),n)},startOf:function(t,e,n){return t=ii(t),"isoWeek"===e?t.isoWeekday(n).valueOf():t.startOf(e).valueOf()},endOf:function(t,e){return ii(t).endOf(e).valueOf()},_create:function(t){return ii(t)}}:{}),Y._set("global",{plugins:{filler:{propagate:!0}}});var ai={dataset:function(t){var e=t.fill,n=t.chart,i=n.getDatasetMeta(e),r=i&&n.isDatasetVisible(e)&&i.dataset._children||[],a=r.length||0;return a?function(t,e){return e<a&&r[e]._view||null}:null},boundary:function(t){var n=t.boundary,e=n?n.x:null,i=n?n.y:null;return B.isArray(n)?function(t,e){return n[e]}:function(t){return{x:null===e?t.x:e,y:null===i?t.y:i}}}};function oi(t){return((t.el._scale||{}).getPointPositionForValue?function(t){var e,n,i,r,a,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),r=0;r<l;++r)a="start"===u||"end"===u?o.getPointPositionForValue(r,"start"===u?e:n):o.getBasePosition(r),s.gridLines.circular&&(a.cx=i.x,a.cy=i.y,a.angle=o.getIndexAngle(r)-Math.PI/2),d.push(a);return d}:function(t){var e,n=t.el._model||{},i=t.el._scale||{},r=t.fill,a=null;if(isFinite(r))return null;if("start"===r?a=void 0===n.scaleBottom?i.bottom:n.scaleBottom:"end"===r?a=void 0===n.scaleTop?i.top:n.scaleTop:void 0!==n.scaleZero?a=n.scaleZero:i.getBasePixel&&(a=i.getBasePixel()),null!=a){if(void 0!==a.x&&void 0!==a.y)return a;if(B.isFinite(a))return{x:(e=i.isHorizontal())?a:null,y:e?null:a}}return null})(t)}function si(t){return t&&!t.skip}function li(t,e,n,i,r){var a,o,s,l;if(i&&r){for(t.moveTo(e[0].x,e[0].y),a=1;a<i;++a)B.canvas.lineTo(t,e[a-1],e[a]);if(void 0===n[0].angle)for(t.lineTo(n[r-1].x,n[r-1].y),a=r-1;0<a;--a)B.canvas.lineTo(t,n[a],n[a-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)),a=r-1;0<a;--a)t.arc(o,s,l,n[a].angle,n[a-1].angle,!0)}}var ui={id:"filler",afterDatasetsUpdate:function(t,e){for(var n,i,r,a,o,s,l=(t.data.datasets||[]).length,u=e.propagate,d=[],h=0;h<l;++h)r=null,(i=(n=t.getDatasetMeta(h)).dataset)&&i._model&&i instanceof wt.Line&&(r={visible:t.isDatasetVisible(h),fill:function(t,e,n){var i,r=t._model||{},a=r.fill;if(void 0===a&&(a=!!r.backgroundColor),!1===a||null===a)return!1;if(!0===a)return"origin";if(i=parseFloat(a,10),isFinite(i)&&Math.floor(i)===i)return"-"!==a[0]&&"+"!==a[0]||(i=e+i),!(i===e||i<0||n<=i)&&i;switch(a){case"bottom":return"start";case"top":return"end";case"zero":return"origin";case"origin":case"start":case"end":return a;default:return!1}}(i,h,l),chart:t,el:i}),n.$filler=r,d.push(r);for(h=0;h<l;++h)(r=d[h])&&(r.fill=function(t,e,n){var i,r=t[e].fill,a=[e];if(!n)return r;for(;!1!==r&&-1===a.indexOf(r);){if(!isFinite(r))return r;if(!(i=t[r]))return!1;if(i.visible)return r;a.push(r),r=i.fill}return!1}(d,h,u),r.boundary=oi(r),r.mapper=(s=void 0,o=(a=r).fill,!(s="dataset")===o?null:(isFinite(o)||(s="boundary"),ai[s](a))))},beforeDatasetsDraw:function(t){for(var e,n,i,r,a,o,s=t._getSortedVisibleDatasetMetas(),l=t.ctx,u=s.length-1;0<=u;--u)(e=s[u].$filler)&&e.visible&&(i=(n=e.el)._view,r=n._children||[],a=e.mapper,o=i.backgroundColor||Y.global.defaultColor,a&&o&&r.length&&(B.canvas.clipArea(l,t.chartArea),function(t,e,n,i,r,a){var o,s,l,u,d,h,c,f,g=e.length,m=i.spanGaps,p=[],v=[],y=0,b=0;for(t.beginPath(),o=0,s=g;o<s;++o)d=n(u=e[l=o%g]._view,l,i),h=si(u),c=si(d),a&&void 0===f&&h&&(s=g+(f=o+1)),h&&c?(y=p.push(u),b=v.push(d)):y&&b&&(m?(h&&p.push(u),c&&v.push(d)):(li(t,p,v,y,b),y=b=0,p=[],v=[]));li(t,p,v,y,b),t.closePath(),t.fillStyle=r,t.fill()}(l,r,a,i,o,n._loop),B.canvas.unclipArea(l)))}},di=B.rtl.getRtlAdapter,hi=B.noop,ci=B.valueOrDefault;function fi(t,e){return t.usePointStyle&&t.boxWidth>e?e:t.boxWidth}Y._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,r=i.getDatasetMeta(n);r.hidden=null===r.hidden?!i.data.datasets[n].hidden:null,i.update()},onHover:null,onLeave:null,labels:{boxWidth:40,padding:10,generateLabels:function(n){var i=n.data.datasets,t=n.options.legend||{},r=t.labels&&t.labels.usePointStyle;return n._getSortedDatasetMetas().map(function(t){var e=t.controller.getStyle(r?0:void 0);return{text:i[t.index].label,fillStyle:e.backgroundColor,hidden:!n.isDatasetVisible(t.index),lineCap:e.borderCapStyle,lineDash:e.borderDash,lineDashOffset:e.borderDashOffset,lineJoin:e.borderJoinStyle,lineWidth:e.borderWidth,strokeStyle:e.borderColor,pointStyle:e.pointStyle,rotation:e.rotation,datasetIndex:t.index}},this)}}},legendCallback:function(t){var e,n,i,r=document.createElement("ul"),a=t.data.datasets;for(r.setAttribute("class",t.id+"-legend"),e=0,n=a.length;e<n;e++)(i=r.appendChild(document.createElement("li"))).appendChild(document.createElement("span")).style.backgroundColor=a[e].backgroundColor,a[e].label&&i.appendChild(document.createTextNode(a[e].label));return r.outerHTML}});var gi=$.extend({initialize:function(t){B.extend(this,t),this.legendHitBoxes=[],this._hoveredItem=null,this.doughnutMode=!1},beforeUpdate:hi,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:hi,beforeSetDimensions:hi,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:hi,beforeBuildLabels:hi,buildLabels:function(){var e=this,n=e.options.labels||{},t=B.callback(n.generateLabels,[e.chart],e)||[];n.filter&&(t=t.filter(function(t){return n.filter(t,e.chart.data)})),e.options.reverse&&t.reverse(),e.legendItems=t},afterBuildLabels:hi,beforeFit:hi,fit:function(){var i,r,a,o,s,l,u,d,t=this,e=t.options,h=e.labels,n=e.display,c=t.ctx,f=B.options._parseFont(h),g=f.size,m=t.legendHitBoxes=[],p=t.minSize,v=t.isHorizontal();v?(p.width=t.maxWidth,p.height=n?10:0):(p.width=n?10:0,p.height=t.maxHeight),n?(c.font=f.string,v?(i=t.lineWidths=[0],r=0,c.textAlign="left",c.textBaseline="middle",B.each(t.legendItems,function(t,e){var n=fi(h,g)+g/2+c.measureText(t.text).width;(0===e||i[i.length-1]+n+2*h.padding>p.width)&&(r+=g+h.padding,i[i.length-(0<e?0:1)]=0),m[e]={left:0,top:0,width:n,height:g},i[i.length-1]+=n+h.padding}),p.height+=r):(a=h.padding,o=t.columnWidths=[],s=t.columnHeights=[],l=h.padding,d=u=0,B.each(t.legendItems,function(t,e){var n=fi(h,g)+g/2+c.measureText(t.text).width;0<e&&d+g+2*a>p.height&&(l+=u+h.padding,o.push(u),s.push(d),d=u=0),u=Math.max(u,n),d+=g+a,m[e]={left:0,top:0,width:n,height:g}}),l+=u,o.push(u),s.push(d),p.width+=l),t.width=p.width,t.height=p.height):t.width=p.width=t.height=p.height=0},afterFit:hi,isHorizontal:function(){return"top"===this.options.position||"bottom"===this.options.position},draw:function(){var _,w,t,e,k,M,S,D,C,P,T,O=this,n=O.options,A=n.labels,i=Y.global,F=i.defaultColor,I=i.elements.line,L=O.height,R=O.columnHeights,N=O.width,W=O.lineWidths;n.display&&(_=di(n.rtl,O.left,O.minSize.width),w=O.ctx,t=ci(A.fontColor,i.defaultFontColor),e=B.options._parseFont(A),k=e.size,w.textAlign=_.textAlign("left"),w.textBaseline="middle",w.lineWidth=.5,w.strokeStyle=t,w.fillStyle=t,w.font=e.string,M=fi(A,k),S=O.legendHitBoxes,D=function(t,e){switch(n.align){case"start":return A.padding;case"end":return t-e;default:return(t-e+A.padding)/2}},C=O.isHorizontal(),P=C?{x:O.left+D(N,W[0]),y:O.top+A.padding,line:0}:{x:O.left+A.padding,y:O.top+D(L,R[0]),line:0},B.rtl.overrideTextDirection(O.ctx,n.textDirection),T=k+A.padding,B.each(O.legendItems,function(t,e){var n=w.measureText(t.text).width,i=M+k/2+n,r=P.x,a=P.y;_.setWidth(O.minSize.width),C?0<e&&r+i+A.padding>O.left+O.minSize.width&&(a=P.y+=T,P.line++,r=P.x=O.left+D(N,W[P.line])):0<e&&a+T>O.top+O.minSize.height&&(r=P.x=r+O.columnWidths[P.line]+A.padding,P.line++,a=P.y=O.top+D(L,R[P.line]));var o,s,l,u,d,h,c,f,g,m,p,v,y,b,x=_.x(r);o=x,s=a,l=t,isNaN(M)||M<=0||(w.save(),u=ci(l.lineWidth,I.borderWidth),w.fillStyle=ci(l.fillStyle,F),w.lineCap=ci(l.lineCap,I.borderCapStyle),w.lineDashOffset=ci(l.lineDashOffset,I.borderDashOffset),w.lineJoin=ci(l.lineJoin,I.borderJoinStyle),w.lineWidth=u,w.strokeStyle=ci(l.strokeStyle,F),w.setLineDash&&w.setLineDash(ci(l.lineDash,I.borderDash)),A&&A.usePointStyle?(d=M*Math.SQRT2/2,h=_.xPlus(o,M/2),c=s+k/2,B.canvas.drawPoint(w,l.pointStyle,d,h,c,l.rotation)):(w.fillRect(_.leftForLtr(o,M),s,M,k),0!==u&&w.strokeRect(_.leftForLtr(o,M),s,M,k)),w.restore()),S[e].left=_.leftForLtr(x,S[e].width),S[e].top=a,f=x,g=a,m=t,p=n,v=k/2,y=_.xPlus(f,M+v),b=g+v,w.fillText(m.text,y,b),m.hidden&&(w.beginPath(),w.lineWidth=2,w.moveTo(y,b),w.lineTo(_.xPlus(y,p),b),w.stroke()),C?P.x+=i+A.padding:P.y+=T}),B.rtl.restoreTextDirection(O.ctx,n.textDirection))},_getLegendItemAt:function(t,e){var n,i,r;if(t>=this.left&&t<=this.right&&e>=this.top&&e<=this.bottom)for(r=this.legendHitBoxes,n=0;n<r.length;++n)if(t>=(i=r[n]).left&&t<=i.left+i.width&&e>=i.top&&e<=i.top+i.height)return this.legendItems[n];return null},handleEvent:function(t){var e,n=this.options,i="mouseup"===t.type?"click":t.type;if("mousemove"===i){if(!n.onHover&&!n.onLeave)return}else{if("click"!==i)return;if(!n.onClick)return}e=this._getLegendItemAt(t.x,t.y),"click"===i?e&&n.onClick&&n.onClick.call(this,t.native,e):(n.onLeave&&e!==this._hoveredItem&&(this._hoveredItem&&n.onLeave.call(this,t.native,this._hoveredItem),this._hoveredItem=e),n.onHover&&e&&n.onHover.call(this,t.native,e))}});function mi(t,e){var n=new gi({ctx:t.ctx,options:e,chart:t});he.configure(t,n,e),he.addBox(t,n),t.legend=n}var pi={id:"legend",_element:gi,beforeInit:function(t){var e=t.options.legend;e&&mi(t,e)},beforeUpdate:function(t){var e=t.options.legend,n=t.legend;e?(B.mergeIf(e,Y.global.legend),n?(he.configure(t,n,e),n.options=e):mi(t,e)):n&&(he.removeBox(t,n),delete t.legend)},afterEvent:function(t,e){var n=t.legend;n&&n.handleEvent(e)}},vi=B.noop;Y._set("global",{title:{display:!1,fontStyle:"bold",fullWidth:!0,padding:10,position:"top",text:"",weight:2e3}});var yi=$.extend({initialize:function(t){B.extend(this,t),this.legendHitBoxes=[]},beforeUpdate:vi,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:vi,beforeSetDimensions:vi,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:vi,beforeBuildLabels:vi,buildLabels:vi,afterBuildLabels:vi,beforeFit:vi,fit:function(){var t,e=this.options,n=this.minSize={},i=this.isHorizontal();e.display?(t=(B.isArray(e.text)?e.text.length:1)*B.options._parseFont(e).lineHeight+2*e.padding,this.width=n.width=i?this.maxWidth:t,this.height=n.height=i?t:this.maxHeight):this.width=n.width=this.height=n.height=0},afterFit:vi,isHorizontal:function(){var t=this.options.position;return"top"===t||"bottom"===t},draw:function(){var t=this.ctx,e=this.options;if(e.display){var n,i,r,a=B.options._parseFont(e),o=a.lineHeight,s=o/2+e.padding,l=0,u=this.top,d=this.left,h=this.bottom,c=this.right;t.fillStyle=B.valueOrDefault(e.fontColor,Y.global.defaultFontColor),t.font=a.string,this.isHorizontal()?(i=d+(c-d)/2,r=u+s,n=c-d):(i="left"===e.position?d+s:c-s,r=u+(h-u)/2,n=h-u,l=Math.PI*("left"===e.position?-.5:.5)),t.save(),t.translate(i,r),t.rotate(l),t.textAlign="center",t.textBaseline="middle";var f=e.text;if(B.isArray(f))for(var g=0,m=0;m<f.length;++m)t.fillText(f[m],0,g,n),g+=o;else t.fillText(f,0,0,n);t.restore()}}});function bi(t,e){var n=new yi({ctx:t.ctx,options:e,chart:t});he.configure(t,n,e),he.addBox(t,n),t.titleBlock=n}var xi={},_i=ui,wi=pi,ki={id:"title",_element:yi,beforeInit:function(t){var e=t.options.title;e&&bi(t,e)},beforeUpdate:function(t){var e=t.options.title,n=t.titleBlock;e?(B.mergeIf(e,Y.global.title),n?(he.configure(t,n,e),n.options=e):bi(t,e)):n&&(he.removeBox(t,n),delete t.titleBlock)}};function Mi(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 Si(t){return null!=t&&"none"!==t}function Di(t,e,n){var i=document.defaultView,r=B._getParentNode(t),a=i.getComputedStyle(t)[e],o=i.getComputedStyle(r)[e],s=Si(a),l=Si(o),u=Number.POSITIVE_INFINITY;return s||l?Math.min(s?Mi(a,t,n):u,l?Mi(o,r,n):u):"none"}for(var Ci in xi.filler=_i,xi.legend=wi,xi.title=ki,(Xe.helpers=B).where=function(t,e){if(B.isArray(t)&&Array.prototype.filter)return t.filter(e);var n=[];return B.each(t,function(t){e(t)&&n.push(t)}),n},B.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,r=t.length;i<r;++i)if(e.call(n,t[i],i,t))return i;return-1},B.findNextWhere=function(t,e,n){B.isNullOrUndef(n)&&(n=-1);for(var i=n+1;i<t.length;i++){var r=t[i];if(e(r))return r}},B.findPreviousWhere=function(t,e,n){B.isNullOrUndef(n)&&(n=t.length);for(var i=n-1;0<=i;i--){var r=t[i];if(e(r))return r}},B.isNumber=function(t){return!isNaN(parseFloat(t))&&isFinite(t)},B.almostEquals=function(t,e,n){return Math.abs(t-e)<n},B.almostWhole=function(t,e){var n=Math.round(t);return n-e<=t&&t<=n+e},B.max=function(t){return t.reduce(function(t,e){return isNaN(e)?t:Math.max(t,e)},Number.NEGATIVE_INFINITY)},B.min=function(t){return t.reduce(function(t,e){return isNaN(e)?t:Math.min(t,e)},Number.POSITIVE_INFINITY)},B.sign=Math.sign?function(t){return Math.sign(t)}:function(t){return 0===(t=+t)||isNaN(t)?t:0<t?1:-1},B.toRadians=function(t){return t*(Math.PI/180)},B.toDegrees=function(t){return t*(180/Math.PI)},B._decimalPlaces=function(t){if(B.isFinite(t)){for(var e=1,n=0;Math.round(t*e)/e!==t;)e*=10,n++;return n}},B.getAngleFromPoint=function(t,e){var n=e.x-t.x,i=e.y-t.y,r=Math.sqrt(n*n+i*i),a=Math.atan2(i,n);return a<-.5*Math.PI&&(a+=2*Math.PI),{angle:a,distance:r}},B.distanceBetweenPoints=function(t,e){return Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2))},B.aliasPixel=function(t){return t%2==0?0:.5},B._alignPixel=function(t,e,n){var i=t.currentDevicePixelRatio,r=n/2;return Math.round((e-r)*i)/i+r},B.splineCurve=function(t,e,n,i){var r=t.skip?e:t,a=e,o=n.skip?e:n,s=Math.sqrt(Math.pow(a.x-r.x,2)+Math.pow(a.y-r.y,2)),l=Math.sqrt(Math.pow(o.x-a.x,2)+Math.pow(o.y-a.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:a.x-h*(o.x-r.x),y:a.y-h*(o.y-r.y)},next:{x:a.x+c*(o.x-r.x),y:a.y+c*(o.y-r.y)}}},B.EPSILON=Number.EPSILON||1e-14,B.splineCurveMonotone=function(t){for(var e,n,i,r,a,o,s,l,u,d=(t||[]).map(function(t){return{model:t._model,deltaK:0,mK:0}}),h=d.length,c=0;c<h;++c){(e=d[c]).model.skip||(i=0<c?d[c-1]:null,(r=c<h-1?d[c+1]:null)&&!r.model.skip&&(n=r.model.x-e.model.x,e.deltaK=0!=n?(r.model.y-e.model.y)/n:0),!i||i.model.skip?e.mK=e.deltaK:!r||r.model.skip?e.mK=i.deltaK:this.sign(i.deltaK)!==this.sign(e.deltaK)?e.mK=0:e.mK=(i.deltaK+e.deltaK)/2)}for(c=0;c<h-1;++c)e=d[c],r=d[c+1],e.model.skip||r.model.skip||(B.almostEquals(e.deltaK,0,this.EPSILON)?e.mK=r.mK=0:(a=e.mK/e.deltaK,o=r.mK/e.deltaK,(l=Math.pow(a,2)+Math.pow(o,2))<=9||(s=3/Math.sqrt(l),e.mK=a*s*e.deltaK,r.mK=o*s*e.deltaK)));for(c=0;c<h;++c)(e=d[c]).model.skip||(i=0<c?d[c-1]:null,r=c<h-1?d[c+1]:null,i&&!i.model.skip&&(u=(e.model.x-i.model.x)/3,e.model.controlPointPreviousX=e.model.x-u,e.model.controlPointPreviousY=e.model.y-u*e.mK),r&&!r.model.skip&&(u=(r.model.x-e.model.x)/3,e.model.controlPointNextX=e.model.x+u,e.model.controlPointNextY=e.model.y+u*e.mK))},B.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]},B.previousItem=function(t,e,n){return n?e<=0?t[t.length-1]:t[e-1]:e<=0?t[0]:t[e-1]},B.niceNum=function(t,e){var n=Math.floor(B.log10(t)),i=t/Math.pow(10,n),r=e?i<1.5?1:i<3?2:i<7?5:10:i<=1?1:i<=2?2:i<=5?5:10;return r*Math.pow(10,n)},B.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)},B.getRelativePosition=function(t,e){var n=t.originalEvent||t,i=t.target||t.srcElement,r=i.getBoundingClientRect(),a=n.touches,o=a&&0<a.length?(f=a[0].clientX,a[0].clientY):(f=n.clientX,n.clientY),s=parseFloat(B.getStyle(i,"padding-left")),l=parseFloat(B.getStyle(i,"padding-top")),u=parseFloat(B.getStyle(i,"padding-right")),d=parseFloat(B.getStyle(i,"padding-bottom")),h=r.right-r.left-s-u,c=r.bottom-r.top-l-d,f=Math.round((f-r.left-s)/h*i.width/e.currentDevicePixelRatio);return{x:f,y:o=Math.round((o-r.top-l)/c*i.height/e.currentDevicePixelRatio)}},B.getConstraintWidth=function(t){return Di(t,"max-width","clientWidth")},B.getConstraintHeight=function(t){return Di(t,"max-height","clientHeight")},B._calculatePadding=function(t,e,n){return-1<(e=B.getStyle(t,e)).indexOf("%")?n*parseInt(e,10)/100:parseInt(e,10)},B._getParentNode=function(t){var e=t.parentNode;return e&&"[object ShadowRoot]"===e.toString()&&(e=e.host),e},B.getMaximumWidth=function(t){var e=B._getParentNode(t);if(!e)return t.clientWidth;var n=e.clientWidth,i=n-B._calculatePadding(e,"padding-left",n)-B._calculatePadding(e,"padding-right",n),r=B.getConstraintWidth(t);return isNaN(r)?i:Math.min(i,r)},B.getMaximumHeight=function(t){var e=B._getParentNode(t);if(!e)return t.clientHeight;var n=e.clientHeight,i=n-B._calculatePadding(e,"padding-top",n)-B._calculatePadding(e,"padding-bottom",n),r=B.getConstraintHeight(t);return isNaN(r)?i:Math.min(i,r)},B.getStyle=function(t,e){return t.currentStyle?t.currentStyle[e]:document.defaultView.getComputedStyle(t,null).getPropertyValue(e)},B.retinaScale=function(t,e){var n,i,r,a=t.currentDevicePixelRatio=e||"undefined"!=typeof window&&window.devicePixelRatio||1;1!==a&&(n=t.canvas,i=t.height,r=t.width,n.height=i*a,n.width=r*a,t.ctx.scale(a,a),n.style.height||n.style.width||(n.style.height=i+"px",n.style.width=r+"px"))},B.fontString=function(t,e,n){return e+" "+t+"px "+n},B.longestText=function(t,e,n,i){var r=(i=i||{}).data=i.data||{},a=i.garbageCollect=i.garbageCollect||[];i.font!==e&&(r=i.data={},a=i.garbageCollect=[],i.font=e),t.font=e;for(var o,s,l,u,d=0,h=n.length,c=0;c<h;c++)if(null!=(l=n[c])&&!0!==B.isArray(l))d=B.measureText(t,r,a,d,l);else if(B.isArray(l))for(o=0,s=l.length;o<s;o++)null==(u=l[o])||B.isArray(u)||(d=B.measureText(t,r,a,d,u));var f=a.length/2;if(f>n.length){for(c=0;c<f;c++)delete r[a[c]];a.splice(0,f)}return d},B.measureText=function(t,e,n,i,r){var a=e[r];return a||(a=e[r]=t.measureText(r).width,n.push(r)),i<a&&(i=a),i},B.numberOfLabelLines=function(t){var e=1;return B.each(t,function(t){B.isArray(t)&&t.length>e&&(e=t.length)}),e},B.color=w?function(t){return t instanceof CanvasGradient&&(t=Y.global.defaultColor),w(t)}:function(t){return console.error("Color.js not found!"),t},B.getHoverColor=function(t){return t instanceof CanvasPattern||t instanceof CanvasGradient?t:B.color(t).saturate(.5).darken(.1).rgbString()},Xe._adapters=Qe,Xe.Animation=K,Xe.animationService=J,Xe.controllers=$t,Xe.DatasetController=it,Xe.defaults=Y,Xe.Element=$,Xe.elements=wt,Xe.Interaction=ne,Xe.layouts=he,Xe.platform=Oe,Xe.plugins=Ae,Xe.Scale=mn,Xe.scaleService=Fe,Xe.Ticks=tn,Xe.Tooltip=He,Xe.helpers.each(ni,function(t,e){Xe.scaleService.registerScaleType(e,t,t._defaults)}),xi)xi.hasOwnProperty(Ci)&&Xe.plugins.register(xi[Ci]);Xe.platform.initialize();var Pi=Xe;return"undefined"!=typeof window&&(window.Chart=Xe),(Xe.Chart=Xe).Legend=xi.legend._element,Xe.Title=xi.title._element,Xe.pluginService=Xe.plugins,Xe.PluginBase=Xe.Element.extend({}),Xe.canvasHelpers=Xe.helpers.canvas,Xe.layoutService=Xe.layouts,Xe.LinearScaleBase=_n,Xe.helpers.each(["Bar","Bubble","Doughnut","Line","PolarArea","Radar","Scatter"],function(n){Xe[n]=function(t,e){return new Xe(t,Xe.helpers.merge(e||{},{type:n.charAt(0).toLowerCase()+n.slice(1)}))}}),Pi});
includes/admin/class-wp-statistics-admin-assets.php CHANGED
@@ -139,7 +139,7 @@ class Admin_Assets
139
 
140
  // Load Chart Js Library [ Load in <head> Tag ]
141
  if (Menus::in_plugin_page() || (in_array($screen_id, array('dashboard')) and !Option::get('disable_dashboard')) || (in_array($hook, array('post.php', 'edit.php', 'post-new.php')) and !Option::get('disable_editor'))) {
142
- wp_enqueue_script(self::$prefix . '-chart.js', self::url('chartjs/chart.bundle.min.js'), false, '2.9.4', false);
143
  }
144
 
145
  // Load Jquery VMap Js Library
139
 
140
  // Load Chart Js Library [ Load in <head> Tag ]
141
  if (Menus::in_plugin_page() || (in_array($screen_id, array('dashboard')) and !Option::get('disable_dashboard')) || (in_array($hook, array('post.php', 'edit.php', 'post-new.php')) and !Option::get('disable_editor'))) {
142
+ wp_enqueue_script(self::$prefix . '-chart.js', self::url('chartjs/chart.bundle.min.js'), false, '2.9.4.1', false);
143
  }
144
 
145
  // Load Jquery VMap Js Library
includes/class-wp-statistics-install.php CHANGED
@@ -114,17 +114,17 @@ class Install
114
  ID bigint(20) NOT NULL AUTO_INCREMENT,
115
  last_counter date NOT NULL,
116
  referred text NOT NULL,
117
- agent varchar(255) NOT NULL,
118
- platform varchar(255),
119
- version varchar(255),
120
- UAString varchar(255),
121
  ip varchar(60) NOT NULL,
122
  location varchar(10),
123
  user_id BIGINT(40) NOT NULL,
124
  hits int(11),
125
  honeypot int(11),
126
  PRIMARY KEY (ID),
127
- UNIQUE KEY date_ip_agent (last_counter,ip,agent(75),platform(75),version(75)),
128
  KEY agent (agent),
129
  KEY platform (platform),
130
  KEY version (version),
@@ -140,7 +140,7 @@ class Install
140
  CREATE TABLE " . DB::table('exclusions') . " (
141
  ID bigint(20) NOT NULL AUTO_INCREMENT,
142
  date date NOT NULL,
143
- reason varchar(255) DEFAULT NULL,
144
  count bigint(20) NOT NULL,
145
  PRIMARY KEY (ID),
146
  KEY date (date),
@@ -152,8 +152,8 @@ class Install
152
  $create_pages_table = ("
153
  CREATE TABLE " . DB::table('pages') . " (
154
  page_id BIGINT(20) NOT NULL AUTO_INCREMENT,
155
- uri varchar(255) NOT NULL,
156
- type varchar(255) NOT NULL,
157
  date date NOT NULL,
158
  count int(11) NOT NULL,
159
  id int(11) NOT NULL,
@@ -172,7 +172,7 @@ class Install
172
  ID bigint(20) NOT NULL AUTO_INCREMENT,
173
  category varchar(25) NOT NULL,
174
  page_id bigint(20) NOT NULL,
175
- uri varchar(255) NOT NULL,
176
  value bigint(20) NOT NULL,
177
  PRIMARY KEY (ID),
178
  KEY category (category),
@@ -187,8 +187,8 @@ class Install
187
  ID bigint(20) NOT NULL AUTO_INCREMENT,
188
  last_counter date NOT NULL,
189
  engine varchar(64) NOT NULL,
190
- host varchar(255),
191
- words varchar(255),
192
  visitor bigint(20),
193
  PRIMARY KEY (ID),
194
  KEY last_counter (last_counter),
114
  ID bigint(20) NOT NULL AUTO_INCREMENT,
115
  last_counter date NOT NULL,
116
  referred text NOT NULL,
117
+ agent varchar(180) NOT NULL,
118
+ platform varchar(180),
119
+ version varchar(180),
120
+ UAString varchar(190),
121
  ip varchar(60) NOT NULL,
122
  location varchar(10),
123
  user_id BIGINT(40) NOT NULL,
124
  hits int(11),
125
  honeypot int(11),
126
  PRIMARY KEY (ID),
127
+ UNIQUE KEY date_ip_agent (last_counter,ip,agent(50),platform(50),version(50)),
128
  KEY agent (agent),
129
  KEY platform (platform),
130
  KEY version (version),
140
  CREATE TABLE " . DB::table('exclusions') . " (
141
  ID bigint(20) NOT NULL AUTO_INCREMENT,
142
  date date NOT NULL,
143
+ reason varchar(180) DEFAULT NULL,
144
  count bigint(20) NOT NULL,
145
  PRIMARY KEY (ID),
146
  KEY date (date),
152
  $create_pages_table = ("
153
  CREATE TABLE " . DB::table('pages') . " (
154
  page_id BIGINT(20) NOT NULL AUTO_INCREMENT,
155
+ uri varchar(190) NOT NULL,
156
+ type varchar(180) NOT NULL,
157
  date date NOT NULL,
158
  count int(11) NOT NULL,
159
  id int(11) NOT NULL,
172
  ID bigint(20) NOT NULL AUTO_INCREMENT,
173
  category varchar(25) NOT NULL,
174
  page_id bigint(20) NOT NULL,
175
+ uri varchar(190) NOT NULL,
176
  value bigint(20) NOT NULL,
177
  PRIMARY KEY (ID),
178
  KEY category (category),
187
  ID bigint(20) NOT NULL AUTO_INCREMENT,
188
  last_counter date NOT NULL,
189
  engine varchar(64) NOT NULL,
190
+ host varchar(190),
191
+ words varchar(190),
192
  visitor bigint(20),
193
  PRIMARY KEY (ID),
194
  KEY last_counter (last_counter),
includes/class-wp-statistics-schedule.php CHANGED
@@ -83,17 +83,11 @@ class Schedule
83
  wp_schedule_event(time(), 'daily', 'wp_statistics_add_visit_hook');
84
  }
85
 
86
- // Add Optimize and repair Table Daily
87
- if (!wp_next_scheduled('wp_statistics_optimize_table')) {
88
- wp_schedule_event(time(), '4weeks', 'wp_statistics_optimize_table');
89
- }
90
-
91
  //After construct
92
  add_action('wp_statistics_add_visit_hook', array($this, 'add_visit_event'));
93
  add_action('wp_statistics_dbmaint_hook', array($this, 'dbmaint_event'));
94
  add_action('wp_statistics_dbmaint_visitor_hook', array($this, 'dbmaint_visitor_event'));
95
  add_action('wp_statistics_report_hook', array($this, 'send_report'));
96
- add_action('wp_statistics_optimize_table', array($this, 'optimize_table'));
97
  }
98
 
99
  }
@@ -221,18 +215,6 @@ class Schedule
221
  }
222
  }
223
 
224
- /**
225
- * Cron Daily Optimize Table
226
- */
227
- public function optimize_table()
228
- {
229
- $table_list = DB::table('all');
230
- foreach ($table_list as $key => $table_name) {
231
- DB::optimizeTable($table_name);
232
- DB::repairTable($table_name);
233
- }
234
- }
235
-
236
  }
237
 
238
  new Schedule;
83
  wp_schedule_event(time(), 'daily', 'wp_statistics_add_visit_hook');
84
  }
85
 
 
 
 
 
 
86
  //After construct
87
  add_action('wp_statistics_add_visit_hook', array($this, 'add_visit_event'));
88
  add_action('wp_statistics_dbmaint_hook', array($this, 'dbmaint_event'));
89
  add_action('wp_statistics_dbmaint_visitor_hook', array($this, 'dbmaint_visitor_event'));
90
  add_action('wp_statistics_report_hook', array($this, 'send_report'));
 
91
  }
92
 
93
  }
215
  }
216
  }
217
 
 
 
 
 
 
 
 
 
 
 
 
 
218
  }
219
 
220
  new Schedule;
includes/class-wp-statistics.php CHANGED
@@ -104,15 +104,21 @@ final class WP_Statistics
104
  */
105
  add_action('init', array($this, 'load_textdomain'));
106
 
107
- /**
108
- * Include Require File
109
- */
110
- $this->includes();
111
 
112
- /**
113
- * instantiate Plugin
114
- */
115
- $this->instantiate();
 
 
 
 
 
 
 
 
 
116
  }
117
 
118
  /**
@@ -276,8 +282,8 @@ final class WP_Statistics
276
  */
277
  public static function install($network_wide)
278
  {
279
- add_filter('wp_statistics_show_welcome_page', '__return_false', 1);
280
- remove_action( 'upgrader_process_complete', 'WP_Statistics_Welcome::do_welcome', 99 );
281
 
282
  require_once WP_STATISTICS_DIR . 'includes/class-wp-statistics-db.php';
283
  require_once WP_STATISTICS_DIR . 'includes/class-wp-statistics-install.php';
@@ -305,30 +311,13 @@ final class WP_Statistics
305
  */
306
  public function instantiate()
307
  {
308
-
309
- # Get Country Codes
310
  $this->container['country_codes'] = \WP_STATISTICS\Country::getList();
311
-
312
- # Get User Detail
313
- $this->container['user_id'] = \WP_STATISTICS\User::get_user_id();
314
-
315
- # Set Options
316
- $this->container['option'] = new \WP_STATISTICS\Option();
317
-
318
- # User IP
319
- $this->container['ip'] = \WP_STATISTICS\IP::getIP();
320
-
321
- # User Agent
322
- $this->container['agent'] = \WP_STATISTICS\UserAgent::getUserAgent();
323
-
324
- # User Online
325
- $this->container['users_online'] = new \WP_STATISTICS\UserOnline();
326
-
327
- # Visitor
328
- $this->container['visitor'] = new \WP_STATISTICS\Visitor();
329
-
330
- # Referer
331
- $this->container['referred'] = \WP_STATISTICS\Referred::get();
332
  }
333
 
334
  /**
@@ -353,7 +342,7 @@ final class WP_Statistics
353
 
354
  // Check User Has Any AddOns
355
  $activate_plugins = get_option('active_plugins');
356
- $user_has_addons = false;
357
  foreach ($addOns as $plugin) {
358
  if (in_array($plugin, $activate_plugins)) {
359
  $user_has_addons = true;
104
  */
105
  add_action('init', array($this, 'load_textdomain'));
106
 
107
+ try {
 
 
 
108
 
109
+ /**
110
+ * Include Require File
111
+ */
112
+ $this->includes();
113
+
114
+ /**
115
+ * instantiate Plugin
116
+ */
117
+ $this->instantiate();
118
+
119
+ } catch (Exception $e) {
120
+ self::log($e->getMessage());
121
+ }
122
  }
123
 
124
  /**
282
  */
283
  public static function install($network_wide)
284
  {
285
+ add_filter('wp_statistics_show_welcome_page', '__return_false', 99);
286
+ remove_action('upgrader_process_complete', 'WP_Statistics_Welcome::do_welcome', 99);
287
 
288
  require_once WP_STATISTICS_DIR . 'includes/class-wp-statistics-db.php';
289
  require_once WP_STATISTICS_DIR . 'includes/class-wp-statistics-install.php';
311
  */
312
  public function instantiate()
313
  {
 
 
314
  $this->container['country_codes'] = \WP_STATISTICS\Country::getList();
315
+ $this->container['user_id'] = \WP_STATISTICS\User::get_user_id();
316
+ $this->container['option'] = new \WP_STATISTICS\Option();
317
+ $this->container['ip'] = \WP_STATISTICS\IP::getIP();
318
+ $this->container['agent'] = \WP_STATISTICS\UserAgent::getUserAgent();
319
+ $this->container['users_online'] = new \WP_STATISTICS\UserOnline();
320
+ $this->container['visitor'] = new \WP_STATISTICS\Visitor();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
321
  }
322
 
323
  /**
342
 
343
  // Check User Has Any AddOns
344
  $activate_plugins = get_option('active_plugins');
345
+ $user_has_addons = false;
346
  foreach ($addOns as $plugin) {
347
  if (in_array($plugin, $activate_plugins)) {
348
  $user_has_addons = true;
includes/vendor/autoload.php CHANGED
@@ -4,4 +4,4 @@
4
 
5
  require_once __DIR__ . '/composer/autoload_real.php';
6
 
7
- return ComposerAutoloaderInit5206856c1ff72d9f8bb6c057422509c9::getLoader();
4
 
5
  require_once __DIR__ . '/composer/autoload_real.php';
6
 
7
+ return ComposerAutoloaderInit2ac516f03a394ec3d1721352b7f43359::getLoader();
includes/vendor/composer/InstalledVersions.php DELETED
@@ -1,281 +0,0 @@
1
- <?php
2
-
3
- namespace Composer;
4
-
5
- use Composer\Semver\VersionParser;
6
-
7
-
8
-
9
-
10
-
11
-
12
- class InstalledVersions
13
- {
14
- private static $installed = array (
15
- 'root' =>
16
- array (
17
- 'pretty_version' => 'dev-master',
18
- 'version' => 'dev-master',
19
- 'aliases' =>
20
- array (
21
- ),
22
- 'reference' => 'd50c2fc7f17ad7cce00ffe728c45b23c92ce02ca',
23
- 'name' => '__root__',
24
- ),
25
- 'versions' =>
26
- array (
27
- '__root__' =>
28
- array (
29
- 'pretty_version' => 'dev-master',
30
- 'version' => 'dev-master',
31
- 'aliases' =>
32
- array (
33
- ),
34
- 'reference' => 'd50c2fc7f17ad7cce00ffe728c45b23c92ce02ca',
35
- ),
36
- 'composer/ca-bundle' =>
37
- array (
38
- 'pretty_version' => '1.2.8',
39
- 'version' => '1.2.8.0',
40
- 'aliases' =>
41
- array (
42
- ),
43
- 'reference' => '8a7ecad675253e4654ea05505233285377405215',
44
- ),
45
- 'geoip2/geoip2' =>
46
- array (
47
- 'pretty_version' => 'v2.10.0',
48
- 'version' => '2.10.0.0',
49
- 'aliases' =>
50
- array (
51
- ),
52
- 'reference' => '419557cd21d9fe039721a83490701a58c8ce784a',
53
- ),
54
- 'jaybizzle/crawler-detect' =>
55
- array (
56
- 'pretty_version' => 'v1.2.102',
57
- 'version' => '1.2.102.0',
58
- 'aliases' =>
59
- array (
60
- ),
61
- 'reference' => '346cfd72d11bb41f15e82654e532dc55360612ac',
62
- ),
63
- 'maxmind-db/reader' =>
64
- array (
65
- 'pretty_version' => 'v1.8.0',
66
- 'version' => '1.8.0.0',
67
- 'aliases' =>
68
- array (
69
- ),
70
- 'reference' => 'b566d429ac9aec10594b0935be8ff38302f8d5c8',
71
- ),
72
- 'maxmind/web-service-common' =>
73
- array (
74
- 'pretty_version' => 'v0.8.1',
75
- 'version' => '0.8.1.0',
76
- 'aliases' =>
77
- array (
78
- ),
79
- 'reference' => '32f274051c543fc865e5a84d3a2c703913641ea8',
80
- ),
81
- 'psr/cache' =>
82
- array (
83
- 'pretty_version' => '1.0.1',
84
- 'version' => '1.0.1.0',
85
- 'aliases' =>
86
- array (
87
- ),
88
- 'reference' => 'd11b50ad223250cf17b86e38383413f5a6764bf8',
89
- ),
90
- 's1lentium/iptools' =>
91
- array (
92
- 'pretty_version' => 'v1.1.1',
93
- 'version' => '1.1.1.0',
94
- 'aliases' =>
95
- array (
96
- ),
97
- 'reference' => 'f6f8ab6132ca7443bd7cced1681f5066d725fd5f',
98
- ),
99
- 'whichbrowser/parser' =>
100
- array (
101
- 'pretty_version' => 'v2.0.42',
102
- 'version' => '2.0.42.0',
103
- 'aliases' =>
104
- array (
105
- ),
106
- 'reference' => '4899110cd2f87b01e04ced62dbb9dec541031dee',
107
- ),
108
- ),
109
- );
110
-
111
-
112
-
113
-
114
-
115
-
116
-
117
- public static function getInstalledPackages()
118
- {
119
- return array_keys(self::$installed['versions']);
120
- }
121
-
122
-
123
-
124
-
125
-
126
-
127
-
128
-
129
-
130
- public static function isInstalled($packageName)
131
- {
132
- return isset(self::$installed['versions'][$packageName]);
133
- }
134
-
135
-
136
-
137
-
138
-
139
-
140
-
141
-
142
-
143
-
144
-
145
-
146
-
147
-
148
- public static function satisfies(VersionParser $parser, $packageName, $constraint)
149
- {
150
- $constraint = $parser->parseConstraints($constraint);
151
- $provided = $parser->parseConstraints(self::getVersionRanges($packageName));
152
-
153
- return $provided->matches($constraint);
154
- }
155
-
156
-
157
-
158
-
159
-
160
-
161
-
162
-
163
-
164
-
165
- public static function getVersionRanges($packageName)
166
- {
167
- if (!isset(self::$installed['versions'][$packageName])) {
168
- throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
169
- }
170
-
171
- $ranges = array();
172
- if (isset(self::$installed['versions'][$packageName]['pretty_version'])) {
173
- $ranges[] = self::$installed['versions'][$packageName]['pretty_version'];
174
- }
175
- if (array_key_exists('aliases', self::$installed['versions'][$packageName])) {
176
- $ranges = array_merge($ranges, self::$installed['versions'][$packageName]['aliases']);
177
- }
178
- if (array_key_exists('replaced', self::$installed['versions'][$packageName])) {
179
- $ranges = array_merge($ranges, self::$installed['versions'][$packageName]['replaced']);
180
- }
181
- if (array_key_exists('provided', self::$installed['versions'][$packageName])) {
182
- $ranges = array_merge($ranges, self::$installed['versions'][$packageName]['provided']);
183
- }
184
-
185
- return implode(' || ', $ranges);
186
- }
187
-
188
-
189
-
190
-
191
-
192
- public static function getVersion($packageName)
193
- {
194
- if (!isset(self::$installed['versions'][$packageName])) {
195
- throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
196
- }
197
-
198
- if (!isset(self::$installed['versions'][$packageName]['version'])) {
199
- return null;
200
- }
201
-
202
- return self::$installed['versions'][$packageName]['version'];
203
- }
204
-
205
-
206
-
207
-
208
-
209
- public static function getPrettyVersion($packageName)
210
- {
211
- if (!isset(self::$installed['versions'][$packageName])) {
212
- throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
213
- }
214
-
215
- if (!isset(self::$installed['versions'][$packageName]['pretty_version'])) {
216
- return null;
217
- }
218
-
219
- return self::$installed['versions'][$packageName]['pretty_version'];
220
- }
221
-
222
-
223
-
224
-
225
-
226
- public static function getReference($packageName)
227
- {
228
- if (!isset(self::$installed['versions'][$packageName])) {
229
- throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
230
- }
231
-
232
- if (!isset(self::$installed['versions'][$packageName]['reference'])) {
233
- return null;
234
- }
235
-
236
- return self::$installed['versions'][$packageName]['reference'];
237
- }
238
-
239
-
240
-
241
-
242
-
243
- public static function getRootPackage()
244
- {
245
- return self::$installed['root'];
246
- }
247
-
248
-
249
-
250
-
251
-
252
-
253
-
254
- public static function getRawData()
255
- {
256
- return self::$installed;
257
- }
258
-
259
-
260
-
261
-
262
-
263
-
264
-
265
-
266
-
267
-
268
-
269
-
270
-
271
-
272
-
273
-
274
-
275
-
276
-
277
- public static function reload($data)
278
- {
279
- self::$installed = $data;
280
- }
281
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/vendor/composer/autoload_real.php CHANGED
@@ -2,7 +2,7 @@
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
- class ComposerAutoloaderInit5206856c1ff72d9f8bb6c057422509c9
6
  {
7
  private static $loader;
8
 
@@ -22,15 +22,15 @@ class ComposerAutoloaderInit5206856c1ff72d9f8bb6c057422509c9
22
  return self::$loader;
23
  }
24
 
25
- spl_autoload_register(array('ComposerAutoloaderInit5206856c1ff72d9f8bb6c057422509c9', 'loadClassLoader'), true, true);
26
  self::$loader = $loader = new \Composer\Autoload\ClassLoader();
27
- spl_autoload_unregister(array('ComposerAutoloaderInit5206856c1ff72d9f8bb6c057422509c9', 'loadClassLoader'));
28
 
29
  $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
30
  if ($useStaticLoader) {
31
  require_once __DIR__ . '/autoload_static.php';
32
 
33
- call_user_func(\Composer\Autoload\ComposerStaticInit5206856c1ff72d9f8bb6c057422509c9::getInitializer($loader));
34
  } else {
35
  $map = require __DIR__ . '/autoload_namespaces.php';
36
  foreach ($map as $namespace => $path) {
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
+ class ComposerAutoloaderInit2ac516f03a394ec3d1721352b7f43359
6
  {
7
  private static $loader;
8
 
22
  return self::$loader;
23
  }
24
 
25
+ spl_autoload_register(array('ComposerAutoloaderInit2ac516f03a394ec3d1721352b7f43359', 'loadClassLoader'), true, true);
26
  self::$loader = $loader = new \Composer\Autoload\ClassLoader();
27
+ spl_autoload_unregister(array('ComposerAutoloaderInit2ac516f03a394ec3d1721352b7f43359', 'loadClassLoader'));
28
 
29
  $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
30
  if ($useStaticLoader) {
31
  require_once __DIR__ . '/autoload_static.php';
32
 
33
+ call_user_func(\Composer\Autoload\ComposerStaticInit2ac516f03a394ec3d1721352b7f43359::getInitializer($loader));
34
  } else {
35
  $map = require __DIR__ . '/autoload_namespaces.php';
36
  foreach ($map as $namespace => $path) {
includes/vendor/composer/autoload_static.php CHANGED
@@ -4,7 +4,7 @@
4
 
5
  namespace Composer\Autoload;
6
 
7
- class ComposerStaticInit5206856c1ff72d9f8bb6c057422509c9
8
  {
9
  public static $prefixLengthsPsr4 = array (
10
  'W' =>
@@ -82,8 +82,8 @@ class ComposerStaticInit5206856c1ff72d9f8bb6c057422509c9
82
  public static function getInitializer(ClassLoader $loader)
83
  {
84
  return \Closure::bind(function () use ($loader) {
85
- $loader->prefixLengthsPsr4 = ComposerStaticInit5206856c1ff72d9f8bb6c057422509c9::$prefixLengthsPsr4;
86
- $loader->prefixDirsPsr4 = ComposerStaticInit5206856c1ff72d9f8bb6c057422509c9::$prefixDirsPsr4;
87
 
88
  }, null, ClassLoader::class);
89
  }
4
 
5
  namespace Composer\Autoload;
6
 
7
+ class ComposerStaticInit2ac516f03a394ec3d1721352b7f43359
8
  {
9
  public static $prefixLengthsPsr4 = array (
10
  'W' =>
82
  public static function getInitializer(ClassLoader $loader)
83
  {
84
  return \Closure::bind(function () use ($loader) {
85
+ $loader->prefixLengthsPsr4 = ComposerStaticInit2ac516f03a394ec3d1721352b7f43359::$prefixLengthsPsr4;
86
+ $loader->prefixDirsPsr4 = ComposerStaticInit2ac516f03a394ec3d1721352b7f43359::$prefixDirsPsr4;
87
 
88
  }, null, ClassLoader::class);
89
  }
includes/vendor/composer/installed.json CHANGED
@@ -191,30 +191,30 @@
191
  },
192
  {
193
  "name": "maxmind-db/reader",
194
- "version": "v1.8.0",
195
- "version_normalized": "1.8.0.0",
196
  "source": {
197
  "type": "git",
198
  "url": "https://github.com/maxmind/MaxMind-DB-Reader-php.git",
199
- "reference": "b566d429ac9aec10594b0935be8ff38302f8d5c8"
200
  },
201
  "dist": {
202
  "type": "zip",
203
- "url": "https://api.github.com/repos/maxmind/MaxMind-DB-Reader-php/zipball/b566d429ac9aec10594b0935be8ff38302f8d5c8",
204
- "reference": "b566d429ac9aec10594b0935be8ff38302f8d5c8",
205
  "shasum": ""
206
  },
207
  "require": {
208
- "php": ">=7.2"
209
  },
210
  "conflict": {
211
- "ext-maxminddb": "<1.8.0,>=2.0.0"
212
  },
213
  "require-dev": {
214
  "friendsofphp/php-cs-fixer": "2.*",
215
  "php-coveralls/php-coveralls": "^2.1",
216
- "phpunit/phpcov": ">=6.0.0",
217
- "phpunit/phpunit": ">=8.0.0,<10.0.0",
218
  "squizlabs/php_codesniffer": "3.*"
219
  },
220
  "suggest": {
@@ -222,7 +222,7 @@
222
  "ext-gmp": "bcmath or gmp is required for decoding larger integers with the pure PHP decoder",
223
  "ext-maxminddb": "A C-based database decoder that provides significantly faster lookups"
224
  },
225
- "time": "2020-10-01T17:30:21+00:00",
226
  "type": "library",
227
  "installation-source": "dist",
228
  "autoload": {
@@ -249,39 +249,35 @@
249
  "geoip2",
250
  "geolocation",
251
  "maxmind"
252
- ],
253
- "support": {
254
- "issues": "https://github.com/maxmind/MaxMind-DB-Reader-php/issues",
255
- "source": "https://github.com/maxmind/MaxMind-DB-Reader-php/tree/v1.8.0"
256
- }
257
  },
258
  {
259
  "name": "maxmind/web-service-common",
260
- "version": "v0.8.1",
261
- "version_normalized": "0.8.1.0",
262
  "source": {
263
  "type": "git",
264
  "url": "https://github.com/maxmind/web-service-common-php.git",
265
- "reference": "32f274051c543fc865e5a84d3a2c703913641ea8"
266
  },
267
  "dist": {
268
  "type": "zip",
269
- "url": "https://api.github.com/repos/maxmind/web-service-common-php/zipball/32f274051c543fc865e5a84d3a2c703913641ea8",
270
- "reference": "32f274051c543fc865e5a84d3a2c703913641ea8",
271
  "shasum": ""
272
  },
273
  "require": {
274
  "composer/ca-bundle": "^1.0.3",
275
  "ext-curl": "*",
276
  "ext-json": "*",
277
- "php": ">=7.2"
278
  },
279
  "require-dev": {
280
  "friendsofphp/php-cs-fixer": "2.*",
281
- "phpunit/phpunit": "^8.0 || ^9.0",
282
  "squizlabs/php_codesniffer": "3.*"
283
  },
284
- "time": "2020-11-02T17:00:53+00:00",
285
  "type": "library",
286
  "installation-source": "dist",
287
  "autoload": {
@@ -301,11 +297,7 @@
301
  }
302
  ],
303
  "description": "Internal MaxMind Web Service API",
304
- "homepage": "https://github.com/maxmind/web-service-common-php",
305
- "support": {
306
- "issues": "https://github.com/maxmind/web-service-common-php/issues",
307
- "source": "https://github.com/maxmind/web-service-common-php/tree/v0.8.1"
308
- }
309
  },
310
  {
311
  "name": "psr/cache",
@@ -410,17 +402,17 @@
410
  },
411
  {
412
  "name": "whichbrowser/parser",
413
- "version": "v2.0.42",
414
- "version_normalized": "2.0.42.0",
415
  "source": {
416
  "type": "git",
417
  "url": "https://github.com/WhichBrowser/Parser-PHP.git",
418
- "reference": "4899110cd2f87b01e04ced62dbb9dec541031dee"
419
  },
420
  "dist": {
421
  "type": "zip",
422
- "url": "https://api.github.com/repos/WhichBrowser/Parser-PHP/zipball/4899110cd2f87b01e04ced62dbb9dec541031dee",
423
- "reference": "4899110cd2f87b01e04ced62dbb9dec541031dee",
424
  "shasum": ""
425
  },
426
  "require": {
@@ -429,16 +421,16 @@
429
  },
430
  "require-dev": {
431
  "icomefromthenet/reverse-regex": "0.0.6.3",
432
- "phpunit/php-code-coverage": "^2.2 || ^3.0",
433
- "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0",
434
  "satooshi/php-coveralls": "^1.0",
435
  "squizlabs/php_codesniffer": "2.5.*",
436
- "symfony/yaml": "~2.8 || ~3.4 || ~4.2 || ~5.0"
437
  },
438
  "suggest": {
439
  "cache/array-adapter": "Allows testing of the caching functionality"
440
  },
441
- "time": "2020-02-12T10:54:23+00:00",
442
  "type": "library",
443
  "installation-source": "dist",
444
  "autoload": {
@@ -470,7 +462,7 @@
470
  ],
471
  "support": {
472
  "issues": "https://github.com/WhichBrowser/Parser-PHP/issues",
473
- "source": "https://github.com/WhichBrowser/Parser-PHP/tree/v2.0.42"
474
  }
475
  }
476
  ]
191
  },
192
  {
193
  "name": "maxmind-db/reader",
194
+ "version": "v1.6.0",
195
+ "version_normalized": "1.6.0.0",
196
  "source": {
197
  "type": "git",
198
  "url": "https://github.com/maxmind/MaxMind-DB-Reader-php.git",
199
+ "reference": "febd4920bf17c1da84cef58e56a8227dfb37fbe4"
200
  },
201
  "dist": {
202
  "type": "zip",
203
+ "url": "https://api.github.com/repos/maxmind/MaxMind-DB-Reader-php/zipball/febd4920bf17c1da84cef58e56a8227dfb37fbe4",
204
+ "reference": "febd4920bf17c1da84cef58e56a8227dfb37fbe4",
205
  "shasum": ""
206
  },
207
  "require": {
208
+ "php": ">=5.6"
209
  },
210
  "conflict": {
211
+ "ext-maxminddb": "<1.6.0,>=2.0.0"
212
  },
213
  "require-dev": {
214
  "friendsofphp/php-cs-fixer": "2.*",
215
  "php-coveralls/php-coveralls": "^2.1",
216
+ "phpunit/phpcov": "^3.0",
217
+ "phpunit/phpunit": "5.*",
218
  "squizlabs/php_codesniffer": "3.*"
219
  },
220
  "suggest": {
222
  "ext-gmp": "bcmath or gmp is required for decoding larger integers with the pure PHP decoder",
223
  "ext-maxminddb": "A C-based database decoder that provides significantly faster lookups"
224
  },
225
+ "time": "2019-12-19T22:59:03+00:00",
226
  "type": "library",
227
  "installation-source": "dist",
228
  "autoload": {
249
  "geoip2",
250
  "geolocation",
251
  "maxmind"
252
+ ]
 
 
 
 
253
  },
254
  {
255
  "name": "maxmind/web-service-common",
256
+ "version": "v0.7.0",
257
+ "version_normalized": "0.7.0.0",
258
  "source": {
259
  "type": "git",
260
  "url": "https://github.com/maxmind/web-service-common-php.git",
261
+ "reference": "74c996c218ada5c639c8c2f076756e059f5552fc"
262
  },
263
  "dist": {
264
  "type": "zip",
265
+ "url": "https://api.github.com/repos/maxmind/web-service-common-php/zipball/74c996c218ada5c639c8c2f076756e059f5552fc",
266
+ "reference": "74c996c218ada5c639c8c2f076756e059f5552fc",
267
  "shasum": ""
268
  },
269
  "require": {
270
  "composer/ca-bundle": "^1.0.3",
271
  "ext-curl": "*",
272
  "ext-json": "*",
273
+ "php": ">=5.6"
274
  },
275
  "require-dev": {
276
  "friendsofphp/php-cs-fixer": "2.*",
277
+ "phpunit/phpunit": "^4.8.36 || ^5.7 || ^6.5 || ^7.0",
278
  "squizlabs/php_codesniffer": "3.*"
279
  },
280
+ "time": "2020-05-06T14:07:26+00:00",
281
  "type": "library",
282
  "installation-source": "dist",
283
  "autoload": {
297
  }
298
  ],
299
  "description": "Internal MaxMind Web Service API",
300
+ "homepage": "https://github.com/maxmind/web-service-common-php"
 
 
 
 
301
  },
302
  {
303
  "name": "psr/cache",
402
  },
403
  {
404
  "name": "whichbrowser/parser",
405
+ "version": "v2.0.37",
406
+ "version_normalized": "2.0.37.0",
407
  "source": {
408
  "type": "git",
409
  "url": "https://github.com/WhichBrowser/Parser-PHP.git",
410
+ "reference": "9c6ad8eadc23294b1c66d92876c11f13c5d4cf48"
411
  },
412
  "dist": {
413
  "type": "zip",
414
+ "url": "https://api.github.com/repos/WhichBrowser/Parser-PHP/zipball/9c6ad8eadc23294b1c66d92876c11f13c5d4cf48",
415
+ "reference": "9c6ad8eadc23294b1c66d92876c11f13c5d4cf48",
416
  "shasum": ""
417
  },
418
  "require": {
421
  },
422
  "require-dev": {
423
  "icomefromthenet/reverse-regex": "0.0.6.3",
424
+ "phpunit/php-code-coverage": "^2.2|^3.0",
425
+ "phpunit/phpunit": "^4.0|^5.0",
426
  "satooshi/php-coveralls": "^1.0",
427
  "squizlabs/php_codesniffer": "2.5.*",
428
+ "symfony/yaml": ">=2.8"
429
  },
430
  "suggest": {
431
  "cache/array-adapter": "Allows testing of the caching functionality"
432
  },
433
+ "time": "2018-10-02T09:26:41+00:00",
434
  "type": "library",
435
  "installation-source": "dist",
436
  "autoload": {
462
  ],
463
  "support": {
464
  "issues": "https://github.com/WhichBrowser/Parser-PHP/issues",
465
+ "source": "https://github.com/WhichBrowser/Parser-PHP/tree/master"
466
  }
467
  }
468
  ]
includes/vendor/composer/installed.php DELETED
@@ -1,96 +0,0 @@
1
- <?php return array (
2
- 'root' =>
3
- array (
4
- 'pretty_version' => 'dev-master',
5
- 'version' => 'dev-master',
6
- 'aliases' =>
7
- array (
8
- ),
9
- 'reference' => 'd50c2fc7f17ad7cce00ffe728c45b23c92ce02ca',
10
- 'name' => '__root__',
11
- ),
12
- 'versions' =>
13
- array (
14
- '__root__' =>
15
- array (
16
- 'pretty_version' => 'dev-master',
17
- 'version' => 'dev-master',
18
- 'aliases' =>
19
- array (
20
- ),
21
- 'reference' => 'd50c2fc7f17ad7cce00ffe728c45b23c92ce02ca',
22
- ),
23
- 'composer/ca-bundle' =>
24
- array (
25
- 'pretty_version' => '1.2.8',
26
- 'version' => '1.2.8.0',
27
- 'aliases' =>
28
- array (
29
- ),
30
- 'reference' => '8a7ecad675253e4654ea05505233285377405215',
31
- ),
32
- 'geoip2/geoip2' =>
33
- array (
34
- 'pretty_version' => 'v2.10.0',
35
- 'version' => '2.10.0.0',
36
- 'aliases' =>
37
- array (
38
- ),
39
- 'reference' => '419557cd21d9fe039721a83490701a58c8ce784a',
40
- ),
41
- 'jaybizzle/crawler-detect' =>
42
- array (
43
- 'pretty_version' => 'v1.2.102',
44
- 'version' => '1.2.102.0',
45
- 'aliases' =>
46
- array (
47
- ),
48
- 'reference' => '346cfd72d11bb41f15e82654e532dc55360612ac',
49
- ),
50
- 'maxmind-db/reader' =>
51
- array (
52
- 'pretty_version' => 'v1.8.0',
53
- 'version' => '1.8.0.0',
54
- 'aliases' =>
55
- array (
56
- ),
57
- 'reference' => 'b566d429ac9aec10594b0935be8ff38302f8d5c8',
58
- ),
59
- 'maxmind/web-service-common' =>
60
- array (
61
- 'pretty_version' => 'v0.8.1',
62
- 'version' => '0.8.1.0',
63
- 'aliases' =>
64
- array (
65
- ),
66
- 'reference' => '32f274051c543fc865e5a84d3a2c703913641ea8',
67
- ),
68
- 'psr/cache' =>
69
- array (
70
- 'pretty_version' => '1.0.1',
71
- 'version' => '1.0.1.0',
72
- 'aliases' =>
73
- array (
74
- ),
75
- 'reference' => 'd11b50ad223250cf17b86e38383413f5a6764bf8',
76
- ),
77
- 's1lentium/iptools' =>
78
- array (
79
- 'pretty_version' => 'v1.1.1',
80
- 'version' => '1.1.1.0',
81
- 'aliases' =>
82
- array (
83
- ),
84
- 'reference' => 'f6f8ab6132ca7443bd7cced1681f5066d725fd5f',
85
- ),
86
- 'whichbrowser/parser' =>
87
- array (
88
- 'pretty_version' => 'v2.0.42',
89
- 'version' => '2.0.42.0',
90
- 'aliases' =>
91
- array (
92
- ),
93
- 'reference' => '4899110cd2f87b01e04ced62dbb9dec541031dee',
94
- ),
95
- ),
96
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/vendor/composer/platform_check.php DELETED
@@ -1,25 +0,0 @@
1
- <?php
2
-
3
- // platform_check.php @generated by Composer
4
-
5
- $issues = array();
6
-
7
- if (!(PHP_VERSION_ID >= 70200)) {
8
- $issues[] = 'Your Composer dependencies require a PHP version ">= 7.2.0". You are running ' . PHP_VERSION . '.';
9
- }
10
-
11
- $missingExtensions = array();
12
- extension_loaded('bcmath') || $missingExtensions[] = 'bcmath';
13
- extension_loaded('curl') || $missingExtensions[] = 'curl';
14
- extension_loaded('json') || $missingExtensions[] = 'json';
15
- extension_loaded('openssl') || $missingExtensions[] = 'openssl';
16
- extension_loaded('pcre') || $missingExtensions[] = 'pcre';
17
-
18
- if ($missingExtensions) {
19
- $issues[] = 'Your Composer dependencies require the following PHP extensions to be installed: ' . implode(', ', $missingExtensions);
20
- }
21
-
22
- if ($issues) {
23
- echo 'Composer detected issues in your platform:' . "\n\n" . implode("\n", $issues);
24
- exit(104);
25
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/vendor/maxmind-db/reader/CHANGELOG.md CHANGED
@@ -1,26 +1,6 @@
1
  CHANGELOG
2
  =========
3
 
4
- 1.8.0 (2020-10-01)
5
- ------------------
6
-
7
- * Fixes for PHP 8.0. Pull Request by Remi Collet. GitHub #108.
8
-
9
- 1.7.0 (2020-08-07)
10
- ------------------
11
-
12
- * IMPORTANT: PHP 7.2 or greater is now required.
13
- * The extension no longer depends on the pure PHP classes in
14
- `maxmind-db/reader`. You can use it independently.
15
- * Type hints have been added to both the pure PHP implementation
16
- and the extension.
17
- * The `metadata` method on the reader now returns a new copy of the
18
- metadata object rather than the actual object used by the reader.
19
- * Work around PHP `is_readable()` bug. Reported by Ben Roberts. GitHub
20
- #92.
21
- * This is the first release of the extension as a PECL package.
22
- GitHub #34.
23
-
24
  1.6.0 (2019-12-19)
25
  ------------------
26
 
1
  CHANGELOG
2
  =========
3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
  1.6.0 (2019-12-19)
5
  ------------------
6
 
includes/vendor/maxmind-db/reader/README.md CHANGED
@@ -157,7 +157,7 @@ client API, please see [our support page](https://www.maxmind.com/en/support).
157
 
158
  ## Requirements ##
159
 
160
- This library requires PHP 7.2 or greater.
161
 
162
  The GMP or BCMath extension may be required to read some databases
163
  using the pure PHP API.
@@ -173,6 +173,6 @@ The MaxMind DB Reader PHP API uses [Semantic Versioning](https://semver.org/).
173
 
174
  ## Copyright and License ##
175
 
176
- This software is Copyright (c) 2014-2020 by MaxMind, Inc.
177
 
178
  This is free software, licensed under the Apache License, Version 2.0.
157
 
158
  ## Requirements ##
159
 
160
+ This library requires PHP 5.6 or greater.
161
 
162
  The GMP or BCMath extension may be required to read some databases
163
  using the pure PHP API.
173
 
174
  ## Copyright and License ##
175
 
176
+ This software is Copyright (c) 2014-2019 by MaxMind, Inc.
177
 
178
  This is free software, licensed under the Apache License, Version 2.0.
includes/vendor/maxmind-db/reader/autoload.php CHANGED
@@ -1,7 +1,5 @@
1
  <?php
2
 
3
- declare(strict_types=1);
4
-
5
  /**
6
  * PSR-4 autoloader implementation for the MaxMind\DB namespace.
7
  * First we define the 'mmdb_autoload' function, and then we register
@@ -16,7 +14,7 @@ declare(strict_types=1);
16
  * @param string $class
17
  * the name of the class to load
18
  */
19
- function mmdb_autoload($class): void
20
  {
21
  /*
22
  * A project-specific mapping between the namespaces and where
1
  <?php
2
 
 
 
3
  /**
4
  * PSR-4 autoloader implementation for the MaxMind\DB namespace.
5
  * First we define the 'mmdb_autoload' function, and then we register
14
  * @param string $class
15
  * the name of the class to load
16
  */
17
+ function mmdb_autoload($class)
18
  {
19
  /*
20
  * A project-specific mapping between the namespaces and where
includes/vendor/maxmind-db/reader/composer.json CHANGED
@@ -13,7 +13,7 @@
13
  }
14
  ],
15
  "require": {
16
- "php": ">=7.2"
17
  },
18
  "suggest": {
19
  "ext-bcmath": "bcmath or gmp is required for decoding larger integers with the pure PHP decoder",
@@ -21,13 +21,13 @@
21
  "ext-maxminddb": "A C-based database decoder that provides significantly faster lookups"
22
  },
23
  "conflict": {
24
- "ext-maxminddb": "<1.8.0,>=2.0.0"
25
  },
26
  "require-dev": {
27
  "friendsofphp/php-cs-fixer": "2.*",
28
- "phpunit/phpunit": ">=8.0.0,<10.0.0",
29
  "php-coveralls/php-coveralls": "^2.1",
30
- "phpunit/phpcov": ">=6.0.0",
31
  "squizlabs/php_codesniffer": "3.*"
32
  },
33
  "autoload": {
13
  }
14
  ],
15
  "require": {
16
+ "php": ">=5.6"
17
  },
18
  "suggest": {
19
  "ext-bcmath": "bcmath or gmp is required for decoding larger integers with the pure PHP decoder",
21
  "ext-maxminddb": "A C-based database decoder that provides significantly faster lookups"
22
  },
23
  "conflict": {
24
+ "ext-maxminddb": "<1.6.0,>=2.0.0"
25
  },
26
  "require-dev": {
27
  "friendsofphp/php-cs-fixer": "2.*",
28
+ "phpunit/phpunit": "5.*",
29
  "php-coveralls/php-coveralls": "^2.1",
30
+ "phpunit/phpcov": "^3.0",
31
  "squizlabs/php_codesniffer": "3.*"
32
  },
33
  "autoload": {
includes/vendor/maxmind-db/reader/ext/maxminddb.c CHANGED
@@ -21,8 +21,6 @@
21
  #include <zend.h>
22
 
23
  #include "Zend/zend_exceptions.h"
24
- #include "Zend/zend_types.h"
25
- #include "ext/spl/spl_exceptions.h"
26
  #include "ext/standard/info.h"
27
  #include <maxminddb.h>
28
 
@@ -35,44 +33,49 @@
35
 
36
  #define PHP_MAXMINDDB_NS ZEND_NS_NAME("MaxMind", "Db")
37
  #define PHP_MAXMINDDB_READER_NS ZEND_NS_NAME(PHP_MAXMINDDB_NS, "Reader")
38
- #define PHP_MAXMINDDB_METADATA_NS \
39
- ZEND_NS_NAME(PHP_MAXMINDDB_READER_NS, "Metadata")
40
  #define PHP_MAXMINDDB_READER_EX_NS \
41
  ZEND_NS_NAME(PHP_MAXMINDDB_READER_NS, "InvalidDatabaseException")
42
 
 
43
  #define Z_MAXMINDDB_P(zv) php_maxminddb_fetch_object(Z_OBJ_P(zv))
 
 
44
  typedef size_t strsize_t;
45
  typedef zend_object free_obj_t;
46
-
47
- /* For PHP 8 compatibility */
48
- #if PHP_VERSION_ID < 80000
49
-
50
- #define PROP_OBJ(zv) (zv)
51
-
52
  #else
 
 
 
 
 
 
 
53
 
54
- #define PROP_OBJ(zv) Z_OBJ_P(zv)
55
-
56
  #define TSRMLS_C
 
 
57
  #define TSRMLS_CC
 
 
58
  #define TSRMLS_DC
59
-
60
- /* End PHP 8 compatibility */
61
  #endif
62
-
63
  #ifndef ZEND_ACC_CTOR
64
  #define ZEND_ACC_CTOR 0
65
  #endif
66
 
67
- /* IS_MIXED was added in 2020 */
68
- #ifndef IS_MIXED
69
- #define IS_MIXED IS_UNDEF
70
- #endif
71
-
72
  typedef struct _maxminddb_obj {
73
  MMDB_s *mmdb;
74
  zend_object std;
75
  } maxminddb_obj;
 
 
 
 
 
 
76
 
77
  PHP_FUNCTION(maxminddb);
78
 
@@ -93,6 +96,7 @@ static void handle_uint64(const MMDB_entry_data_list_s *entry_data_list,
93
  zval *z_value TSRMLS_DC);
94
  static void handle_uint32(const MMDB_entry_data_list_s *entry_data_list,
95
  zval *z_value TSRMLS_DC);
 
96
 
97
  #define CHECK_ALLOCATED(val) \
98
  if (!val) { \
@@ -100,16 +104,38 @@ static void handle_uint32(const MMDB_entry_data_list_s *entry_data_list,
100
  return; \
101
  }
102
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
103
  static zend_object_handlers maxminddb_obj_handlers;
104
- static zend_class_entry *maxminddb_ce, *maxminddb_exception_ce, *metadata_ce;
105
 
106
  static inline maxminddb_obj *
107
  php_maxminddb_fetch_object(zend_object *obj TSRMLS_DC) {
 
108
  return (maxminddb_obj *)((char *)(obj)-XtOffsetOf(maxminddb_obj, std));
 
 
 
109
  }
110
 
111
- ZEND_BEGIN_ARG_INFO_EX(arginfo_maxminddbreader_construct, 0, 0, 1)
112
- ZEND_ARG_TYPE_INFO(0, db_file, IS_STRING, 0)
113
  ZEND_END_ARG_INFO()
114
 
115
  PHP_METHOD(MaxMind_Db_Reader, __construct) {
@@ -124,16 +150,16 @@ PHP_METHOD(MaxMind_Db_Reader, __construct) {
124
  maxminddb_ce,
125
  &db_file,
126
  &name_len) == FAILURE) {
 
 
127
  return;
128
  }
129
 
130
  if (0 != php_check_open_basedir(db_file TSRMLS_CC) ||
131
  0 != access(db_file, R_OK)) {
132
- zend_throw_exception_ex(
133
- spl_ce_InvalidArgumentException,
134
- 0 TSRMLS_CC,
135
- "The file \"%s\" does not exist or is not readable.",
136
- db_file);
137
  return;
138
  }
139
 
@@ -141,12 +167,10 @@ PHP_METHOD(MaxMind_Db_Reader, __construct) {
141
  uint16_t status = MMDB_open(db_file, MMDB_MODE_MMAP, mmdb);
142
 
143
  if (MMDB_SUCCESS != status) {
144
- zend_throw_exception_ex(
145
- maxminddb_exception_ce,
146
- 0 TSRMLS_CC,
147
- "Error opening database file (%s). Is this a valid "
148
- "MaxMind DB file?",
149
- db_file);
150
  efree(mmdb);
151
  return;
152
  }
@@ -155,9 +179,8 @@ PHP_METHOD(MaxMind_Db_Reader, __construct) {
155
  mmdb_obj->mmdb = mmdb;
156
  }
157
 
158
- ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(
159
- arginfo_maxminddbreader_get, 0, 1, IS_MIXED, 1)
160
- ZEND_ARG_TYPE_INFO(0, ip_address, IS_STRING, 0)
161
  ZEND_END_ARG_INFO()
162
 
163
  PHP_METHOD(MaxMind_Db_Reader, get) {
@@ -165,41 +188,45 @@ PHP_METHOD(MaxMind_Db_Reader, get) {
165
  get_record(INTERNAL_FUNCTION_PARAM_PASSTHRU, return_value, &prefix_len);
166
  }
167
 
168
- ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(
169
- arginfo_maxminddbreader_getWithPrefixLen, 0, 1, IS_ARRAY, 1)
170
- ZEND_ARG_TYPE_INFO(0, ip_address, IS_STRING, 0)
171
- ZEND_END_ARG_INFO()
172
-
173
  PHP_METHOD(MaxMind_Db_Reader, getWithPrefixLen) {
174
- zval record, z_prefix_len;
 
 
 
 
 
 
 
 
175
 
176
  int prefix_len = 0;
177
- if (get_record(INTERNAL_FUNCTION_PARAM_PASSTHRU, &record, &prefix_len) ==
178
- FAILURE) {
179
  return;
180
  }
181
 
182
  array_init(return_value);
183
- add_next_index_zval(return_value, &record);
184
 
185
- ZVAL_LONG(&z_prefix_len, prefix_len);
186
- add_next_index_zval(return_value, &z_prefix_len);
187
  }
188
 
189
  static int
190
  get_record(INTERNAL_FUNCTION_PARAMETERS, zval *record, int *prefix_len) {
191
  char *ip_address = NULL;
192
  strsize_t name_len;
193
- zval *this_zval = NULL;
194
 
195
  if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
196
  getThis(),
197
  "Os",
198
- &this_zval,
199
  maxminddb_ce,
200
  &ip_address,
201
  &name_len) == FAILURE) {
202
- return FAILURE;
 
 
203
  }
204
 
205
  const maxminddb_obj *mmdb_obj = (maxminddb_obj *)Z_MAXMINDDB_P(getThis());
@@ -207,33 +234,30 @@ get_record(INTERNAL_FUNCTION_PARAMETERS, zval *record, int *prefix_len) {
207
  MMDB_s *mmdb = mmdb_obj->mmdb;
208
 
209
  if (NULL == mmdb) {
210
- zend_throw_exception_ex(spl_ce_BadMethodCallException,
211
- 0 TSRMLS_CC,
212
- "Attempt to read from a closed MaxMind DB.");
213
- return FAILURE;
214
  }
215
 
216
  struct addrinfo hints = {
217
  .ai_family = AF_UNSPEC,
218
  .ai_flags = AI_NUMERICHOST,
219
- /* We set ai_socktype so that we only get one result back */
220
  .ai_socktype = SOCK_STREAM};
221
 
222
  struct addrinfo *addresses = NULL;
223
  int gai_status = getaddrinfo(ip_address, NULL, &hints, &addresses);
224
  if (gai_status) {
225
- zend_throw_exception_ex(spl_ce_InvalidArgumentException,
226
- 0 TSRMLS_CC,
227
- "The value \"%s\" is not a valid IP address.",
228
- ip_address);
229
- return FAILURE;
230
  }
231
  if (!addresses || !addresses->ai_addr) {
232
- zend_throw_exception_ex(
233
- spl_ce_InvalidArgumentException,
234
- 0 TSRMLS_CC,
235
  "getaddrinfo was successful but failed to set the addrinfo");
236
- return FAILURE;
237
  }
238
 
239
  int sa_family = addresses->ai_addr->sa_family;
@@ -245,127 +269,132 @@ get_record(INTERNAL_FUNCTION_PARAMETERS, zval *record, int *prefix_len) {
245
  freeaddrinfo(addresses);
246
 
247
  if (MMDB_SUCCESS != mmdb_error) {
248
- zend_class_entry *ex;
249
  if (MMDB_IPV6_LOOKUP_IN_IPV4_DATABASE_ERROR == mmdb_error) {
250
- ex = spl_ce_InvalidArgumentException;
251
  } else {
252
- ex = maxminddb_exception_ce;
253
  }
254
- zend_throw_exception_ex(ex,
255
- 0 TSRMLS_CC,
256
- "Error looking up %s. %s",
257
- ip_address,
258
- MMDB_strerror(mmdb_error));
259
- return FAILURE;
260
  }
261
 
262
  *prefix_len = result.netmask;
263
 
264
  if (sa_family == AF_INET && mmdb->metadata.ip_version == 6) {
265
- /* We return the prefix length given the IPv4 address. If there is
266
- no IPv4 subtree, we return a prefix length of 0. */
267
  *prefix_len = *prefix_len >= 96 ? *prefix_len - 96 : 0;
268
  }
269
 
270
  if (!result.found_entry) {
271
  ZVAL_NULL(record);
272
- return SUCCESS;
273
  }
274
 
275
  MMDB_entry_data_list_s *entry_data_list = NULL;
276
  int status = MMDB_get_entry_data_list(&result.entry, &entry_data_list);
277
 
278
  if (MMDB_SUCCESS != status) {
279
- zend_throw_exception_ex(maxminddb_exception_ce,
280
- 0 TSRMLS_CC,
281
- "Error while looking up data for %s. %s",
282
- ip_address,
283
- MMDB_strerror(status));
284
  MMDB_free_entry_data_list(entry_data_list);
285
- return FAILURE;
286
  } else if (NULL == entry_data_list) {
287
- zend_throw_exception_ex(
288
- maxminddb_exception_ce,
289
- 0 TSRMLS_CC,
290
- "Error while looking up data for %s. Your database may "
291
- "be corrupt or you have found a bug in libmaxminddb.",
292
- ip_address);
293
- return FAILURE;
294
  }
295
 
296
- const MMDB_entry_data_list_s *rv =
297
- handle_entry_data_list(entry_data_list, record TSRMLS_CC);
298
- if (rv == NULL) {
299
- /* We should have already thrown the exception in handle_entry_data_list
300
- */
301
- return FAILURE;
302
- }
303
  MMDB_free_entry_data_list(entry_data_list);
304
- return SUCCESS;
305
  }
306
 
307
- ZEND_BEGIN_ARG_INFO_EX(arginfo_maxminddbreader_void, 0, 0, 0)
308
  ZEND_END_ARG_INFO()
309
 
310
  PHP_METHOD(MaxMind_Db_Reader, metadata) {
311
- zval *this_zval = NULL;
312
-
313
- if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
314
- getThis(),
315
- "O",
316
- &this_zval,
317
- maxminddb_ce) == FAILURE) {
318
  return;
319
  }
320
 
321
  const maxminddb_obj *const mmdb_obj =
322
- (maxminddb_obj *)Z_MAXMINDDB_P(this_zval);
323
 
324
  if (NULL == mmdb_obj->mmdb) {
325
- zend_throw_exception_ex(spl_ce_BadMethodCallException,
326
- 0 TSRMLS_CC,
327
- "Attempt to read from a closed MaxMind DB.");
328
  return;
329
  }
330
 
 
 
 
331
  object_init_ex(return_value, metadata_ce);
332
 
 
 
 
 
 
 
 
 
 
333
  MMDB_entry_data_list_s *entry_data_list;
334
  MMDB_get_metadata_as_entry_data_list(mmdb_obj->mmdb, &entry_data_list);
335
 
336
- zval metadata_array;
337
- const MMDB_entry_data_list_s *rv =
338
- handle_entry_data_list(entry_data_list, &metadata_array TSRMLS_CC);
339
- if (rv == NULL) {
340
- return;
341
- }
342
  MMDB_free_entry_data_list(entry_data_list);
343
- zend_call_method_with_1_params(PROP_OBJ(return_value),
 
344
  metadata_ce,
345
  &metadata_ce->constructor,
346
  ZEND_CONSTRUCTOR_FUNC_NAME,
347
  NULL,
348
- &metadata_array);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
349
  zval_ptr_dtor(&metadata_array);
 
350
  }
351
 
352
  PHP_METHOD(MaxMind_Db_Reader, close) {
353
- zval *this_zval = NULL;
354
-
355
- if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
356
- getThis(),
357
- "O",
358
- &this_zval,
359
- maxminddb_ce) == FAILURE) {
360
  return;
361
  }
362
 
363
- maxminddb_obj *mmdb_obj = (maxminddb_obj *)Z_MAXMINDDB_P(this_zval);
364
 
365
  if (NULL == mmdb_obj->mmdb) {
366
- zend_throw_exception_ex(spl_ce_BadMethodCallException,
367
- 0 TSRMLS_CC,
368
- "Attempt to close a closed MaxMind DB.");
369
  return;
370
  }
371
  MMDB_close(mmdb_obj->mmdb);
@@ -382,14 +411,14 @@ handle_entry_data_list(const MMDB_entry_data_list_s *entry_data_list,
382
  case MMDB_DATA_TYPE_ARRAY:
383
  return handle_array(entry_data_list, z_value TSRMLS_CC);
384
  case MMDB_DATA_TYPE_UTF8_STRING:
385
- ZVAL_STRINGL(z_value,
386
- (char *)entry_data_list->entry_data.utf8_string,
387
- entry_data_list->entry_data.data_size);
388
  break;
389
  case MMDB_DATA_TYPE_BYTES:
390
- ZVAL_STRINGL(z_value,
391
- (char *)entry_data_list->entry_data.bytes,
392
- entry_data_list->entry_data.data_size);
393
  break;
394
  case MMDB_DATA_TYPE_DOUBLE:
395
  ZVAL_DOUBLE(z_value, entry_data_list->entry_data.double_value);
@@ -416,10 +445,9 @@ handle_entry_data_list(const MMDB_entry_data_list_s *entry_data_list,
416
  ZVAL_LONG(z_value, entry_data_list->entry_data.int32);
417
  break;
418
  default:
419
- zend_throw_exception_ex(maxminddb_exception_ce,
420
- 0 TSRMLS_CC,
421
- "Invalid data type arguments: %d",
422
- entry_data_list->entry_data.type);
423
  return NULL;
424
  }
425
  return entry_data_list;
@@ -438,19 +466,23 @@ handle_map(const MMDB_entry_data_list_s *entry_data_list,
438
  char *key = estrndup((char *)entry_data_list->entry_data.utf8_string,
439
  entry_data_list->entry_data.data_size);
440
  if (NULL == key) {
441
- zend_throw_exception_ex(maxminddb_exception_ce,
442
- 0 TSRMLS_CC,
443
- "Invalid data type arguments");
444
  return NULL;
445
  }
446
 
447
  entry_data_list = entry_data_list->next;
448
- zval new_value;
 
 
 
 
 
 
 
449
  entry_data_list =
450
- handle_entry_data_list(entry_data_list, &new_value TSRMLS_CC);
451
- if (entry_data_list != NULL) {
452
- add_assoc_zval(z_value, key, &new_value);
453
- }
454
  efree(key);
455
  }
456
  return entry_data_list;
@@ -466,12 +498,17 @@ handle_array(const MMDB_entry_data_list_s *entry_data_list,
466
  uint i;
467
  for (i = 0; i < size && entry_data_list; i++) {
468
  entry_data_list = entry_data_list->next;
469
- zval new_value;
 
 
 
 
 
 
 
470
  entry_data_list =
471
- handle_entry_data_list(entry_data_list, &new_value TSRMLS_CC);
472
- if (entry_data_list != NULL) {
473
- add_next_index_zval(z_value, &new_value);
474
- }
475
  }
476
  return entry_data_list;
477
  }
@@ -498,7 +535,7 @@ static void handle_uint128(const MMDB_entry_data_list_s *entry_data_list,
498
  spprintf(&num_str, 0, "0x%016" PRIX64 "%016" PRIX64, high, low);
499
  CHECK_ALLOCATED(num_str);
500
 
501
- ZVAL_STRING(z_value, num_str);
502
  efree(num_str);
503
  }
504
 
@@ -519,7 +556,7 @@ static void handle_uint32(const MMDB_entry_data_list_s *entry_data_list,
519
  spprintf(&int_str, 0, "%" PRIu32, val);
520
  CHECK_ALLOCATED(int_str);
521
 
522
- ZVAL_STRING(z_value, int_str);
523
  efree(int_str);
524
  #endif
525
  }
@@ -541,11 +578,29 @@ static void handle_uint64(const MMDB_entry_data_list_s *entry_data_list,
541
  spprintf(&int_str, 0, "%" PRIu64, val);
542
  CHECK_ALLOCATED(int_str);
543
 
544
- ZVAL_STRING(z_value, int_str);
545
  efree(int_str);
546
  #endif
547
  }
548
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
549
  static void maxminddb_free_storage(free_obj_t *object TSRMLS_DC) {
550
  maxminddb_obj *obj =
551
  php_maxminddb_fetch_object((zend_object *)object TSRMLS_CC);
@@ -555,8 +610,12 @@ static void maxminddb_free_storage(free_obj_t *object TSRMLS_DC) {
555
  }
556
 
557
  zend_object_std_dtor(&obj->std TSRMLS_CC);
 
 
 
558
  }
559
 
 
560
  static zend_object *maxminddb_create_handler(zend_class_entry *type TSRMLS_DC) {
561
  maxminddb_obj *obj = (maxminddb_obj *)ecalloc(1, sizeof(maxminddb_obj));
562
  zend_object_std_init(&obj->std, type TSRMLS_CC);
@@ -566,210 +625,49 @@ static zend_object *maxminddb_create_handler(zend_class_entry *type TSRMLS_DC) {
566
 
567
  return &obj->std;
568
  }
 
 
 
 
569
 
570
- /* clang-format off */
571
- static zend_function_entry maxminddb_methods[] = {
572
- PHP_ME(MaxMind_Db_Reader, __construct, arginfo_maxminddbreader_construct,
573
- ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
574
- PHP_ME(MaxMind_Db_Reader, close, arginfo_maxminddbreader_void, ZEND_ACC_PUBLIC)
575
- PHP_ME(MaxMind_Db_Reader, get, arginfo_maxminddbreader_get, ZEND_ACC_PUBLIC)
576
- PHP_ME(MaxMind_Db_Reader, getWithPrefixLen, arginfo_maxminddbreader_getWithPrefixLen, ZEND_ACC_PUBLIC)
577
- PHP_ME(MaxMind_Db_Reader, metadata, arginfo_maxminddbreader_void, ZEND_ACC_PUBLIC)
578
- { NULL, NULL, NULL }
579
- };
580
- /* clang-format on */
581
-
582
- ZEND_BEGIN_ARG_INFO_EX(arginfo_metadata_construct, 0, 0, 1)
583
- ZEND_ARG_TYPE_INFO(0, metadata, IS_ARRAY, 0)
584
- ZEND_END_ARG_INFO()
585
-
586
- PHP_METHOD(MaxMind_Db_Reader_Metadata, __construct) {
587
- zval *object = NULL;
588
- zval *metadata_array = NULL;
589
- zend_long node_count = 0;
590
- zend_long record_size = 0;
591
-
592
- if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
593
- getThis(),
594
- "Oa",
595
- &object,
596
- metadata_ce,
597
- &metadata_array) == FAILURE) {
598
- return;
599
- }
600
-
601
- zval *tmp = NULL;
602
- if ((tmp = zend_hash_str_find(HASH_OF(metadata_array),
603
- "binary_format_major_version",
604
- sizeof("binary_format_major_version") - 1))) {
605
- zend_update_property(metadata_ce,
606
- PROP_OBJ(object),
607
- "binaryFormatMajorVersion",
608
- sizeof("binaryFormatMajorVersion") - 1,
609
- tmp);
610
- }
611
-
612
- if ((tmp = zend_hash_str_find(HASH_OF(metadata_array),
613
- "binary_format_minor_version",
614
- sizeof("binary_format_minor_version") - 1))) {
615
- zend_update_property(metadata_ce,
616
- PROP_OBJ(object),
617
- "binaryFormatMinorVersion",
618
- sizeof("binaryFormatMinorVersion") - 1,
619
- tmp);
620
- }
621
-
622
- if ((tmp = zend_hash_str_find(HASH_OF(metadata_array),
623
- "build_epoch",
624
- sizeof("build_epoch") - 1))) {
625
- zend_update_property(metadata_ce,
626
- PROP_OBJ(object),
627
- "buildEpoch",
628
- sizeof("buildEpoch") - 1,
629
- tmp);
630
- }
631
-
632
- if ((tmp = zend_hash_str_find(HASH_OF(metadata_array),
633
- "database_type",
634
- sizeof("database_type") - 1))) {
635
- zend_update_property(metadata_ce,
636
- PROP_OBJ(object),
637
- "databaseType",
638
- sizeof("databaseType") - 1,
639
- tmp);
640
- }
641
-
642
- if ((tmp = zend_hash_str_find(HASH_OF(metadata_array),
643
- "description",
644
- sizeof("description") - 1))) {
645
- zend_update_property(metadata_ce,
646
- PROP_OBJ(object),
647
- "description",
648
- sizeof("description") - 1,
649
- tmp);
650
- }
651
-
652
- if ((tmp = zend_hash_str_find(HASH_OF(metadata_array),
653
- "ip_version",
654
- sizeof("ip_version") - 1))) {
655
- zend_update_property(metadata_ce,
656
- PROP_OBJ(object),
657
- "ipVersion",
658
- sizeof("ipVersion") - 1,
659
- tmp);
660
- }
661
-
662
- if ((tmp = zend_hash_str_find(
663
- HASH_OF(metadata_array), "languages", sizeof("languages") - 1))) {
664
- zend_update_property(metadata_ce,
665
- PROP_OBJ(object),
666
- "languages",
667
- sizeof("languages") - 1,
668
- tmp);
669
- }
670
-
671
- if ((tmp = zend_hash_str_find(HASH_OF(metadata_array),
672
- "record_size",
673
- sizeof("record_size") - 1))) {
674
- zend_update_property(metadata_ce,
675
- PROP_OBJ(object),
676
- "recordSize",
677
- sizeof("recordSize") - 1,
678
- tmp);
679
- if (Z_TYPE_P(tmp) == IS_LONG) {
680
- record_size = Z_LVAL_P(tmp);
681
- }
682
- }
683
-
684
- if (record_size != 0) {
685
- zend_update_property_long(metadata_ce,
686
- PROP_OBJ(object),
687
- "nodeByteSize",
688
- sizeof("nodeByteSize") - 1,
689
- record_size / 4);
690
- }
691
 
692
- if ((tmp = zend_hash_str_find(HASH_OF(metadata_array),
693
- "node_count",
694
- sizeof("node_count") - 1))) {
695
- zend_update_property(metadata_ce,
696
- PROP_OBJ(object),
697
- "nodeCount",
698
- sizeof("nodeCount") - 1,
699
- tmp);
700
- if (Z_TYPE_P(tmp) == IS_LONG) {
701
- node_count = Z_LVAL_P(tmp);
702
- }
703
- }
704
 
705
- if (record_size != 0) {
706
- zend_update_property_long(metadata_ce,
707
- PROP_OBJ(object),
708
- "searchTreeSize",
709
- sizeof("searchTreeSize") - 1,
710
- record_size * node_count / 4);
711
- }
712
  }
 
713
 
714
  // clang-format off
715
- static zend_function_entry metadata_methods[] = {
716
- PHP_ME(MaxMind_Db_Reader_Metadata, __construct, arginfo_metadata_construct, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
717
- {NULL, NULL, NULL}
 
 
 
 
 
718
  };
719
  // clang-format on
720
 
721
  PHP_MINIT_FUNCTION(maxminddb) {
722
  zend_class_entry ce;
723
 
724
- INIT_CLASS_ENTRY(ce, PHP_MAXMINDDB_READER_EX_NS, NULL);
725
- maxminddb_exception_ce =
726
- zend_register_internal_class_ex(&ce, zend_ce_exception);
727
-
728
  INIT_CLASS_ENTRY(ce, PHP_MAXMINDDB_READER_NS, maxminddb_methods);
729
  maxminddb_ce = zend_register_internal_class(&ce TSRMLS_CC);
730
  maxminddb_ce->create_object = maxminddb_create_handler;
731
-
732
- INIT_CLASS_ENTRY(ce, PHP_MAXMINDDB_METADATA_NS, metadata_methods);
733
- metadata_ce = zend_register_internal_class(&ce TSRMLS_CC);
734
- zend_declare_property_null(metadata_ce,
735
- "binaryFormatMajorVersion",
736
- sizeof("binaryFormatMajorVersion") - 1,
737
- ZEND_ACC_PUBLIC);
738
- zend_declare_property_null(metadata_ce,
739
- "binaryFormatMinorVersion",
740
- sizeof("binaryFormatMinorVersion") - 1,
741
- ZEND_ACC_PUBLIC);
742
- zend_declare_property_null(
743
- metadata_ce, "buildEpoch", sizeof("buildEpoch") - 1, ZEND_ACC_PUBLIC);
744
- zend_declare_property_null(metadata_ce,
745
- "databaseType",
746
- sizeof("databaseType") - 1,
747
- ZEND_ACC_PUBLIC);
748
- zend_declare_property_null(
749
- metadata_ce, "description", sizeof("description") - 1, ZEND_ACC_PUBLIC);
750
- zend_declare_property_null(
751
- metadata_ce, "ipVersion", sizeof("ipVersion") - 1, ZEND_ACC_PUBLIC);
752
- zend_declare_property_null(
753
- metadata_ce, "languages", sizeof("languages") - 1, ZEND_ACC_PUBLIC);
754
- zend_declare_property_null(metadata_ce,
755
- "nodeByteSize",
756
- sizeof("nodeByteSize") - 1,
757
- ZEND_ACC_PUBLIC);
758
- zend_declare_property_null(
759
- metadata_ce, "nodeCount", sizeof("nodeCount") - 1, ZEND_ACC_PUBLIC);
760
- zend_declare_property_null(
761
- metadata_ce, "recordSize", sizeof("recordSize") - 1, ZEND_ACC_PUBLIC);
762
- zend_declare_property_null(metadata_ce,
763
- "searchTreeSize",
764
- sizeof("searchTreeSize") - 1,
765
- ZEND_ACC_PUBLIC);
766
-
767
  memcpy(&maxminddb_obj_handlers,
768
  zend_get_std_object_handlers(),
769
  sizeof(zend_object_handlers));
770
  maxminddb_obj_handlers.clone_obj = NULL;
 
771
  maxminddb_obj_handlers.offset = XtOffsetOf(maxminddb_obj, std);
772
  maxminddb_obj_handlers.free_obj = maxminddb_free_storage;
 
773
  zend_declare_class_constant_string(maxminddb_ce,
774
  "MMDB_LIB_VERSION",
775
  sizeof("MMDB_LIB_VERSION") - 1,
21
  #include <zend.h>
22
 
23
  #include "Zend/zend_exceptions.h"
 
 
24
  #include "ext/standard/info.h"
25
  #include <maxminddb.h>
26
 
33
 
34
  #define PHP_MAXMINDDB_NS ZEND_NS_NAME("MaxMind", "Db")
35
  #define PHP_MAXMINDDB_READER_NS ZEND_NS_NAME(PHP_MAXMINDDB_NS, "Reader")
 
 
36
  #define PHP_MAXMINDDB_READER_EX_NS \
37
  ZEND_NS_NAME(PHP_MAXMINDDB_READER_NS, "InvalidDatabaseException")
38
 
39
+ #ifdef ZEND_ENGINE_3
40
  #define Z_MAXMINDDB_P(zv) php_maxminddb_fetch_object(Z_OBJ_P(zv))
41
+ #define _ZVAL_STRING ZVAL_STRING
42
+ #define _ZVAL_STRINGL ZVAL_STRINGL
43
  typedef size_t strsize_t;
44
  typedef zend_object free_obj_t;
 
 
 
 
 
 
45
  #else
46
+ #define Z_MAXMINDDB_P(zv) \
47
+ (maxminddb_obj *)zend_object_store_get_object(zv TSRMLS_CC)
48
+ #define _ZVAL_STRING(a, b) ZVAL_STRING(a, b, 1)
49
+ #define _ZVAL_STRINGL(a, b, c) ZVAL_STRINGL(a, b, c, 1)
50
+ typedef int strsize_t;
51
+ typedef void free_obj_t;
52
+ #endif
53
 
54
+ /* For PHP 8 compatibility */
55
+ #ifndef TSRMLS_C
56
  #define TSRMLS_C
57
+ #endif
58
+ #ifndef TSRMLS_CC
59
  #define TSRMLS_CC
60
+ #endif
61
+ #ifndef TSRMLS_DC
62
  #define TSRMLS_DC
 
 
63
  #endif
 
64
  #ifndef ZEND_ACC_CTOR
65
  #define ZEND_ACC_CTOR 0
66
  #endif
67
 
68
+ #ifdef ZEND_ENGINE_3
 
 
 
 
69
  typedef struct _maxminddb_obj {
70
  MMDB_s *mmdb;
71
  zend_object std;
72
  } maxminddb_obj;
73
+ #else
74
+ typedef struct _maxminddb_obj {
75
+ zend_object std;
76
+ MMDB_s *mmdb;
77
+ } maxminddb_obj;
78
+ #endif
79
 
80
  PHP_FUNCTION(maxminddb);
81
 
96
  zval *z_value TSRMLS_DC);
97
  static void handle_uint32(const MMDB_entry_data_list_s *entry_data_list,
98
  zval *z_value TSRMLS_DC);
99
+ static zend_class_entry *lookup_class(const char *name TSRMLS_DC);
100
 
101
  #define CHECK_ALLOCATED(val) \
102
  if (!val) { \
104
  return; \
105
  }
106
 
107
+ #define THROW_EXCEPTION(name, ...) \
108
+ { \
109
+ zend_class_entry *exception_ce = lookup_class(name TSRMLS_CC); \
110
+ zend_throw_exception_ex(exception_ce, 0 TSRMLS_CC, __VA_ARGS__); \
111
+ }
112
+
113
+ #if PHP_VERSION_ID < 50399
114
+ #define object_properties_init(zo, class_type) \
115
+ { \
116
+ zval *tmp; \
117
+ zend_hash_copy((*zo).properties, \
118
+ &class_type->default_properties, \
119
+ (copy_ctor_func_t)zval_add_ref, \
120
+ (void *)&tmp, \
121
+ sizeof(zval *)); \
122
+ }
123
+ #endif
124
+
125
  static zend_object_handlers maxminddb_obj_handlers;
126
+ static zend_class_entry *maxminddb_ce;
127
 
128
  static inline maxminddb_obj *
129
  php_maxminddb_fetch_object(zend_object *obj TSRMLS_DC) {
130
+ #ifdef ZEND_ENGINE_3
131
  return (maxminddb_obj *)((char *)(obj)-XtOffsetOf(maxminddb_obj, std));
132
+ #else
133
+ return (maxminddb_obj *)obj;
134
+ #endif
135
  }
136
 
137
+ ZEND_BEGIN_ARG_INFO_EX(arginfo_maxmindbreader_construct, 0, 0, 1)
138
+ ZEND_ARG_INFO(0, db_file)
139
  ZEND_END_ARG_INFO()
140
 
141
  PHP_METHOD(MaxMind_Db_Reader, __construct) {
150
  maxminddb_ce,
151
  &db_file,
152
  &name_len) == FAILURE) {
153
+ THROW_EXCEPTION("InvalidArgumentException",
154
+ "The constructor takes exactly one argument.");
155
  return;
156
  }
157
 
158
  if (0 != php_check_open_basedir(db_file TSRMLS_CC) ||
159
  0 != access(db_file, R_OK)) {
160
+ THROW_EXCEPTION("InvalidArgumentException",
161
+ "The file \"%s\" does not exist or is not readable.",
162
+ db_file);
 
 
163
  return;
164
  }
165
 
167
  uint16_t status = MMDB_open(db_file, MMDB_MODE_MMAP, mmdb);
168
 
169
  if (MMDB_SUCCESS != status) {
170
+ THROW_EXCEPTION(PHP_MAXMINDDB_READER_EX_NS,
171
+ "Error opening database file (%s). Is this a valid "
172
+ "MaxMind DB file?",
173
+ db_file);
 
 
174
  efree(mmdb);
175
  return;
176
  }
179
  mmdb_obj->mmdb = mmdb;
180
  }
181
 
182
+ ZEND_BEGIN_ARG_INFO_EX(arginfo_maxmindbreader_get, 0, 0, 1)
183
+ ZEND_ARG_INFO(0, ip_address)
 
184
  ZEND_END_ARG_INFO()
185
 
186
  PHP_METHOD(MaxMind_Db_Reader, get) {
188
  get_record(INTERNAL_FUNCTION_PARAM_PASSTHRU, return_value, &prefix_len);
189
  }
190
 
 
 
 
 
 
191
  PHP_METHOD(MaxMind_Db_Reader, getWithPrefixLen) {
192
+ zval *record, *z_prefix_len;
193
+ #ifdef ZEND_ENGINE_3
194
+ zval _record, _z_prefix_len;
195
+ record = &_record;
196
+ z_prefix_len = &_z_prefix_len;
197
+ #else
198
+ ALLOC_INIT_ZVAL(record);
199
+ ALLOC_INIT_ZVAL(z_prefix_len);
200
+ #endif
201
 
202
  int prefix_len = 0;
203
+ if (get_record(INTERNAL_FUNCTION_PARAM_PASSTHRU, record, &prefix_len)) {
 
204
  return;
205
  }
206
 
207
  array_init(return_value);
208
+ add_next_index_zval(return_value, record);
209
 
210
+ ZVAL_LONG(z_prefix_len, prefix_len);
211
+ add_next_index_zval(return_value, z_prefix_len);
212
  }
213
 
214
  static int
215
  get_record(INTERNAL_FUNCTION_PARAMETERS, zval *record, int *prefix_len) {
216
  char *ip_address = NULL;
217
  strsize_t name_len;
218
+ zval *_this_zval = NULL;
219
 
220
  if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
221
  getThis(),
222
  "Os",
223
+ &_this_zval,
224
  maxminddb_ce,
225
  &ip_address,
226
  &name_len) == FAILURE) {
227
+ THROW_EXCEPTION("InvalidArgumentException",
228
+ "Method takes exactly one argument.");
229
+ return 1;
230
  }
231
 
232
  const maxminddb_obj *mmdb_obj = (maxminddb_obj *)Z_MAXMINDDB_P(getThis());
234
  MMDB_s *mmdb = mmdb_obj->mmdb;
235
 
236
  if (NULL == mmdb) {
237
+ THROW_EXCEPTION("BadMethodCallException",
238
+ "Attempt to read from a closed MaxMind DB.");
239
+ return 1;
 
240
  }
241
 
242
  struct addrinfo hints = {
243
  .ai_family = AF_UNSPEC,
244
  .ai_flags = AI_NUMERICHOST,
245
+ // We set ai_socktype so that we only get one result back
246
  .ai_socktype = SOCK_STREAM};
247
 
248
  struct addrinfo *addresses = NULL;
249
  int gai_status = getaddrinfo(ip_address, NULL, &hints, &addresses);
250
  if (gai_status) {
251
+ THROW_EXCEPTION("InvalidArgumentException",
252
+ "The value \"%s\" is not a valid IP address.",
253
+ ip_address);
254
+ return 1;
 
255
  }
256
  if (!addresses || !addresses->ai_addr) {
257
+ THROW_EXCEPTION(
258
+ "InvalidArgumentException",
 
259
  "getaddrinfo was successful but failed to set the addrinfo");
260
+ return 1;
261
  }
262
 
263
  int sa_family = addresses->ai_addr->sa_family;
269
  freeaddrinfo(addresses);
270
 
271
  if (MMDB_SUCCESS != mmdb_error) {
272
+ char *exception_name;
273
  if (MMDB_IPV6_LOOKUP_IN_IPV4_DATABASE_ERROR == mmdb_error) {
274
+ exception_name = "InvalidArgumentException";
275
  } else {
276
+ exception_name = PHP_MAXMINDDB_READER_EX_NS;
277
  }
278
+ THROW_EXCEPTION(exception_name,
279
+ "Error looking up %s. %s",
280
+ ip_address,
281
+ MMDB_strerror(mmdb_error));
282
+ return 1;
 
283
  }
284
 
285
  *prefix_len = result.netmask;
286
 
287
  if (sa_family == AF_INET && mmdb->metadata.ip_version == 6) {
288
+ // We return the prefix length given the IPv4 address. If there is
289
+ // no IPv4 subtree, we return a prefix length of 0.
290
  *prefix_len = *prefix_len >= 96 ? *prefix_len - 96 : 0;
291
  }
292
 
293
  if (!result.found_entry) {
294
  ZVAL_NULL(record);
295
+ return 0;
296
  }
297
 
298
  MMDB_entry_data_list_s *entry_data_list = NULL;
299
  int status = MMDB_get_entry_data_list(&result.entry, &entry_data_list);
300
 
301
  if (MMDB_SUCCESS != status) {
302
+ THROW_EXCEPTION(PHP_MAXMINDDB_READER_EX_NS,
303
+ "Error while looking up data for %s. %s",
304
+ ip_address,
305
+ MMDB_strerror(status));
 
306
  MMDB_free_entry_data_list(entry_data_list);
307
+ return 1;
308
  } else if (NULL == entry_data_list) {
309
+ THROW_EXCEPTION(PHP_MAXMINDDB_READER_EX_NS,
310
+ "Error while looking up data for %s. Your database may "
311
+ "be corrupt or you have found a bug in libmaxminddb.",
312
+ ip_address);
313
+ return 1;
 
 
314
  }
315
 
316
+ handle_entry_data_list(entry_data_list, record TSRMLS_CC);
 
 
 
 
 
 
317
  MMDB_free_entry_data_list(entry_data_list);
318
+ return 0;
319
  }
320
 
321
+ ZEND_BEGIN_ARG_INFO_EX(arginfo_maxmindbreader_void, 0, 0, 0)
322
  ZEND_END_ARG_INFO()
323
 
324
  PHP_METHOD(MaxMind_Db_Reader, metadata) {
325
+ if (ZEND_NUM_ARGS() != 0) {
326
+ THROW_EXCEPTION("InvalidArgumentException",
327
+ "Method takes no arguments.");
 
 
 
 
328
  return;
329
  }
330
 
331
  const maxminddb_obj *const mmdb_obj =
332
+ (maxminddb_obj *)Z_MAXMINDDB_P(getThis());
333
 
334
  if (NULL == mmdb_obj->mmdb) {
335
+ THROW_EXCEPTION("BadMethodCallException",
336
+ "Attempt to read from a closed MaxMind DB.");
 
337
  return;
338
  }
339
 
340
+ const char *const name = ZEND_NS_NAME(PHP_MAXMINDDB_READER_NS, "Metadata");
341
+ zend_class_entry *metadata_ce = lookup_class(name TSRMLS_CC);
342
+
343
  object_init_ex(return_value, metadata_ce);
344
 
345
+ #ifdef ZEND_ENGINE_3
346
+ zval _metadata_array;
347
+ zval *metadata_array = &_metadata_array;
348
+ ZVAL_NULL(metadata_array);
349
+ #else
350
+ zval *metadata_array;
351
+ ALLOC_INIT_ZVAL(metadata_array);
352
+ #endif
353
+
354
  MMDB_entry_data_list_s *entry_data_list;
355
  MMDB_get_metadata_as_entry_data_list(mmdb_obj->mmdb, &entry_data_list);
356
 
357
+ handle_entry_data_list(entry_data_list, metadata_array TSRMLS_CC);
 
 
 
 
 
358
  MMDB_free_entry_data_list(entry_data_list);
359
+ #if PHP_VERSION_ID >= 80000
360
+ zend_call_method_with_1_params(Z_OBJ_P(return_value),
361
  metadata_ce,
362
  &metadata_ce->constructor,
363
  ZEND_CONSTRUCTOR_FUNC_NAME,
364
  NULL,
365
+ metadata_array);
366
+ zval_ptr_dtor(metadata_array);
367
+ #elif defined(ZEND_ENGINE_3)
368
+ zend_call_method_with_1_params(return_value,
369
+ metadata_ce,
370
+ &metadata_ce->constructor,
371
+ ZEND_CONSTRUCTOR_FUNC_NAME,
372
+ NULL,
373
+ metadata_array);
374
+ zval_ptr_dtor(metadata_array);
375
+ #else
376
+ zend_call_method_with_1_params(&return_value,
377
+ metadata_ce,
378
+ &metadata_ce->constructor,
379
+ ZEND_CONSTRUCTOR_FUNC_NAME,
380
+ NULL,
381
+ metadata_array);
382
  zval_ptr_dtor(&metadata_array);
383
+ #endif
384
  }
385
 
386
  PHP_METHOD(MaxMind_Db_Reader, close) {
387
+ if (ZEND_NUM_ARGS() != 0) {
388
+ THROW_EXCEPTION("InvalidArgumentException",
389
+ "Method takes no arguments.");
 
 
 
 
390
  return;
391
  }
392
 
393
+ maxminddb_obj *mmdb_obj = (maxminddb_obj *)Z_MAXMINDDB_P(getThis());
394
 
395
  if (NULL == mmdb_obj->mmdb) {
396
+ THROW_EXCEPTION("BadMethodCallException",
397
+ "Attempt to close a closed MaxMind DB.");
 
398
  return;
399
  }
400
  MMDB_close(mmdb_obj->mmdb);
411
  case MMDB_DATA_TYPE_ARRAY:
412
  return handle_array(entry_data_list, z_value TSRMLS_CC);
413
  case MMDB_DATA_TYPE_UTF8_STRING:
414
+ _ZVAL_STRINGL(z_value,
415
+ (char *)entry_data_list->entry_data.utf8_string,
416
+ entry_data_list->entry_data.data_size);
417
  break;
418
  case MMDB_DATA_TYPE_BYTES:
419
+ _ZVAL_STRINGL(z_value,
420
+ (char *)entry_data_list->entry_data.bytes,
421
+ entry_data_list->entry_data.data_size);
422
  break;
423
  case MMDB_DATA_TYPE_DOUBLE:
424
  ZVAL_DOUBLE(z_value, entry_data_list->entry_data.double_value);
445
  ZVAL_LONG(z_value, entry_data_list->entry_data.int32);
446
  break;
447
  default:
448
+ THROW_EXCEPTION(PHP_MAXMINDDB_READER_EX_NS,
449
+ "Invalid data type arguments: %d",
450
+ entry_data_list->entry_data.type);
 
451
  return NULL;
452
  }
453
  return entry_data_list;
466
  char *key = estrndup((char *)entry_data_list->entry_data.utf8_string,
467
  entry_data_list->entry_data.data_size);
468
  if (NULL == key) {
469
+ THROW_EXCEPTION(PHP_MAXMINDDB_READER_EX_NS,
470
+ "Invalid data type arguments");
 
471
  return NULL;
472
  }
473
 
474
  entry_data_list = entry_data_list->next;
475
+ #ifdef ZEND_ENGINE_3
476
+ zval _new_value;
477
+ zval *new_value = &_new_value;
478
+ ZVAL_NULL(new_value);
479
+ #else
480
+ zval *new_value;
481
+ ALLOC_INIT_ZVAL(new_value);
482
+ #endif
483
  entry_data_list =
484
+ handle_entry_data_list(entry_data_list, new_value TSRMLS_CC);
485
+ add_assoc_zval(z_value, key, new_value);
 
 
486
  efree(key);
487
  }
488
  return entry_data_list;
498
  uint i;
499
  for (i = 0; i < size && entry_data_list; i++) {
500
  entry_data_list = entry_data_list->next;
501
+ #ifdef ZEND_ENGINE_3
502
+ zval _new_value;
503
+ zval *new_value = &_new_value;
504
+ ZVAL_NULL(new_value);
505
+ #else
506
+ zval *new_value;
507
+ ALLOC_INIT_ZVAL(new_value);
508
+ #endif
509
  entry_data_list =
510
+ handle_entry_data_list(entry_data_list, new_value TSRMLS_CC);
511
+ add_next_index_zval(z_value, new_value);
 
 
512
  }
513
  return entry_data_list;
514
  }
535
  spprintf(&num_str, 0, "0x%016" PRIX64 "%016" PRIX64, high, low);
536
  CHECK_ALLOCATED(num_str);
537
 
538
+ _ZVAL_STRING(z_value, num_str);
539
  efree(num_str);
540
  }
541
 
556
  spprintf(&int_str, 0, "%" PRIu32, val);
557
  CHECK_ALLOCATED(int_str);
558
 
559
+ _ZVAL_STRING(z_value, int_str);
560
  efree(int_str);
561
  #endif
562
  }
578
  spprintf(&int_str, 0, "%" PRIu64, val);
579
  CHECK_ALLOCATED(int_str);
580
 
581
+ _ZVAL_STRING(z_value, int_str);
582
  efree(int_str);
583
  #endif
584
  }
585
 
586
+ static zend_class_entry *lookup_class(const char *name TSRMLS_DC) {
587
+ #ifdef ZEND_ENGINE_3
588
+ zend_string *n = zend_string_init(name, strlen(name), 0);
589
+ zend_class_entry *ce = zend_lookup_class(n);
590
+ zend_string_release(n);
591
+ if (NULL == ce) {
592
+ zend_error(E_ERROR, "Class %s not found", name);
593
+ }
594
+ return ce;
595
+ #else
596
+ zend_class_entry **ce;
597
+ if (FAILURE == zend_lookup_class(name, strlen(name), &ce TSRMLS_CC)) {
598
+ zend_error(E_ERROR, "Class %s not found", name);
599
+ }
600
+ return *ce;
601
+ #endif
602
+ }
603
+
604
  static void maxminddb_free_storage(free_obj_t *object TSRMLS_DC) {
605
  maxminddb_obj *obj =
606
  php_maxminddb_fetch_object((zend_object *)object TSRMLS_CC);
610
  }
611
 
612
  zend_object_std_dtor(&obj->std TSRMLS_CC);
613
+ #ifndef ZEND_ENGINE_3
614
+ efree(object);
615
+ #endif
616
  }
617
 
618
+ #ifdef ZEND_ENGINE_3
619
  static zend_object *maxminddb_create_handler(zend_class_entry *type TSRMLS_DC) {
620
  maxminddb_obj *obj = (maxminddb_obj *)ecalloc(1, sizeof(maxminddb_obj));
621
  zend_object_std_init(&obj->std, type TSRMLS_CC);
625
 
626
  return &obj->std;
627
  }
628
+ #else
629
+ static zend_object_value
630
+ maxminddb_create_handler(zend_class_entry *type TSRMLS_DC) {
631
+ zend_object_value retval;
632
 
633
+ maxminddb_obj *obj = (maxminddb_obj *)ecalloc(1, sizeof(maxminddb_obj));
634
+ zend_object_std_init(&obj->std, type TSRMLS_CC);
635
+ object_properties_init(&(obj->std), type);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
636
 
637
+ retval.handle = zend_objects_store_put(
638
+ obj, NULL, maxminddb_free_storage, NULL TSRMLS_CC);
639
+ retval.handlers = &maxminddb_obj_handlers;
 
 
 
 
 
 
 
 
 
640
 
641
+ return retval;
 
 
 
 
 
 
642
  }
643
+ #endif
644
 
645
  // clang-format off
646
+ static zend_function_entry maxminddb_methods[] = {
647
+ PHP_ME(MaxMind_Db_Reader, __construct, arginfo_maxmindbreader_construct,
648
+ ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
649
+ PHP_ME(MaxMind_Db_Reader, close, arginfo_maxmindbreader_void, ZEND_ACC_PUBLIC)
650
+ PHP_ME(MaxMind_Db_Reader, get, arginfo_maxmindbreader_get, ZEND_ACC_PUBLIC)
651
+ PHP_ME(MaxMind_Db_Reader, getWithPrefixLen, arginfo_maxmindbreader_get, ZEND_ACC_PUBLIC)
652
+ PHP_ME(MaxMind_Db_Reader, metadata, arginfo_maxmindbreader_void, ZEND_ACC_PUBLIC)
653
+ { NULL, NULL, NULL }
654
  };
655
  // clang-format on
656
 
657
  PHP_MINIT_FUNCTION(maxminddb) {
658
  zend_class_entry ce;
659
 
 
 
 
 
660
  INIT_CLASS_ENTRY(ce, PHP_MAXMINDDB_READER_NS, maxminddb_methods);
661
  maxminddb_ce = zend_register_internal_class(&ce TSRMLS_CC);
662
  maxminddb_ce->create_object = maxminddb_create_handler;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
663
  memcpy(&maxminddb_obj_handlers,
664
  zend_get_std_object_handlers(),
665
  sizeof(zend_object_handlers));
666
  maxminddb_obj_handlers.clone_obj = NULL;
667
+ #ifdef ZEND_ENGINE_3
668
  maxminddb_obj_handlers.offset = XtOffsetOf(maxminddb_obj, std);
669
  maxminddb_obj_handlers.free_obj = maxminddb_free_storage;
670
+ #endif
671
  zend_declare_class_constant_string(maxminddb_ce,
672
  "MMDB_LIB_VERSION",
673
  sizeof("MMDB_LIB_VERSION") - 1,
includes/vendor/maxmind-db/reader/ext/php_maxminddb.h CHANGED
@@ -15,7 +15,7 @@
15
 
16
  #ifndef PHP_MAXMINDDB_H
17
  #define PHP_MAXMINDDB_H 1
18
- #define PHP_MAXMINDDB_VERSION "1.8.0"
19
  #define PHP_MAXMINDDB_EXTNAME "maxminddb"
20
 
21
  extern zend_module_entry maxminddb_module_entry;
15
 
16
  #ifndef PHP_MAXMINDDB_H
17
  #define PHP_MAXMINDDB_H 1
18
+ #define PHP_MAXMINDDB_VERSION "1.6.0"
19
  #define PHP_MAXMINDDB_EXTNAME "maxminddb"
20
 
21
  extern zend_module_entry maxminddb_module_entry;
includes/vendor/maxmind-db/reader/package.xml DELETED
@@ -1,60 +0,0 @@
1
- <?xml version="1.0"?>
2
- <package version="2.0" xmlns="http://pear.php.net/dtd/package-2.0"
3
- xmlns:tasks="http://pear.php.net/dtd/tasks-1.0"
4
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5
- xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 http://pear.php.net/dtd/package-2.0.xsd">
6
-
7
- <name>maxminddb</name>
8
- <channel>pecl.php.net</channel>
9
- <summary>Reader for the MaxMind DB file format</summary>
10
- <description>This is the PHP extension for reading MaxMind DB files. MaxMind DB is a binary file format that stores data indexed by IP address subnets (IPv4 or IPv6).</description>
11
- <lead>
12
- <name>Greg Oschwald</name>
13
- <user>oschwald</user>
14
- <email>goschwald@maxmind.com</email>
15
- <active>yes</active>
16
- </lead>
17
- <date>2020-10-01</date>
18
- <version>
19
- <release>1.8.0</release>
20
- <api>1.7.0</api>
21
- </version>
22
- <stability>
23
- <release>stable</release>
24
- <api>stable</api>
25
- </stability>
26
- <license uri="https://github.com/maxmind/MaxMind-DB-Reader-php/blob/master/LICENSE">Apache License 2.0</license>
27
- <notes>* Fixes for PHP 8.0. Pull Request by Remi Collet. GitHub #108.</notes>
28
- <contents>
29
- <dir name="/">
30
- <file role="doc" name="LICENSE"/>
31
- <file role="doc" name="CHANGELOG.md"/>
32
- <file role="doc" name="README.md"/>
33
-
34
- <dir name="ext">
35
- <file role="src" name="config.m4"/>
36
-
37
- <file role="src" name="maxminddb.c"/>
38
- <file role="src" name="php_maxminddb.h"/>
39
-
40
- <dir name="tests">
41
- <file role="test" name="001-load.phpt"/>
42
- <file role="test" name="002-final.phpt"/>
43
- <file role="test" name="003-open-basedir.phpt"/>
44
- </dir>
45
- </dir>
46
- </dir>
47
- </contents>
48
- <dependencies>
49
- <required>
50
- <php>
51
- <min>7.2.0</min>
52
- </php>
53
- <pearinstaller>
54
- <min>1.10.0</min>
55
- </pearinstaller>
56
- </required>
57
- </dependencies>
58
- <providesextension>maxminddb</providesextension>
59
- <extsrcrelease />
60
- </package>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/vendor/maxmind-db/reader/src/MaxMind/Db/Reader.php CHANGED
@@ -1,10 +1,7 @@
1
  <?php
2
 
3
- declare(strict_types=1);
4
-
5
  namespace MaxMind\Db;
6
 
7
- use ArgumentCountError;
8
  use BadMethodCallException;
9
  use Exception;
10
  use InvalidArgumentException;
@@ -20,42 +17,15 @@ use UnexpectedValueException;
20
  */
21
  class Reader
22
  {
23
- /**
24
- * @var int
25
- */
26
  private static $DATA_SECTION_SEPARATOR_SIZE = 16;
27
- /**
28
- * @var string
29
- */
30
  private static $METADATA_START_MARKER = "\xAB\xCD\xEFMaxMind.com";
31
- /**
32
- * @var int
33
- */
34
  private static $METADATA_START_MARKER_LENGTH = 14;
35
- /**
36
- * @var int
37
- */
38
- private static $METADATA_MAX_SIZE = 131072; // 128 * 1024 = 128KiB
39
 
40
- /**
41
- * @var Decoder
42
- */
43
  private $decoder;
44
- /**
45
- * @var resource
46
- */
47
  private $fileHandle;
48
- /**
49
- * @var int
50
- */
51
  private $fileSize;
52
- /**
53
- * @var int
54
- */
55
  private $ipV4Start;
56
- /**
57
- * @var Metadata
58
- */
59
  private $metadata;
60
 
61
  /**
@@ -65,38 +35,40 @@ class Reader
65
  * @param string $database
66
  * the MaxMind DB file to use
67
  *
68
- * @throws InvalidArgumentException for invalid database path or unknown arguments
69
- * @throws InvalidDatabaseException
70
- * if the database is invalid or there is an error reading
71
- * from it
72
  */
73
- public function __construct(string $database)
74
  {
75
  if (\func_num_args() !== 1) {
76
- throw new ArgumentCountError(
77
- sprintf('%s() expects exactly 1 parameter, %d given', __METHOD__, \func_num_args())
78
  );
79
  }
80
 
81
- $fileHandle = @fopen($database, 'rb');
82
- if ($fileHandle === false) {
83
  throw new InvalidArgumentException(
84
  "The file \"$database\" does not exist or is not readable."
85
  );
86
  }
87
- $this->fileHandle = $fileHandle;
88
-
89
- $fileSize = @filesize($database);
90
- if ($fileSize === false) {
 
 
 
 
91
  throw new UnexpectedValueException(
92
  "Error determining the size of \"$database\"."
93
  );
94
  }
95
- $this->fileSize = $fileSize;
96
 
97
  $start = $this->findMetadataStart($database);
98
  $metadataDecoder = new Decoder($this->fileHandle, $start);
99
- [$metadataArray] = $metadataDecoder->decode($start);
100
  $this->metadata = new Metadata($metadataArray);
101
  $this->decoder = new Decoder(
102
  $this->fileHandle,
@@ -119,14 +91,14 @@ class Reader
119
  *
120
  * @return mixed the record for the IP address
121
  */
122
- public function get(string $ipAddress)
123
  {
124
  if (\func_num_args() !== 1) {
125
- throw new ArgumentCountError(
126
- sprintf('%s() expects exactly 1 parameter, %d given', __METHOD__, \func_num_args())
127
  );
128
  }
129
- [$record] = $this->getWithPrefixLen($ipAddress);
130
 
131
  return $record;
132
  }
@@ -146,11 +118,11 @@ class Reader
146
  * @return array an array where the first element is the record and the
147
  * second the network prefix length for the record
148
  */
149
- public function getWithPrefixLen(string $ipAddress): array
150
  {
151
  if (\func_num_args() !== 1) {
152
- throw new ArgumentCountError(
153
- sprintf('%s() expects exactly 1 parameter, %d given', __METHOD__, \func_num_args())
154
  );
155
  }
156
 
@@ -160,7 +132,13 @@ class Reader
160
  );
161
  }
162
 
163
- [$pointer, $prefixLen] = $this->findAddressInTree($ipAddress);
 
 
 
 
 
 
164
  if ($pointer === 0) {
165
  return [null, $prefixLen];
166
  }
@@ -168,16 +146,9 @@ class Reader
168
  return [$this->resolveDataPointer($pointer), $prefixLen];
169
  }
170
 
171
- private function findAddressInTree(string $ipAddress): array
172
  {
173
- $packedAddr = @inet_pton($ipAddress);
174
- if ($packedAddr === false) {
175
- throw new InvalidArgumentException(
176
- "The value \"$ipAddress\" is not a valid IP address."
177
- );
178
- }
179
-
180
- $rawAddress = unpack('C*', $packedAddr);
181
 
182
  $bitCount = \count($rawAddress) * 8;
183
 
@@ -218,7 +189,7 @@ class Reader
218
  throw new InvalidDatabaseException('Something bad happened');
219
  }
220
 
221
- private function ipV4StartNode(): int
222
  {
223
  // If we have an IPv4 database, the start node is the first node
224
  if ($this->metadata->ipVersion === 4) {
@@ -234,14 +205,14 @@ class Reader
234
  return $node;
235
  }
236
 
237
- private function readNode(int $nodeNumber, int $index): int
238
  {
239
  $baseOffset = $nodeNumber * $this->metadata->nodeByteSize;
240
 
241
  switch ($this->metadata->recordSize) {
242
  case 24:
243
  $bytes = Util::read($this->fileHandle, $baseOffset + $index * 3, 3);
244
- [, $node] = unpack('N', "\x00" . $bytes);
245
 
246
  return $node;
247
  case 28:
@@ -251,12 +222,12 @@ class Reader
251
  } else {
252
  $middle = 0x0F & \ord($bytes[0]);
253
  }
254
- [, $node] = unpack('N', \chr($middle) . substr($bytes, $index, 3));
255
 
256
  return $node;
257
  case 32:
258
  $bytes = Util::read($this->fileHandle, $baseOffset + $index * 4, 4);
259
- [, $node] = unpack('N', $bytes);
260
 
261
  return $node;
262
  default:
@@ -267,10 +238,7 @@ class Reader
267
  }
268
  }
269
 
270
- /**
271
- * @return mixed
272
- */
273
- private function resolveDataPointer(int $pointer)
274
  {
275
  $resolved = $pointer - $this->metadata->nodeCount
276
  + $this->metadata->searchTreeSize;
@@ -280,7 +248,7 @@ class Reader
280
  );
281
  }
282
 
283
- [$data] = $this->decoder->decode($resolved);
284
 
285
  return $data;
286
  }
@@ -290,7 +258,7 @@ class Reader
290
  * are much faster algorithms (e.g., Boyer-Moore) for this if speed is ever
291
  * an issue, but I suspect it won't be.
292
  */
293
- private function findMetadataStart(string $filename): int
294
  {
295
  $handle = $this->fileHandle;
296
  $fstat = fstat($handle);
@@ -322,11 +290,11 @@ class Reader
322
  *
323
  * @return Metadata object for the database
324
  */
325
- public function metadata(): Metadata
326
  {
327
  if (\func_num_args()) {
328
- throw new ArgumentCountError(
329
- sprintf('%s() expects exactly 0 parameters, %d given', __METHOD__, \func_num_args())
330
  );
331
  }
332
 
@@ -338,7 +306,7 @@ class Reader
338
  );
339
  }
340
 
341
- return clone $this->metadata;
342
  }
343
 
344
  /**
@@ -347,14 +315,8 @@ class Reader
347
  * @throws Exception
348
  * if an I/O error occurs
349
  */
350
- public function close(): void
351
  {
352
- if (\func_num_args()) {
353
- throw new ArgumentCountError(
354
- sprintf('%s() expects exactly 0 parameters, %d given', __METHOD__, \func_num_args())
355
- );
356
- }
357
-
358
  if (!\is_resource($this->fileHandle)) {
359
  throw new BadMethodCallException(
360
  'Attempt to close a closed MaxMind DB.'
1
  <?php
2
 
 
 
3
  namespace MaxMind\Db;
4
 
 
5
  use BadMethodCallException;
6
  use Exception;
7
  use InvalidArgumentException;
17
  */
18
  class Reader
19
  {
 
 
 
20
  private static $DATA_SECTION_SEPARATOR_SIZE = 16;
 
 
 
21
  private static $METADATA_START_MARKER = "\xAB\xCD\xEFMaxMind.com";
 
 
 
22
  private static $METADATA_START_MARKER_LENGTH = 14;
23
+ private static $METADATA_MAX_SIZE = 131072; // 128 * 1024 = 128KB
 
 
 
24
 
 
 
 
25
  private $decoder;
 
 
 
26
  private $fileHandle;
 
 
 
27
  private $fileSize;
 
 
 
28
  private $ipV4Start;
 
 
 
29
  private $metadata;
30
 
31
  /**
35
  * @param string $database
36
  * the MaxMind DB file to use
37
  *
38
+ * @throws InvalidArgumentException for invalid database path or unknown arguments
39
+ * @throws \MaxMind\Db\Reader\InvalidDatabaseException
40
+ * if the database is invalid or there is an error reading
41
+ * from it
42
  */
43
+ public function __construct($database)
44
  {
45
  if (\func_num_args() !== 1) {
46
+ throw new InvalidArgumentException(
47
+ 'The constructor takes exactly one argument.'
48
  );
49
  }
50
 
51
+ if (!is_readable($database)) {
 
52
  throw new InvalidArgumentException(
53
  "The file \"$database\" does not exist or is not readable."
54
  );
55
  }
56
+ $this->fileHandle = @fopen($database, 'rb');
57
+ if ($this->fileHandle === false) {
58
+ throw new InvalidArgumentException(
59
+ "Error opening \"$database\"."
60
+ );
61
+ }
62
+ $this->fileSize = @filesize($database);
63
+ if ($this->fileSize === false) {
64
  throw new UnexpectedValueException(
65
  "Error determining the size of \"$database\"."
66
  );
67
  }
 
68
 
69
  $start = $this->findMetadataStart($database);
70
  $metadataDecoder = new Decoder($this->fileHandle, $start);
71
+ list($metadataArray) = $metadataDecoder->decode($start);
72
  $this->metadata = new Metadata($metadataArray);
73
  $this->decoder = new Decoder(
74
  $this->fileHandle,
91
  *
92
  * @return mixed the record for the IP address
93
  */
94
+ public function get($ipAddress)
95
  {
96
  if (\func_num_args() !== 1) {
97
+ throw new InvalidArgumentException(
98
+ 'Method takes exactly one argument.'
99
  );
100
  }
101
+ list($record) = $this->getWithPrefixLen($ipAddress);
102
 
103
  return $record;
104
  }
118
  * @return array an array where the first element is the record and the
119
  * second the network prefix length for the record
120
  */
121
+ public function getWithPrefixLen($ipAddress)
122
  {
123
  if (\func_num_args() !== 1) {
124
+ throw new InvalidArgumentException(
125
+ 'Method takes exactly one argument.'
126
  );
127
  }
128
 
132
  );
133
  }
134
 
135
+ if (!filter_var($ipAddress, FILTER_VALIDATE_IP)) {
136
+ throw new InvalidArgumentException(
137
+ "The value \"$ipAddress\" is not a valid IP address."
138
+ );
139
+ }
140
+
141
+ list($pointer, $prefixLen) = $this->findAddressInTree($ipAddress);
142
  if ($pointer === 0) {
143
  return [null, $prefixLen];
144
  }
146
  return [$this->resolveDataPointer($pointer), $prefixLen];
147
  }
148
 
149
+ private function findAddressInTree($ipAddress)
150
  {
151
+ $rawAddress = unpack('C*', inet_pton($ipAddress));
 
 
 
 
 
 
 
152
 
153
  $bitCount = \count($rawAddress) * 8;
154
 
189
  throw new InvalidDatabaseException('Something bad happened');
190
  }
191
 
192
+ private function ipV4StartNode()
193
  {
194
  // If we have an IPv4 database, the start node is the first node
195
  if ($this->metadata->ipVersion === 4) {
205
  return $node;
206
  }
207
 
208
+ private function readNode($nodeNumber, $index)
209
  {
210
  $baseOffset = $nodeNumber * $this->metadata->nodeByteSize;
211
 
212
  switch ($this->metadata->recordSize) {
213
  case 24:
214
  $bytes = Util::read($this->fileHandle, $baseOffset + $index * 3, 3);
215
+ list(, $node) = unpack('N', "\x00" . $bytes);
216
 
217
  return $node;
218
  case 28:
222
  } else {
223
  $middle = 0x0F & \ord($bytes[0]);
224
  }
225
+ list(, $node) = unpack('N', \chr($middle) . substr($bytes, $index, 3));
226
 
227
  return $node;
228
  case 32:
229
  $bytes = Util::read($this->fileHandle, $baseOffset + $index * 4, 4);
230
+ list(, $node) = unpack('N', $bytes);
231
 
232
  return $node;
233
  default:
238
  }
239
  }
240
 
241
+ private function resolveDataPointer($pointer)
 
 
 
242
  {
243
  $resolved = $pointer - $this->metadata->nodeCount
244
  + $this->metadata->searchTreeSize;
248
  );
249
  }
250
 
251
+ list($data) = $this->decoder->decode($resolved);
252
 
253
  return $data;
254
  }
258
  * are much faster algorithms (e.g., Boyer-Moore) for this if speed is ever
259
  * an issue, but I suspect it won't be.
260
  */
261
+ private function findMetadataStart($filename)
262
  {
263
  $handle = $this->fileHandle;
264
  $fstat = fstat($handle);
290
  *
291
  * @return Metadata object for the database
292
  */
293
+ public function metadata()
294
  {
295
  if (\func_num_args()) {
296
+ throw new InvalidArgumentException(
297
+ 'Method takes no arguments.'
298
  );
299
  }
300
 
306
  );
307
  }
308
 
309
+ return $this->metadata;
310
  }
311
 
312
  /**
315
  * @throws Exception
316
  * if an I/O error occurs
317
  */
318
+ public function close()
319
  {
 
 
 
 
 
 
320
  if (!\is_resource($this->fileHandle)) {
321
  throw new BadMethodCallException(
322
  'Attempt to close a closed MaxMind DB.'
includes/vendor/maxmind-db/reader/src/MaxMind/Db/Reader/Decoder.php CHANGED
@@ -1,7 +1,5 @@
1
  <?php
2
 
3
- declare(strict_types=1);
4
-
5
  namespace MaxMind\Db\Reader;
6
 
7
  // @codingStandardsIgnoreLine
@@ -16,53 +14,50 @@ use RuntimeException;
16
 
17
  class Decoder
18
  {
19
- /**
20
- * @var resource
21
- */
22
  private $fileStream;
23
- /**
24
- * @var int
25
- */
26
  private $pointerBase;
27
- /**
28
- * @var float
29
- */
30
  private $pointerBaseByteSize;
31
- /**
32
- * This is only used for unit testing.
33
- *
34
- * @var bool
35
- */
36
  private $pointerTestHack;
37
- /**
38
- * @var bool
39
- */
40
  private $switchByteOrder;
41
 
42
- private const _EXTENDED = 0;
43
- private const _POINTER = 1;
44
- private const _UTF8_STRING = 2;
45
- private const _DOUBLE = 3;
46
- private const _BYTES = 4;
47
- private const _UINT16 = 5;
48
- private const _UINT32 = 6;
49
- private const _MAP = 7;
50
- private const _INT32 = 8;
51
- private const _UINT64 = 9;
52
- private const _UINT128 = 10;
53
- private const _ARRAY = 11;
54
- private const _CONTAINER = 12;
55
- private const _END_MARKER = 13;
56
- private const _BOOLEAN = 14;
57
- private const _FLOAT = 15;
58
-
59
- /**
60
- * @param resource $fileStream
61
- */
 
 
 
 
 
 
 
 
 
 
 
 
 
62
  public function __construct(
63
  $fileStream,
64
- int $pointerBase = 0,
65
- bool $pointerTestHack = false
66
  ) {
67
  $this->fileStream = $fileStream;
68
  $this->pointerBase = $pointerBase;
@@ -73,7 +68,7 @@ class Decoder
73
  $this->switchByteOrder = $this->isPlatformLittleEndian();
74
  }
75
 
76
- public function decode(int $offset): array
77
  {
78
  $ctrlByte = \ord(Util::read($this->fileStream, $offset, 1));
79
  ++$offset;
@@ -84,14 +79,14 @@ class Decoder
84
  // use the size to determine the length of the pointer and then follow
85
  // it.
86
  if ($type === self::_POINTER) {
87
- [$pointer, $offset] = $this->decodePointer($ctrlByte, $offset);
88
 
89
  // for unit testing
90
  if ($this->pointerTestHack) {
91
  return [$pointer];
92
  }
93
 
94
- [$result] = $this->decode($pointer);
95
 
96
  return [$result, $offset];
97
  }
@@ -113,12 +108,12 @@ class Decoder
113
  ++$offset;
114
  }
115
 
116
- [$size, $offset] = $this->sizeFromCtrlByte($ctrlByte, $offset);
117
 
118
  return $this->decodeByType($type, $offset, $size);
119
  }
120
 
121
- private function decodeByType(int $type, int $offset, int $size): array
122
  {
123
  switch ($type) {
124
  case self::_MAP:
@@ -157,7 +152,7 @@ class Decoder
157
  }
158
  }
159
 
160
- private function verifySize(int $expected, int $actual): void
161
  {
162
  if ($expected !== $actual) {
163
  throw new InvalidDatabaseException(
@@ -166,42 +161,50 @@ class Decoder
166
  }
167
  }
168
 
169
- private function decodeArray(int $size, int $offset): array
170
  {
171
  $array = [];
172
 
173
  for ($i = 0; $i < $size; ++$i) {
174
- [$value, $offset] = $this->decode($offset);
175
  array_push($array, $value);
176
  }
177
 
178
  return [$array, $offset];
179
  }
180
 
181
- private function decodeBoolean(int $size): bool
182
  {
183
- return $size !== 0;
184
  }
185
 
186
- private function decodeDouble(string $bytes): float
187
  {
188
  // This assumes IEEE 754 doubles, but most (all?) modern platforms
189
  // use them.
190
- [, $double] = unpack('E', $bytes);
 
 
 
 
191
 
192
  return $double;
193
  }
194
 
195
- private function decodeFloat(string $bytes): float
196
  {
197
  // This assumes IEEE 754 floats, but most (all?) modern platforms
198
  // use them.
199
- [, $float] = unpack('G', $bytes);
 
 
 
 
200
 
201
  return $float;
202
  }
203
 
204
- private function decodeInt32(string $bytes, int $size): int
205
  {
206
  switch ($size) {
207
  case 0:
@@ -219,25 +222,25 @@ class Decoder
219
  );
220
  }
221
 
222
- [, $int] = unpack('l', $this->maybeSwitchByteOrder($bytes));
223
 
224
  return $int;
225
  }
226
 
227
- private function decodeMap(int $size, int $offset): array
228
  {
229
  $map = [];
230
 
231
  for ($i = 0; $i < $size; ++$i) {
232
- [$key, $offset] = $this->decode($offset);
233
- [$value, $offset] = $this->decode($offset);
234
  $map[$key] = $value;
235
  }
236
 
237
  return [$map, $offset];
238
  }
239
 
240
- private function decodePointer(int $ctrlByte, int $offset): array
241
  {
242
  $pointerSize = (($ctrlByte >> 3) & 0x3) + 1;
243
 
@@ -247,12 +250,12 @@ class Decoder
247
  switch ($pointerSize) {
248
  case 1:
249
  $packed = \chr($ctrlByte & 0x7) . $buffer;
250
- [, $pointer] = unpack('n', $packed);
251
  $pointer += $this->pointerBase;
252
  break;
253
  case 2:
254
  $packed = "\x00" . \chr($ctrlByte & 0x7) . $buffer;
255
- [, $pointer] = unpack('N', $packed);
256
  $pointer += $this->pointerBase + 2048;
257
  break;
258
  case 3:
@@ -260,7 +263,7 @@ class Decoder
260
 
261
  // It is safe to use 'N' here, even on 32 bit machines as the
262
  // first bit is 0.
263
- [, $pointer] = unpack('N', $packed);
264
  $pointer += $this->pointerBase + 526336;
265
  break;
266
  case 4:
@@ -275,23 +278,18 @@ class Decoder
275
  } elseif (\extension_loaded('gmp')) {
276
  $pointer = gmp_strval(gmp_add($pointerOffset, $this->pointerBase));
277
  } elseif (\extension_loaded('bcmath')) {
278
- $pointer = bcadd($pointerOffset, (string) $this->pointerBase);
279
  } else {
280
  throw new RuntimeException(
281
  'The gmp or bcmath extension must be installed to read this database.'
282
  );
283
  }
284
- break;
285
- default:
286
- throw new InvalidDatabaseException(
287
- 'Unexpected pointer size ' . $pointerSize
288
- );
289
  }
290
 
291
  return [$pointer, $offset];
292
  }
293
 
294
- private function decodeUint(string $bytes, int $byteLength)
295
  {
296
  if ($byteLength === 0) {
297
  return 0;
@@ -306,9 +304,9 @@ class Decoder
306
  if ($byteLength <= _MM_MAX_INT_BYTES) {
307
  $integer = ($integer << 8) + $part;
308
  } elseif (\extension_loaded('gmp')) {
309
- $integer = gmp_strval(gmp_add(gmp_mul((string) $integer, '256'), $part));
310
  } elseif (\extension_loaded('bcmath')) {
311
- $integer = bcadd(bcmul((string) $integer, '256'), (string) $part);
312
  } else {
313
  throw new RuntimeException(
314
  'The gmp or bcmath extension must be installed to read this database.'
@@ -319,7 +317,7 @@ class Decoder
319
  return $integer;
320
  }
321
 
322
- private function sizeFromCtrlByte(int $ctrlByte, int $offset): array
323
  {
324
  $size = $ctrlByte & 0x1f;
325
 
@@ -333,22 +331,22 @@ class Decoder
333
  if ($size === 29) {
334
  $size = 29 + \ord($bytes);
335
  } elseif ($size === 30) {
336
- [, $adjust] = unpack('n', $bytes);
337
  $size = 285 + $adjust;
338
- } else {
339
- [, $adjust] = unpack('N', "\x00" . $bytes);
340
  $size = $adjust + 65821;
341
  }
342
 
343
  return [$size, $offset + $bytesToRead];
344
  }
345
 
346
- private function maybeSwitchByteOrder(string $bytes): string
347
  {
348
  return $this->switchByteOrder ? strrev($bytes) : $bytes;
349
  }
350
 
351
- private function isPlatformLittleEndian(): bool
352
  {
353
  $testint = 0x00FF;
354
  $packed = pack('S', $testint);
1
  <?php
2
 
 
 
3
  namespace MaxMind\Db\Reader;
4
 
5
  // @codingStandardsIgnoreLine
14
 
15
  class Decoder
16
  {
 
 
 
17
  private $fileStream;
 
 
 
18
  private $pointerBase;
 
 
 
19
  private $pointerBaseByteSize;
20
+ // This is only used for unit testing
 
 
 
 
21
  private $pointerTestHack;
 
 
 
22
  private $switchByteOrder;
23
 
24
+ /** @ignore */
25
+ const _EXTENDED = 0;
26
+ /** @ignore */
27
+ const _POINTER = 1;
28
+ /** @ignore */
29
+ const _UTF8_STRING = 2;
30
+ /** @ignore */
31
+ const _DOUBLE = 3;
32
+ /** @ignore */
33
+ const _BYTES = 4;
34
+ /** @ignore */
35
+ const _UINT16 = 5;
36
+ /** @ignore */
37
+ const _UINT32 = 6;
38
+ /** @ignore */
39
+ const _MAP = 7;
40
+ /** @ignore */
41
+ const _INT32 = 8;
42
+ /** @ignore */
43
+ const _UINT64 = 9;
44
+ /** @ignore */
45
+ const _UINT128 = 10;
46
+ /** @ignore */
47
+ const _ARRAY = 11;
48
+ /** @ignore */
49
+ const _CONTAINER = 12;
50
+ /** @ignore */
51
+ const _END_MARKER = 13;
52
+ /** @ignore */
53
+ const _BOOLEAN = 14;
54
+ /** @ignore */
55
+ const _FLOAT = 15;
56
+
57
  public function __construct(
58
  $fileStream,
59
+ $pointerBase = 0,
60
+ $pointerTestHack = false
61
  ) {
62
  $this->fileStream = $fileStream;
63
  $this->pointerBase = $pointerBase;
68
  $this->switchByteOrder = $this->isPlatformLittleEndian();
69
  }
70
 
71
+ public function decode($offset)
72
  {
73
  $ctrlByte = \ord(Util::read($this->fileStream, $offset, 1));
74
  ++$offset;
79
  // use the size to determine the length of the pointer and then follow
80
  // it.
81
  if ($type === self::_POINTER) {
82
+ list($pointer, $offset) = $this->decodePointer($ctrlByte, $offset);
83
 
84
  // for unit testing
85
  if ($this->pointerTestHack) {
86
  return [$pointer];
87
  }
88
 
89
+ list($result) = $this->decode($pointer);
90
 
91
  return [$result, $offset];
92
  }
108
  ++$offset;
109
  }
110
 
111
+ list($size, $offset) = $this->sizeFromCtrlByte($ctrlByte, $offset);
112
 
113
  return $this->decodeByType($type, $offset, $size);
114
  }
115
 
116
+ private function decodeByType($type, $offset, $size)
117
  {
118
  switch ($type) {
119
  case self::_MAP:
152
  }
153
  }
154
 
155
+ private function verifySize($expected, $actual)
156
  {
157
  if ($expected !== $actual) {
158
  throw new InvalidDatabaseException(
161
  }
162
  }
163
 
164
+ private function decodeArray($size, $offset)
165
  {
166
  $array = [];
167
 
168
  for ($i = 0; $i < $size; ++$i) {
169
+ list($value, $offset) = $this->decode($offset);
170
  array_push($array, $value);
171
  }
172
 
173
  return [$array, $offset];
174
  }
175
 
176
+ private function decodeBoolean($size)
177
  {
178
+ return $size === 0 ? false : true;
179
  }
180
 
181
+ private function decodeDouble($bits)
182
  {
183
  // This assumes IEEE 754 doubles, but most (all?) modern platforms
184
  // use them.
185
+ //
186
+ // We are not using the "E" format as that was only added in
187
+ // 7.0.15 and 7.1.1. As such, we must switch byte order on
188
+ // little endian machines.
189
+ list(, $double) = unpack('d', $this->maybeSwitchByteOrder($bits));
190
 
191
  return $double;
192
  }
193
 
194
+ private function decodeFloat($bits)
195
  {
196
  // This assumes IEEE 754 floats, but most (all?) modern platforms
197
  // use them.
198
+ //
199
+ // We are not using the "G" format as that was only added in
200
+ // 7.0.15 and 7.1.1. As such, we must switch byte order on
201
+ // little endian machines.
202
+ list(, $float) = unpack('f', $this->maybeSwitchByteOrder($bits));
203
 
204
  return $float;
205
  }
206
 
207
+ private function decodeInt32($bytes, $size)
208
  {
209
  switch ($size) {
210
  case 0:
222
  );
223
  }
224
 
225
+ list(, $int) = unpack('l', $this->maybeSwitchByteOrder($bytes));
226
 
227
  return $int;
228
  }
229
 
230
+ private function decodeMap($size, $offset)
231
  {
232
  $map = [];
233
 
234
  for ($i = 0; $i < $size; ++$i) {
235
+ list($key, $offset) = $this->decode($offset);
236
+ list($value, $offset) = $this->decode($offset);
237
  $map[$key] = $value;
238
  }
239
 
240
  return [$map, $offset];
241
  }
242
 
243
+ private function decodePointer($ctrlByte, $offset)
244
  {
245
  $pointerSize = (($ctrlByte >> 3) & 0x3) + 1;
246
 
250
  switch ($pointerSize) {
251
  case 1:
252
  $packed = \chr($ctrlByte & 0x7) . $buffer;
253
+ list(, $pointer) = unpack('n', $packed);
254
  $pointer += $this->pointerBase;
255
  break;
256
  case 2:
257
  $packed = "\x00" . \chr($ctrlByte & 0x7) . $buffer;
258
+ list(, $pointer) = unpack('N', $packed);
259
  $pointer += $this->pointerBase + 2048;
260
  break;
261
  case 3:
263
 
264
  // It is safe to use 'N' here, even on 32 bit machines as the
265
  // first bit is 0.
266
+ list(, $pointer) = unpack('N', $packed);
267
  $pointer += $this->pointerBase + 526336;
268
  break;
269
  case 4:
278
  } elseif (\extension_loaded('gmp')) {
279
  $pointer = gmp_strval(gmp_add($pointerOffset, $this->pointerBase));
280
  } elseif (\extension_loaded('bcmath')) {
281
+ $pointer = bcadd($pointerOffset, $this->pointerBase);
282
  } else {
283
  throw new RuntimeException(
284
  'The gmp or bcmath extension must be installed to read this database.'
285
  );
286
  }
 
 
 
 
 
287
  }
288
 
289
  return [$pointer, $offset];
290
  }
291
 
292
+ private function decodeUint($bytes, $byteLength)
293
  {
294
  if ($byteLength === 0) {
295
  return 0;
304
  if ($byteLength <= _MM_MAX_INT_BYTES) {
305
  $integer = ($integer << 8) + $part;
306
  } elseif (\extension_loaded('gmp')) {
307
+ $integer = gmp_strval(gmp_add(gmp_mul($integer, 256), $part));
308
  } elseif (\extension_loaded('bcmath')) {
309
+ $integer = bcadd(bcmul($integer, 256), $part);
310
  } else {
311
  throw new RuntimeException(
312
  'The gmp or bcmath extension must be installed to read this database.'
317
  return $integer;
318
  }
319
 
320
+ private function sizeFromCtrlByte($ctrlByte, $offset)
321
  {
322
  $size = $ctrlByte & 0x1f;
323
 
331
  if ($size === 29) {
332
  $size = 29 + \ord($bytes);
333
  } elseif ($size === 30) {
334
+ list(, $adjust) = unpack('n', $bytes);
335
  $size = 285 + $adjust;
336
+ } elseif ($size > 30) {
337
+ list(, $adjust) = unpack('N', "\x00" . $bytes);
338
  $size = $adjust + 65821;
339
  }
340
 
341
  return [$size, $offset + $bytesToRead];
342
  }
343
 
344
+ private function maybeSwitchByteOrder($bytes)
345
  {
346
  return $this->switchByteOrder ? strrev($bytes) : $bytes;
347
  }
348
 
349
+ private function isPlatformLittleEndian()
350
  {
351
  $testint = 0x00FF;
352
  $packed = pack('S', $testint);
includes/vendor/maxmind-db/reader/src/MaxMind/Db/Reader/InvalidDatabaseException.php CHANGED
@@ -1,7 +1,5 @@
1
  <?php
2
 
3
- declare(strict_types=1);
4
-
5
  namespace MaxMind\Db\Reader;
6
 
7
  use Exception;
1
  <?php
2
 
 
 
3
  namespace MaxMind\Db\Reader;
4
 
5
  use Exception;
includes/vendor/maxmind-db/reader/src/MaxMind/Db/Reader/Metadata.php CHANGED
@@ -1,100 +1,71 @@
1
  <?php
2
 
3
- declare(strict_types=1);
4
-
5
  namespace MaxMind\Db\Reader;
6
 
7
- use ArgumentCountError;
8
-
9
  /**
10
  * This class provides the metadata for the MaxMind DB file.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
  */
12
  class Metadata
13
  {
14
- /**
15
- * This is an unsigned 16-bit integer indicating the major version number
16
- * for the database's binary format.
17
- *
18
- * @var int
19
- */
20
- public $binaryFormatMajorVersion;
21
- /**
22
- * This is an unsigned 16-bit integer indicating the minor version number
23
- * for the database's binary format.
24
- *
25
- * @var int
26
- */
27
- public $binaryFormatMinorVersion;
28
- /**
29
- * This is an unsigned 64-bit integer that contains the database build
30
- * timestamp as a Unix epoch value.
31
- *
32
- * @var int
33
- */
34
- public $buildEpoch;
35
- /**
36
- * This is a string that indicates the structure of each data record
37
- * associated with an IP address. The actual definition of these
38
- * structures is left up to the database creator.
39
- *
40
- * @var string
41
- */
42
- public $databaseType;
43
- /**
44
- * This key will always point to a map (associative array). The keys of
45
- * that map will be language codes, and the values will be a description
46
- * in that language as a UTF-8 string. May be undefined for some
47
- * databases.
48
- *
49
- * @var array
50
- */
51
- public $description;
52
- /**
53
- * This is an unsigned 16-bit integer which is always 4 or 6. It indicates
54
- * whether the database contains IPv4 or IPv6 address data.
55
- *
56
- * @var int
57
- */
58
- public $ipVersion;
59
- /**
60
- * An array of strings, each of which is a language code. A given record
61
- * may contain data items that have been localized to some or all of
62
- * these languages. This may be undefined.
63
- *
64
- * @var array
65
- */
66
- public $languages;
67
- /**
68
- * @var int
69
- */
70
- public $nodeByteSize;
71
- /**
72
- * This is an unsigned 32-bit integer indicating the number of nodes in
73
- * the search tree.
74
- *
75
- * @var int
76
- */
77
- public $nodeCount;
78
- /**
79
- * This is an unsigned 16-bit integer. It indicates the number of bits in a
80
- * record in the search tree. Note that each node consists of two records.
81
- *
82
- * @var int
83
- */
84
- public $recordSize;
85
- /**
86
- * @var int
87
- */
88
- public $searchTreeSize;
89
 
90
- public function __construct(array $metadata)
91
  {
92
- if (\func_num_args() !== 1) {
93
- throw new ArgumentCountError(
94
- sprintf('%s() expects exactly 1 parameter, %d given', __METHOD__, \func_num_args())
95
- );
96
- }
97
-
98
  $this->binaryFormatMajorVersion =
99
  $metadata['binary_format_major_version'];
100
  $this->binaryFormatMinorVersion =
@@ -109,4 +80,9 @@ class Metadata
109
  $this->nodeByteSize = $this->recordSize / 4;
110
  $this->searchTreeSize = $this->nodeCount * $this->nodeByteSize;
111
  }
 
 
 
 
 
112
  }
1
  <?php
2
 
 
 
3
  namespace MaxMind\Db\Reader;
4
 
 
 
5
  /**
6
  * This class provides the metadata for the MaxMind DB file.
7
+ *
8
+ * @property int $nodeCount This is an unsigned 32-bit
9
+ * integer indicating the number of
10
+ * nodes in the search tree.
11
+ * @property int $recordSize This is an unsigned 16-bit
12
+ * integer. It indicates the number
13
+ * of bits in a record in the search
14
+ * tree. Note that each node
15
+ * consists of two records.
16
+ * @property int $ipVersion This is an unsigned 16-bit
17
+ * integer which is always 4 or 6.
18
+ * It indicates whether the database
19
+ * contains IPv4 or IPv6 address
20
+ * data.
21
+ * @property string $databaseType This is a string that indicates
22
+ * the structure of each data record
23
+ * associated with an IP address.
24
+ * The actual definition of these
25
+ * structures is left up to the
26
+ * database creator.
27
+ * @property array $languages An array of strings, each of
28
+ * which is a language code. A given
29
+ * record may contain data items
30
+ * that have been localized to some
31
+ * or all of these languages. This
32
+ * may be undefined.
33
+ * @property int $binaryFormatMajorVersion This is an unsigned 16-bit
34
+ * integer indicating the major
35
+ * version number for the database's
36
+ * binary format.
37
+ * @property int $binaryFormatMinorVersion This is an unsigned 16-bit
38
+ * integer indicating the minor
39
+ * version number for the database's
40
+ * binary format.
41
+ * @property int $buildEpoch This is an unsigned 64-bit
42
+ * integer that contains the
43
+ * database build timestamp as a
44
+ * Unix epoch value.
45
+ * @property array $description This key will always point to a
46
+ * map (associative array). The keys
47
+ * of that map will be language
48
+ * codes, and the values will be a
49
+ * description in that language as a
50
+ * UTF-8 string. May be undefined
51
+ * for some databases.
52
  */
53
  class Metadata
54
  {
55
+ private $binaryFormatMajorVersion;
56
+ private $binaryFormatMinorVersion;
57
+ private $buildEpoch;
58
+ private $databaseType;
59
+ private $description;
60
+ private $ipVersion;
61
+ private $languages;
62
+ private $nodeByteSize;
63
+ private $nodeCount;
64
+ private $recordSize;
65
+ private $searchTreeSize;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
66
 
67
+ public function __construct($metadata)
68
  {
 
 
 
 
 
 
69
  $this->binaryFormatMajorVersion =
70
  $metadata['binary_format_major_version'];
71
  $this->binaryFormatMinorVersion =
80
  $this->nodeByteSize = $this->recordSize / 4;
81
  $this->searchTreeSize = $this->nodeCount * $this->nodeByteSize;
82
  }
83
+
84
+ public function __get($var)
85
+ {
86
+ return $this->$var;
87
+ }
88
  }
includes/vendor/maxmind-db/reader/src/MaxMind/Db/Reader/Util.php CHANGED
@@ -1,15 +1,10 @@
1
  <?php
2
 
3
- declare(strict_types=1);
4
-
5
  namespace MaxMind\Db\Reader;
6
 
7
  class Util
8
  {
9
- /**
10
- * @param resource $stream
11
- */
12
- public static function read($stream, int $offset, int $numberOfBytes): string
13
  {
14
  if ($numberOfBytes === 0) {
15
  return '';
@@ -20,7 +15,7 @@ class Util
20
  // We check that the number of bytes read is equal to the number
21
  // asked for. We use ftell as getting the length of $value is
22
  // much slower.
23
- if ($value !== false && ftell($stream) - $offset === $numberOfBytes) {
24
  return $value;
25
  }
26
  }
1
  <?php
2
 
 
 
3
  namespace MaxMind\Db\Reader;
4
 
5
  class Util
6
  {
7
+ public static function read($stream, $offset, $numberOfBytes)
 
 
 
8
  {
9
  if ($numberOfBytes === 0) {
10
  return '';
15
  // We check that the number of bytes read is equal to the number
16
  // asked for. We use ftell as getting the length of $value is
17
  // much slower.
18
+ if (ftell($stream) - $offset === $numberOfBytes) {
19
  return $value;
20
  }
21
  }
includes/vendor/maxmind/web-service-common/CHANGELOG.md CHANGED
@@ -1,21 +1,6 @@
1
  CHANGELOG
2
  =========
3
 
4
- 0.8.1 (2020-11-02)
5
- ------------------
6
-
7
- * We now correctly handle responses without a `Content-Type` header. In 0.8.0,
8
- such responses could lead to a type error. In particular, this affected the
9
- minFraud Report Transaction endpoint, which returns a response with no
10
- content. Reported by Dmitry Malashko. GitHub #99 on
11
- `maxmind/minfraud-api-php`.
12
-
13
- 0.8.0 (2020-10-01)
14
- ------------------
15
-
16
- * PHP 7.2 or greater is now required.
17
- * Added additional type hints.
18
-
19
  0.7.0 (2020-05-06)
20
  ------------------
21
 
1
  CHANGELOG
2
  =========
3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
  0.7.0 (2020-05-06)
5
  ------------------
6
 
includes/vendor/maxmind/web-service-common/README.md CHANGED
@@ -5,7 +5,7 @@ shared code between MaxMind's various web service client APIs.
5
 
6
  ## Requirements ##
7
 
8
- The library requires PHP 7.2 or greater.
9
 
10
  There are several other dependencies as defined in the `composer.json` file.
11
 
5
 
6
  ## Requirements ##
7
 
8
+ The library requires PHP 5.6 or greater.
9
 
10
  There are several other dependencies as defined in the `composer.json` file.
11
 
includes/vendor/maxmind/web-service-common/composer.json CHANGED
@@ -12,14 +12,14 @@
12
  }
13
  ],
14
  "require": {
15
- "php": ">=7.2",
16
  "composer/ca-bundle": "^1.0.3",
17
  "ext-curl": "*",
18
  "ext-json": "*"
19
  },
20
  "require-dev": {
21
  "friendsofphp/php-cs-fixer": "2.*",
22
- "phpunit/phpunit": "^8.0 || ^9.0",
23
  "squizlabs/php_codesniffer": "3.*"
24
  },
25
  "autoload": {
12
  }
13
  ],
14
  "require": {
15
+ "php": ">=5.6",
16
  "composer/ca-bundle": "^1.0.3",
17
  "ext-curl": "*",
18
  "ext-json": "*"
19
  },
20
  "require-dev": {
21
  "friendsofphp/php-cs-fixer": "2.*",
22
+ "phpunit/phpunit": "^4.8.36 || ^5.7 || ^6.5 || ^7.0",
23
  "squizlabs/php_codesniffer": "3.*"
24
  },
25
  "autoload": {
includes/vendor/maxmind/web-service-common/src/Exception/AuthenticationException.php CHANGED
@@ -1,7 +1,5 @@
1
  <?php
2
 
3
- declare(strict_types=1);
4
-
5
  namespace MaxMind\Exception;
6
 
7
  /**
1
  <?php
2
 
 
 
3
  namespace MaxMind\Exception;
4
 
5
  /**
includes/vendor/maxmind/web-service-common/src/Exception/HttpException.php CHANGED
@@ -1,7 +1,5 @@
1
  <?php
2
 
3
- declare(strict_types=1);
4
-
5
  namespace MaxMind\Exception;
6
 
7
  /**
@@ -21,21 +19,21 @@ class HttpException extends WebServiceException
21
  * @param \Exception $previous the previous exception, if any
22
  */
23
  public function __construct(
24
- string $message,
25
- int $httpStatus,
26
- string $uri,
27
  \Exception $previous = null
28
  ) {
29
  $this->uri = $uri;
30
  parent::__construct($message, $httpStatus, $previous);
31
  }
32
 
33
- public function getUri(): string
34
  {
35
  return $this->uri;
36
  }
37
 
38
- public function getStatusCode(): int
39
  {
40
  return $this->getCode();
41
  }
1
  <?php
2
 
 
 
3
  namespace MaxMind\Exception;
4
 
5
  /**
19
  * @param \Exception $previous the previous exception, if any
20
  */
21
  public function __construct(
22
+ $message,
23
+ $httpStatus,
24
+ $uri,
25
  \Exception $previous = null
26
  ) {
27
  $this->uri = $uri;
28
  parent::__construct($message, $httpStatus, $previous);
29
  }
30
 
31
+ public function getUri()
32
  {
33
  return $this->uri;
34
  }
35
 
36
+ public function getStatusCode()
37
  {
38
  return $this->getCode();
39
  }
includes/vendor/maxmind/web-service-common/src/Exception/InsufficientFundsException.php CHANGED
@@ -1,7 +1,5 @@
1
  <?php
2
 
3
- declare(strict_types=1);
4
-
5
  namespace MaxMind\Exception;
6
 
7
  /**
1
  <?php
2
 
 
 
3
  namespace MaxMind\Exception;
4
 
5
  /**
includes/vendor/maxmind/web-service-common/src/Exception/InvalidInputException.php CHANGED
@@ -1,7 +1,5 @@
1
  <?php
2
 
3
- declare(strict_types=1);
4
-
5
  namespace MaxMind\Exception;
6
 
7
  /**
1
  <?php
2
 
 
 
3
  namespace MaxMind\Exception;
4
 
5
  /**
includes/vendor/maxmind/web-service-common/src/Exception/InvalidRequestException.php CHANGED
@@ -1,7 +1,5 @@
1
  <?php
2
 
3
- declare(strict_types=1);
4
-
5
  namespace MaxMind\Exception;
6
 
7
  /**
@@ -16,23 +14,23 @@ class InvalidRequestException extends HttpException
16
 
17
  /**
18
  * @param string $message the exception message
19
- * @param string $error the error code returned by the MaxMind web service
20
  * @param int $httpStatus the HTTP status code of the response
21
  * @param string $uri the URI queries
22
  * @param \Exception $previous the previous exception, if any
23
  */
24
  public function __construct(
25
- string $message,
26
- string $error,
27
- int $httpStatus,
28
- string $uri,
29
  \Exception $previous = null
30
  ) {
31
  $this->error = $error;
32
  parent::__construct($message, $httpStatus, $uri, $previous);
33
  }
34
 
35
- public function getErrorCode(): string
36
  {
37
  return $this->error;
38
  }
1
  <?php
2
 
 
 
3
  namespace MaxMind\Exception;
4
 
5
  /**
14
 
15
  /**
16
  * @param string $message the exception message
17
+ * @param int $error the error code returned by the MaxMind web service
18
  * @param int $httpStatus the HTTP status code of the response
19
  * @param string $uri the URI queries
20
  * @param \Exception $previous the previous exception, if any
21
  */
22
  public function __construct(
23
+ $message,
24
+ $error,
25
+ $httpStatus,
26
+ $uri,
27
  \Exception $previous = null
28
  ) {
29
  $this->error = $error;
30
  parent::__construct($message, $httpStatus, $uri, $previous);
31
  }
32
 
33
+ public function getErrorCode()
34
  {
35
  return $this->error;
36
  }
includes/vendor/maxmind/web-service-common/src/Exception/IpAddressNotFoundException.php CHANGED
@@ -1,7 +1,5 @@
1
  <?php
2
 
3
- declare(strict_types=1);
4
-
5
  namespace MaxMind\Exception;
6
 
7
  class IpAddressNotFoundException extends InvalidRequestException
1
  <?php
2
 
 
 
3
  namespace MaxMind\Exception;
4
 
5
  class IpAddressNotFoundException extends InvalidRequestException
includes/vendor/maxmind/web-service-common/src/Exception/PermissionRequiredException.php CHANGED
@@ -1,7 +1,5 @@
1
  <?php
2
 
3
- declare(strict_types=1);
4
-
5
  namespace MaxMind\Exception;
6
 
7
  /**
1
  <?php
2
 
 
 
3
  namespace MaxMind\Exception;
4
 
5
  /**
includes/vendor/maxmind/web-service-common/src/Exception/WebServiceException.php CHANGED
@@ -1,7 +1,5 @@
1
  <?php
2
 
3
- declare(strict_types=1);
4
-
5
  namespace MaxMind\Exception;
6
 
7
  /**
1
  <?php
2
 
 
 
3
  namespace MaxMind\Exception;
4
 
5
  /**
includes/vendor/maxmind/web-service-common/src/WebService/Client.php CHANGED
@@ -1,7 +1,5 @@
1
  <?php
2
 
3
- declare(strict_types=1);
4
-
5
  namespace MaxMind\WebService;
6
 
7
  use Composer\CaBundle\CaBundle;
@@ -49,9 +47,9 @@ class Client
49
  * username, and password, e.g., `http://username:password@127.0.0.1:10`.
50
  */
51
  public function __construct(
52
- int $accountId,
53
- string $licenseKey,
54
- array $options = []
55
  ) {
56
  $this->accountId = $accountId;
57
  $this->licenseKey = $licenseKey;
@@ -98,9 +96,9 @@ class Client
98
  * @throws WebServiceException when some other error occurs. This also
99
  * serves as the base class for the above exceptions.
100
  *
101
- * @return array|null The decoded content of a successful response
102
  */
103
- public function post(string $service, string $path, array $input): ?array
104
  {
105
  $requestBody = json_encode($input);
106
  if ($requestBody === false) {
@@ -126,7 +124,7 @@ class Client
126
  );
127
  }
128
 
129
- public function get(string $service, string $path): ?array
130
  {
131
  $request = $this->createRequest($path);
132
 
@@ -141,7 +139,7 @@ class Client
141
  );
142
  }
143
 
144
- private function userAgent(): string
145
  {
146
  $curlVersion = curl_version();
147
 
@@ -149,7 +147,7 @@ class Client
149
  ' curl/' . $curlVersion['version'];
150
  }
151
 
152
- private function createRequest(string $path, array $headers = []): \MaxMind\WebService\Http\Request
153
  {
154
  array_push(
155
  $headers,
@@ -172,11 +170,11 @@ class Client
172
  }
173
 
174
  /**
175
- * @param int $statusCode the HTTP status code of the response
176
- * @param string|null $contentType the Content-Type of the response
177
- * @param string|null $responseBody the response body
178
- * @param string $service the name of the service
179
- * @param string $path the path used in the request
180
  *
181
  * @throws AuthenticationException when there is an issue authenticating the
182
  * request
@@ -187,15 +185,15 @@ class Client
187
  * @throws WebServiceException when some other error occurs. This also
188
  * serves as the base class for the above exceptions
189
  *
190
- * @return array|null The decoded content of a successful response
191
  */
192
  private function handleResponse(
193
- int $statusCode,
194
- ?string $contentType,
195
- ?string $responseBody,
196
- string $service,
197
- string $path
198
- ): ?array {
199
  if ($statusCode >= 400 && $statusCode <= 499) {
200
  $this->handle4xx($statusCode, $contentType, $responseBody, $service, $path);
201
  } elseif ($statusCode >= 500) {
@@ -210,7 +208,7 @@ class Client
210
  /**
211
  * @return string describing the JSON error
212
  */
213
- private function jsonErrorDescription(): string
214
  {
215
  $errno = json_last_error();
216
  switch ($errno) {
@@ -234,17 +232,17 @@ class Client
234
  *
235
  * @return string the constructed URL
236
  */
237
- private function urlFor(string $path): string
238
  {
239
  return 'https://' . $this->host . $path;
240
  }
241
 
242
  /**
243
- * @param int $statusCode the HTTP status code
244
- * @param string|null $contentType the response content-type
245
- * @param string|null $body the response body
246
- * @param string $service the service name
247
- * @param string $path the path used in the request
248
  *
249
  * @throws AuthenticationException
250
  * @throws HttpException
@@ -252,20 +250,20 @@ class Client
252
  * @throws InvalidRequestException
253
  */
254
  private function handle4xx(
255
- int $statusCode,
256
- ?string $contentType,
257
- ?string $body,
258
- string $service,
259
- string $path
260
- ): void {
261
- if ($body === null || $body === '') {
262
  throw new HttpException(
263
  "Received a $statusCode error for $service with no body",
264
  $statusCode,
265
  $this->urlFor($path)
266
  );
267
  }
268
- if ($contentType === null || !strstr($contentType, 'json')) {
269
  throw new HttpException(
270
  "Received a $statusCode error for $service with " .
271
  'the following body: ' . $body,
@@ -313,11 +311,11 @@ class Client
313
  * @throws InsufficientFundsException
314
  */
315
  private function handleWebServiceError(
316
- string $message,
317
- string $code,
318
- int $statusCode,
319
- string $path
320
- ): void {
321
  switch ($code) {
322
  case 'IP_ADDRESS_NOT_FOUND':
323
  case 'IP_ADDRESS_RESERVED':
@@ -371,7 +369,7 @@ class Client
371
  *
372
  * @throws HttpException
373
  */
374
- private function handle5xx(int $statusCode, string $service, string $path): void
375
  {
376
  throw new HttpException(
377
  "Received a server error ($statusCode) for $service",
@@ -387,7 +385,7 @@ class Client
387
  *
388
  * @throws HttpException
389
  */
390
- private function handleUnexpectedStatus(int $statusCode, string $service, string $path): void
391
  {
392
  throw new HttpException(
393
  'Received an unexpected HTTP status ' .
@@ -398,22 +396,22 @@ class Client
398
  }
399
 
400
  /**
401
- * @param int $statusCode the HTTP status code
402
- * @param string|null $body the successful request body
403
- * @param string $service the service name
404
  *
405
  * @throws WebServiceException if a response body is included but not
406
  * expected, or is not expected but not
407
  * included, or is expected and included
408
  * but cannot be decoded as JSON
409
  *
410
- * @return array|null the decoded request body
411
  */
412
- private function handleSuccess(int $statusCode, ?string $body, string $service): ?array
413
  {
414
  // A 204 should have no response body
415
  if ($statusCode === 204) {
416
- if ($body !== null && $body !== '') {
417
  throw new WebServiceException(
418
  "Received a 204 response for $service along with an " .
419
  "unexpected HTTP body: $body"
@@ -424,7 +422,7 @@ class Client
424
  }
425
 
426
  // A 200 should have a valid JSON body
427
- if ($body === null || $body === '') {
428
  throw new WebServiceException(
429
  "Received a 200 response for $service but did not " .
430
  'receive a HTTP body.'
1
  <?php
2
 
 
 
3
  namespace MaxMind\WebService;
4
 
5
  use Composer\CaBundle\CaBundle;
47
  * username, and password, e.g., `http://username:password@127.0.0.1:10`.
48
  */
49
  public function __construct(
50
+ $accountId,
51
+ $licenseKey,
52
+ $options = []
53
  ) {
54
  $this->accountId = $accountId;
55
  $this->licenseKey = $licenseKey;
96
  * @throws WebServiceException when some other error occurs. This also
97
  * serves as the base class for the above exceptions.
98
  *
99
+ * @return array The decoded content of a successful response
100
  */
101
+ public function post($service, $path, $input)
102
  {
103
  $requestBody = json_encode($input);
104
  if ($requestBody === false) {
124
  );
125
  }
126
 
127
+ public function get($service, $path)
128
  {
129
  $request = $this->createRequest($path);
130
 
139
  );
140
  }
141
 
142
+ private function userAgent()
143
  {
144
  $curlVersion = curl_version();
145
 
147
  ' curl/' . $curlVersion['version'];
148
  }
149
 
150
+ private function createRequest($path, $headers = [])
151
  {
152
  array_push(
153
  $headers,
170
  }
171
 
172
  /**
173
+ * @param int $statusCode the HTTP status code of the response
174
+ * @param string $contentType the Content-Type of the response
175
+ * @param string $responseBody the response body
176
+ * @param string $service the name of the service
177
+ * @param string $path the path used in the request
178
  *
179
  * @throws AuthenticationException when there is an issue authenticating the
180
  * request
185
  * @throws WebServiceException when some other error occurs. This also
186
  * serves as the base class for the above exceptions
187
  *
188
+ * @return array The decoded content of a successful response
189
  */
190
  private function handleResponse(
191
+ $statusCode,
192
+ $contentType,
193
+ $responseBody,
194
+ $service,
195
+ $path
196
+ ) {
197
  if ($statusCode >= 400 && $statusCode <= 499) {
198
  $this->handle4xx($statusCode, $contentType, $responseBody, $service, $path);
199
  } elseif ($statusCode >= 500) {
208
  /**
209
  * @return string describing the JSON error
210
  */
211
+ private function jsonErrorDescription()
212
  {
213
  $errno = json_last_error();
214
  switch ($errno) {
232
  *
233
  * @return string the constructed URL
234
  */
235
+ private function urlFor($path)
236
  {
237
  return 'https://' . $this->host . $path;
238
  }
239
 
240
  /**
241
+ * @param int $statusCode the HTTP status code
242
+ * @param string $contentType the response content-type
243
+ * @param string $body the response body
244
+ * @param string $service the service name
245
+ * @param string $path the path used in the request
246
  *
247
  * @throws AuthenticationException
248
  * @throws HttpException
250
  * @throws InvalidRequestException
251
  */
252
  private function handle4xx(
253
+ $statusCode,
254
+ $contentType,
255
+ $body,
256
+ $service,
257
+ $path
258
+ ) {
259
+ if (\strlen($body) === 0) {
260
  throw new HttpException(
261
  "Received a $statusCode error for $service with no body",
262
  $statusCode,
263
  $this->urlFor($path)
264
  );
265
  }
266
+ if (!strstr($contentType, 'json')) {
267
  throw new HttpException(
268
  "Received a $statusCode error for $service with " .
269
  'the following body: ' . $body,
311
  * @throws InsufficientFundsException
312
  */
313
  private function handleWebServiceError(
314
+ $message,
315
+ $code,
316
+ $statusCode,
317
+ $path
318
+ ) {
319
  switch ($code) {
320
  case 'IP_ADDRESS_NOT_FOUND':
321
  case 'IP_ADDRESS_RESERVED':
369
  *
370
  * @throws HttpException
371
  */
372
+ private function handle5xx($statusCode, $service, $path)
373
  {
374
  throw new HttpException(
375
  "Received a server error ($statusCode) for $service",
385
  *
386
  * @throws HttpException
387
  */
388
+ private function handleUnexpectedStatus($statusCode, $service, $path)
389
  {
390
  throw new HttpException(
391
  'Received an unexpected HTTP status ' .
396
  }
397
 
398
  /**
399
+ * @param int $statusCode the HTTP status code
400
+ * @param string $body the successful request body
401
+ * @param string $service the service name
402
  *
403
  * @throws WebServiceException if a response body is included but not
404
  * expected, or is not expected but not
405
  * included, or is expected and included
406
  * but cannot be decoded as JSON
407
  *
408
+ * @return array the decoded request body
409
  */
410
+ private function handleSuccess($statusCode, $body, $service)
411
  {
412
  // A 204 should have no response body
413
  if ($statusCode === 204) {
414
+ if (\strlen($body) !== 0) {
415
  throw new WebServiceException(
416
  "Received a 204 response for $service along with an " .
417
  "unexpected HTTP body: $body"
422
  }
423
 
424
  // A 200 should have a valid JSON body
425
+ if (\strlen($body) === 0) {
426
  throw new WebServiceException(
427
  "Received a 200 response for $service but did not " .
428
  'receive a HTTP body.'
includes/vendor/maxmind/web-service-common/src/WebService/Http/CurlRequest.php CHANGED
@@ -1,7 +1,5 @@
1
  <?php
2
 
3
- declare(strict_types=1);
4
-
5
  namespace MaxMind\WebService\Http;
6
 
7
  use MaxMind\Exception\HttpException;
@@ -28,7 +26,11 @@ class CurlRequest implements Request
28
  */
29
  private $options;
30
 
31
- public function __construct(string $url, array $options)
 
 
 
 
32
  {
33
  $this->url = $url;
34
  $this->options = $options;
@@ -36,9 +38,13 @@ class CurlRequest implements Request
36
  }
37
 
38
  /**
 
 
39
  * @throws HttpException
 
 
40
  */
41
- public function post(string $body): array
42
  {
43
  $curl = $this->createCurl();
44
 
@@ -48,7 +54,7 @@ class CurlRequest implements Request
48
  return $this->execute($curl);
49
  }
50
 
51
- public function get(): array
52
  {
53
  $curl = $this->createCurl();
54
 
@@ -106,8 +112,10 @@ class CurlRequest implements Request
106
  * @param resource $curl
107
  *
108
  * @throws HttpException
 
 
109
  */
110
- private function execute($curl): array
111
  {
112
  $body = curl_exec($curl);
113
  if ($errno = curl_errno($curl)) {
@@ -123,14 +131,6 @@ class CurlRequest implements Request
123
  $statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
124
  $contentType = curl_getinfo($curl, CURLINFO_CONTENT_TYPE);
125
 
126
- return [
127
- $statusCode,
128
- // The PHP docs say "Content-Type: of the requested document. NULL
129
- // indicates server did not send valid Content-Type: header" for
130
- // CURLINFO_CONTENT_TYPE. However, it will return FALSE if no header
131
- // is set. To keep our types simple, we return null in this case.
132
- ($contentType === false ? null : $contentType),
133
- $body,
134
- ];
135
  }
136
  }
1
  <?php
2
 
 
 
3
  namespace MaxMind\WebService\Http;
4
 
5
  use MaxMind\Exception\HttpException;
26
  */
27
  private $options;
28
 
29
+ /**
30
+ * @param string $url
31
+ * @param array $options
32
+ */
33
+ public function __construct($url, $options)
34
  {
35
  $this->url = $url;
36
  $this->options = $options;
38
  }
39
 
40
  /**
41
+ * @param string $body
42
+ *
43
  * @throws HttpException
44
+ *
45
+ * @return array
46
  */
47
+ public function post($body)
48
  {
49
  $curl = $this->createCurl();
50
 
54
  return $this->execute($curl);
55
  }
56
 
57
+ public function get()
58
  {
59
  $curl = $this->createCurl();
60
 
112
  * @param resource $curl
113
  *
114
  * @throws HttpException
115
+ *
116
+ * @return array
117
  */
118
+ private function execute($curl)
119
  {
120
  $body = curl_exec($curl);
121
  if ($errno = curl_errno($curl)) {
131
  $statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
132
  $contentType = curl_getinfo($curl, CURLINFO_CONTENT_TYPE);
133
 
134
+ return [$statusCode, $contentType, $body];
 
 
 
 
 
 
 
 
135
  }
136
  }
includes/vendor/maxmind/web-service-common/src/WebService/Http/Request.php CHANGED
@@ -1,7 +1,5 @@
1
  <?php
2
 
3
- declare(strict_types=1);
4
-
5
  namespace MaxMind\WebService\Http;
6
 
7
  /**
@@ -11,9 +9,21 @@ namespace MaxMind\WebService\Http;
11
  */
12
  interface Request
13
  {
14
- public function __construct(string $url, array $options);
 
 
 
 
15
 
16
- public function post(string $body): array;
 
 
 
 
 
17
 
18
- public function get(): array;
 
 
 
19
  }
1
  <?php
2
 
 
 
3
  namespace MaxMind\WebService\Http;
4
 
5
  /**
9
  */
10
  interface Request
11
  {
12
+ /**
13
+ * @param string $url
14
+ * @param array $options
15
+ */
16
+ public function __construct($url, $options);
17
 
18
+ /**
19
+ * @param string $body
20
+ *
21
+ * @return mixed
22
+ */
23
+ public function post($body);
24
 
25
+ /**
26
+ * @return mixed
27
+ */
28
+ public function get();
29
  }
includes/vendor/maxmind/web-service-common/src/WebService/Http/RequestFactory.php CHANGED
@@ -1,7 +1,5 @@
1
  <?php
2
 
3
- declare(strict_types=1);
4
-
5
  namespace MaxMind\WebService\Http;
6
 
7
  /**
@@ -37,9 +35,12 @@ class RequestFactory
37
  }
38
 
39
  /**
 
 
 
40
  * @return Request
41
  */
42
- public function request(string $url, array $options)
43
  {
44
  $options['curlHandle'] = $this->getCurlHandle();
45
 
1
  <?php
2
 
 
 
3
  namespace MaxMind\WebService\Http;
4
 
5
  /**
35
  }
36
 
37
  /**
38
+ * @param string $url
39
+ * @param array $options
40
+ *
41
  * @return Request
42
  */
43
+ public function request($url, $options)
44
  {
45
  $options['curlHandle'] = $this->getCurlHandle();
46
 
includes/vendor/whichbrowser/parser/.coveralls.yml ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ service_name: travis-ci
2
+
3
+ coverage_clover:
4
+ - runner.xml
5
+ - phpunit.xml
6
+
7
+ json_path: coveralls.json
includes/vendor/whichbrowser/parser/.gitignore ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ runner.log
2
+ runner.xml
3
+ composer.lock
4
+ package-lock.json
5
+ vendor/*
6
+ package.json
7
+ Gruntfile.js
8
+ node_modules/*
9
+ humbug*
10
+ build/*
11
+ .vscode
12
+ .DS_Store
includes/vendor/whichbrowser/parser/.travis.yml ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ sudo: false
2
+ dist: trusty
3
+ language: php
4
+
5
+ php:
6
+ - 5.4
7
+ - 5.5
8
+ - 5.6
9
+ - 7.0
10
+ - 7.1
11
+ - 7.2
12
+
13
+ before_script:
14
+ - composer self-update
15
+ - composer update --prefer-source
16
+
17
+ # Install suggested cache/array-adapter on supported versions of PHP
18
+ - composer require --dev cache/array-adapter || true
19
+
20
+ # Set memory limit to 2 MB
21
+ - echo "memory_limit=2048M" >> ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini
22
+
23
+ # Disable X-debug on all but PHP 5.6
24
+ - if [ "$TRAVIS_PHP_VERSION" != "5.6" ]; then phpenv config-rm xdebug.ini; fi
25
+
26
+ script:
27
+ - vendor/bin/phpcs --standard=PSR1,PSR2 -n src
28
+
29
+ # Run tests (all except PHP 5.6)
30
+ - if [ "$TRAVIS_PHP_VERSION" != "5.6" ]; then php bin/runner.php --show check; fi
31
+ - if [ "$TRAVIS_PHP_VERSION" != "5.6" ]; then vendor/bin/phpunit; fi
32
+
33
+ # Run tests with coverage enabled (only PHP 5.6)
34
+ - if [ "$TRAVIS_PHP_VERSION" = "5.6" ]; then php bin/runner.php --coverage --show check; fi
35
+ - if [ "$TRAVIS_PHP_VERSION" = "5.6" ]; then vendor/bin/phpunit --coverage-clover phpunit.xml; fi
36
+
37
+ after_script:
38
+ # Upload coverage to Coveralls.io
39
+ - if [ "$TRAVIS_PHP_VERSION" = "5.6" ]; then travis_retry php vendor/bin/coveralls -v; fi
includes/vendor/whichbrowser/parser/README.md CHANGED
@@ -6,9 +6,9 @@ This is an extremely complicated and almost completely useless browser sniffing
6
  WhichBrowser/Parser-PHP
7
  =======================
8
 
9
- The PHP version of WhichBrowser for use on a server. Fully compatible with PHP 5.4 or higher, including PHP 7.
10
 
11
- [![Build Status](https://travis-ci.org/WhichBrowser/Parser-PHP.svg?branch=master)](https://travis-ci.org/WhichBrowser/Parser-PHP)
12
  [![Coverage Status](https://coveralls.io/repos/WhichBrowser/Parser-PHP/badge.svg?branch=master&service=github)](https://coveralls.io/github/WhichBrowser/Parser-PHP?branch=master)
13
  [![License](https://poser.pugx.org/whichbrowser/parser/license)](https://packagist.org/packages/whichbrowser/parser)
14
  [![Latest Stable Version](https://poser.pugx.org/whichbrowser/parser/v/stable)](https://packagist.org/packages/whichbrowser/parser)
@@ -58,7 +58,7 @@ The useragent header looks like Opera 11.10 on Linux, but we know it's Opera Min
58
  Requirements
59
  -----------------
60
 
61
- WhichBrowser requires with PHP 5.4 or higher and supports PHP 7. WhichBrowser is compatible with the PSR-4 autoloading standard and follows PSR-1 and PSR-2 coding style.
62
 
63
 
64
  How to install it
@@ -385,29 +385,20 @@ The `type` property can contain any value from the following list:
385
 
386
  * desktop
387
  * mobile
388
- * pda
389
- * dect
390
  * tablet
391
  * gaming
 
392
  * ereader
393
  * media
394
- * headset
395
- * watch
396
  * emulator
397
  * television
398
  * monitor
399
  * camera
400
- * printer
401
  * signage
402
  * whiteboard
403
- * devboard
404
- * inflight
405
- * appliance
406
- * gps
407
  * car
408
  * pos
409
  * bot
410
- * projector
411
 
412
  If the `type` is "mobile", the `subtype` property can contain any value from the following list:
413
 
@@ -487,8 +478,6 @@ An object of the `WhichBrowser\Model\Version` class is used for the `version` pr
487
  a string containing the original version number.
488
  * `alias`
489
  a string containing an alias for the version number, ie. 'XP' for Windows '5.1'.
490
- * `nickname`
491
- a string containing a nickname for the version number, ie. 'Mojave' for OS X '10.14'.
492
  * `details`
493
  an integer containing the number of digits of the version number that should be printed.
494
 
6
  WhichBrowser/Parser-PHP
7
  =======================
8
 
9
+ The PHP version of WhichBrowser for use on a server. Fully compatible with PHP 5.4 or higher, including PHP 7 and HHVM.
10
 
11
+ [![Build Status](https://travis-ci.org/WhichBrowser/Parser-PHP.svg?branch=master)](https://travis-ci.org/WhichBrowser/Parser)
12
  [![Coverage Status](https://coveralls.io/repos/WhichBrowser/Parser-PHP/badge.svg?branch=master&service=github)](https://coveralls.io/github/WhichBrowser/Parser-PHP?branch=master)
13
  [![License](https://poser.pugx.org/whichbrowser/parser/license)](https://packagist.org/packages/whichbrowser/parser)
14
  [![Latest Stable Version](https://poser.pugx.org/whichbrowser/parser/v/stable)](https://packagist.org/packages/whichbrowser/parser)
58
  Requirements
59
  -----------------
60
 
61
+ WhichBrowser requires with PHP 5.4 or higher and supports PHP 7 and HHVM. WhichBrowser is compatible with the PSR-4 autoloading standard and follows PSR-1 and PSR-2 coding style.
62
 
63
 
64
  How to install it
385
 
386
  * desktop
387
  * mobile
 
 
388
  * tablet
389
  * gaming
390
+ * headset
391
  * ereader
392
  * media
 
 
393
  * emulator
394
  * television
395
  * monitor
396
  * camera
 
397
  * signage
398
  * whiteboard
 
 
 
 
399
  * car
400
  * pos
401
  * bot
 
402
 
403
  If the `type` is "mobile", the `subtype` property can contain any value from the following list:
404
 
478
  a string containing the original version number.
479
  * `alias`
480
  a string containing an alias for the version number, ie. 'XP' for Windows '5.1'.
 
 
481
  * `details`
482
  an integer containing the number of digits of the version number that should be printed.
483
 
includes/vendor/whichbrowser/parser/composer.json CHANGED
@@ -29,9 +29,9 @@
29
  },
30
 
31
  "require-dev": {
32
- "symfony/yaml": "~2.8 || ~3.4 || ~4.2 || ~5.0",
33
- "phpunit/php-code-coverage": "^2.2 || ^3.0",
34
- "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0",
35
  "satooshi/php-coveralls": "^1.0",
36
  "icomefromthenet/reverse-regex" : "0.0.6.3",
37
  "squizlabs/php_codesniffer": "2.5.*"
29
  },
30
 
31
  "require-dev": {
32
+ "symfony/yaml": ">=2.8",
33
+ "phpunit/php-code-coverage": "^2.2|^3.0",
34
+ "phpunit/PHPUnit": "^4.0|^5.0",
35
  "satooshi/php-coveralls": "^1.0",
36
  "icomefromthenet/reverse-regex" : "0.0.6.3",
37
  "squizlabs/php_codesniffer": "2.5.*"
includes/vendor/whichbrowser/parser/data/applications-bots.php CHANGED
@@ -283,8 +283,7 @@ Applications::$BOTS = [
283
  [ 'name' => 'Perl', 'id' => 'simple', 'regexp' => '/LWP::Simple\//u' ],
284
  [ 'name' => 'Perl', 'id' => 'libwww', 'regexp' => '/libwww-perl\//u' ],
285
  [ 'name' => 'Perl', 'id' => 'lwp', 'regexp' => '/lwp-trivial\//u' ],
286
- [ 'name' => 'Python', 'id' => 'urllib', 'regexp' => '/Python-urllib\/([0-9.]*)/u' ],
287
- [ 'name' => 'Python', 'id' => 'requests', 'regexp' => '/python-requests\/([0-9.]*)/u' ],
288
  [ 'name' => 'PHP', 'id' => 'php', 'regexp' => '/ PHP\/([0-9.]*)/u' ],
289
  [ 'name' => 'PHP', 'id' => 'php', 'regexp' => '/^PHP/u' ],
290
  [ 'name' => 'PHP', 'id' => 'pear', 'regexp' => '/PEAR HTTP_Request class/u' ],
283
  [ 'name' => 'Perl', 'id' => 'simple', 'regexp' => '/LWP::Simple\//u' ],
284
  [ 'name' => 'Perl', 'id' => 'libwww', 'regexp' => '/libwww-perl\//u' ],
285
  [ 'name' => 'Perl', 'id' => 'lwp', 'regexp' => '/lwp-trivial\//u' ],
286
+ [ 'name' => 'Python', 'id' => 'urllib', 'regexp' => '/Python-urllib/u' ],
 
287
  [ 'name' => 'PHP', 'id' => 'php', 'regexp' => '/ PHP\/([0-9.]*)/u' ],
288
  [ 'name' => 'PHP', 'id' => 'php', 'regexp' => '/^PHP/u' ],
289
  [ 'name' => 'PHP', 'id' => 'pear', 'regexp' => '/PEAR HTTP_Request class/u' ],
includes/vendor/whichbrowser/parser/data/applications-browsers.php CHANGED
@@ -160,7 +160,6 @@ Applications::$BROWSERS = [
160
  [ 'name' => 'Openwave', 'id' => 'up', 'regexp' =>'/UP\. ?Browser(?:\/([a-z0-9.]*))?/iu', 'details' => 2, 'type' => Constants\DeviceType::MOBILE ],
161
  [ 'name' => 'Openwave', 'id' => 'km', 'regexp' =>'/KM\.Browser\/([0-9.]+)/iu', 'details' => 2, 'type' => Constants\DeviceType::MOBILE ],
162
  [ 'name' => 'Openwave', 'id' => 'up', 'regexp' =>'/UP\/([0-9.]+)/u', 'details' => 2, 'type' => Constants\DeviceType::MOBILE ],
163
- [ 'name' => 'Oppo Browser', 'id' => 'oppo', 'regexp' =>'/OppoBrowser\/([0-9.]+)/iu' ],
164
  [ 'name' => 'Quark Browser', 'id' => 'quark', 'regexp' =>'/Quark\/([0-9.]*)/u', 'details' => 3 ],
165
  [ 'name' => 'SEMC Browser', 'id' => 'semc', 'regexp' =>'/SEMC-Browser\/([0-9.]*)/u' ],
166
  [ 'name' => 'STNC HitchHiker' , 'id' => 'stnc', 'regexp' =>'/STNC-WTL\/[0-9.]*/u' ],
@@ -168,7 +167,6 @@ Applications::$BROWSERS = [
168
  [ 'name' => 'Swing Browser', 'id' => 'swing', 'regexp' =>'/Swing\(And\)\/([0-9.]*)/u', 'details' => 3 ],
169
  [ 'name' => 'Symphony', 'id' => 'symphony', 'regexp' =>'/Symphony ([0-9.]+)$/u' ],
170
  [ 'name' => 'TinY', 'id' => 'ucpro', 'regexp' =>'/ucpro\/([0-9.]+)/iu' ],
171
- [ 'name' => 'Vivo Browser', 'id' => 'vivo', 'regexp' =>'/VivoBrowser\/([0-9.]+)/iu' ],
172
  [ 'name' => 'WebLite', 'id' => 'weblite', 'regexp' =>'/WebLite\/([0-9.]*)/u', 'type' => Constants\DeviceType::MOBILE ],
173
 
174
  /* Television browsers */
160
  [ 'name' => 'Openwave', 'id' => 'up', 'regexp' =>'/UP\. ?Browser(?:\/([a-z0-9.]*))?/iu', 'details' => 2, 'type' => Constants\DeviceType::MOBILE ],
161
  [ 'name' => 'Openwave', 'id' => 'km', 'regexp' =>'/KM\.Browser\/([0-9.]+)/iu', 'details' => 2, 'type' => Constants\DeviceType::MOBILE ],
162
  [ 'name' => 'Openwave', 'id' => 'up', 'regexp' =>'/UP\/([0-9.]+)/u', 'details' => 2, 'type' => Constants\DeviceType::MOBILE ],
 
163
  [ 'name' => 'Quark Browser', 'id' => 'quark', 'regexp' =>'/Quark\/([0-9.]*)/u', 'details' => 3 ],
164
  [ 'name' => 'SEMC Browser', 'id' => 'semc', 'regexp' =>'/SEMC-Browser\/([0-9.]*)/u' ],
165
  [ 'name' => 'STNC HitchHiker' , 'id' => 'stnc', 'regexp' =>'/STNC-WTL\/[0-9.]*/u' ],
167
  [ 'name' => 'Swing Browser', 'id' => 'swing', 'regexp' =>'/Swing\(And\)\/([0-9.]*)/u', 'details' => 3 ],
168
  [ 'name' => 'Symphony', 'id' => 'symphony', 'regexp' =>'/Symphony ([0-9.]+)$/u' ],
169
  [ 'name' => 'TinY', 'id' => 'ucpro', 'regexp' =>'/ucpro\/([0-9.]+)/iu' ],
 
170
  [ 'name' => 'WebLite', 'id' => 'weblite', 'regexp' =>'/WebLite\/([0-9.]*)/u', 'type' => Constants\DeviceType::MOBILE ],
171
 
172
  /* Television browsers */
includes/vendor/whichbrowser/parser/data/browsers-chrome.php CHANGED
@@ -76,15 +76,6 @@ Chrome::$DESKTOP = [
76
  '67.0.3396' => 'stable',
77
  '68.0.3440' => 'stable',
78
  '69.0.3497' => 'stable',
79
- '72.0.3626' => 'stable',
80
- '73.0.3683' => 'stable',
81
- '74.0.3729' => 'stable',
82
- '75.0.3770' => 'stable',
83
- '76.0.3809' => 'stable',
84
- '77.0.3865' => 'stable',
85
- '78.0.3904' => 'stable',
86
- '79.0.3945' => 'stable',
87
- '80.0.3987' => 'stable',
88
  ];
89
 
90
  Chrome::$MOBILE = [
@@ -133,15 +124,4 @@ Chrome::$MOBILE = [
133
  '67.0.3396' => 'stable',
134
  '68.0.3440' => 'stable',
135
  '69.0.3497' => 'stable',
136
- '70.0.3538' => 'stable',
137
- '71.0.3578' => 'stable',
138
- '72.0.3626' => 'stable',
139
- '73.0.3683' => 'stable',
140
- '74.0.3729' => 'stable',
141
- '75.0.3770' => 'stable',
142
- '76.0.3809' => 'stable',
143
- '77.0.3865' => 'stable',
144
- '78.0.3904' => 'stable',
145
- '79.0.3945' => 'stable',
146
- '80.0.3987' => 'stable',
147
  ];
76
  '67.0.3396' => 'stable',
77
  '68.0.3440' => 'stable',
78
  '69.0.3497' => 'stable',
 
 
 
 
 
 
 
 
 
79
  ];
80
 
81
  Chrome::$MOBILE = [
124
  '67.0.3396' => 'stable',
125
  '68.0.3440' => 'stable',
126
  '69.0.3497' => 'stable',
 
 
 
 
 
 
 
 
 
 
 
127
  ];
includes/vendor/whichbrowser/parser/data/indices/models-android.php CHANGED
@@ -15,48 +15,46 @@ DeviceModels::$ANDROID_INDEX = array (
15
  7 => '(Hisense )?(LED[0-9]{2,2}(G|K|L|EC|XT)[0-9]{2,3})!',
16
  8 => '[SX06][0-9]{2,2}HT!!',
17
  9 => '(Huawei )?[MSTX](1|2|7|8|10)\\-[A-Z0-9][0-9]{2,2}!!',
18
- 10 => '(HW-|HUAWEI )?(ATU|DRA|FLA|JKM|TIT|TAG||MRD|NCE|POT|TRT|SLA)!!',
19
- 11 => 'G[0-9]{3,3}!!',
20
- 12 => 'Y[0-9]{3,3}!!',
21
- 13 => '[0-9AS][0-9]{2,2}HW!!',
22
- 14 => '(USCC-|KYOCERA-)?E[0-9]{4,4}!!',
23
- 15 => '(USCC-|KYOCERA-)?C[0-9]{4,4}!!',
24
- 16 => '[0-9]0[0-9]KC?!!',
25
- 17 => 'K\\-?Touch!!',
26
- 18 => '(Lenovo ?)?(IdeaTab ?)?[AB][0-9]{4,4}!!',
27
- 19 => '(Lenovo )?(Tab ?)?(2 ?)?[AS](7|8|10)!!',
28
- 20 => '(Lenovo ?)?(IdeaTab ?)?[KSV][0-9]{4,4}!!',
29
- 21 => '[0-9]0[0-9]LG!!',
30
- 22 => 'M\\-PP!!',
31
- 23 => 'M\\-MP!!',
32
- 24 => 'M\\-IPRO!!',
33
- 25 => '(MEDION|(MD )?LIFETAB)!!',
34
- 26 => 'M\\.T\\.T\\.!!',
35
- 27 => 'O\\+!!',
36
- 28 => '[0-9]{2,2}PFH6[0-9]{3,3}!',
37
- 29 => '(?:RIVO )?RHYTHM RX ?([0-9]+)!',
38
- 30 => '[4567A]0[0-9]SH!!',
39
- 31 => '(3|5|6|7)0[0-9]SH!!',
40
- 32 => 'C[0-9]{4,4}!!',
41
- 33 => 'D[0-9]{4,4}!!',
42
- 34 => 'E[0-9]{4,4}!!',
43
- 35 => 'F[0-9]{4,4}!!',
44
- 36 => 'G[0-9]{4,4}!!',
45
- 37 => 'H[0-9]{4,4}!!',
46
- 38 => 'I[0-9]{4,4}!!',
47
- 39 => 'E[0-9]{2,2}[a-z]!!',
48
- 40 => 'L[0-9]{2,2}[a-z]!!',
49
- 41 => '(SNM\\-)?M[0-9]{2,2}[a-z]!!',
50
- 42 => 'S[0-9]{2,2}[a-z]!!',
51
- 43 => '(XOLO )?[ABQX][0-9]{3,4}!!',
52
- 44 => '(ZTE ?)?N[0-9]{3,3}!!',
53
- 45 => '(ZXY-)?(ZTE )?N[0-9]{4,4}!!',
54
- 46 => '(ZTE ?)?U[0-9]{3,3}!!',
55
- 47 => '(ZTE ?)?V[0-9]{3,3}[A-Z]!!',
56
- 48 => '(ZTE ?)?V ?[0-9]{3,3}!!',
57
- 49 => '(ZTE ?)?X[0-9]{3,3}!!',
58
- 50 => '(ZTE )?Z[0-9]!!',
59
- 51 => '[a-z][a-z](?:-[a-z][a-z])?, SmartTabII7!',
60
  ),
61
  '@00' =>
62
  array (
@@ -135,10 +133,6 @@ DeviceModels::$ANDROID_INDEX = array (
135
  array (
136
  0 => '(3|5|6|7)0[0-9]SH!!',
137
  ),
138
- '@30' =>
139
- array (
140
- 0 => 3007,
141
- ),
142
  '@36' =>
143
  array (
144
  0 => '360 N4S',
@@ -168,7 +162,7 @@ DeviceModels::$ANDROID_INDEX = array (
168
  13 => '4027[ADNX]!',
169
  14 => '4028[AEJS]!',
170
  15 => '4032[ADEX]!',
171
- 16 => '4033[ADLX]!',
172
  17 => '4034[ADEFGX]!',
173
  18 => '4035[ADYX]!',
174
  19 => '4036[E]!',
@@ -176,14 +170,12 @@ DeviceModels::$ANDROID_INDEX = array (
176
  21 => '4037[T]!',
177
  22 => '4037[V]!',
178
  23 => '4045[ADEFLOYX]!',
179
- 24 => '4047[ADFGX]!',
180
- 25 => '4049[DG]!',
181
- 26 => '4055[JU]!',
182
- 27 => '4060[A]!',
183
- 28 => '4060[SW]!',
184
- 29 => '40[0-9]SC!!',
185
- 30 => '40[0-9]SO!!',
186
- 31 => '402ZT',
187
  ),
188
  '@48' =>
189
  array (
@@ -196,62 +188,50 @@ DeviceModels::$ANDROID_INDEX = array (
196
  '@50' =>
197
  array (
198
  0 => '5010[DEGSUX]!',
199
- 1 => '5011[A]!',
200
- 2 => '5012[G]!',
201
- 3 => '5015[ADEX]!',
202
- 4 => '5016[AJ]!',
203
- 5 => '5017[B]!',
204
- 6 => '5017[ADEOX]!',
205
- 7 => '5019[D]!',
206
- 8 => '5020[A]!',
207
- 9 => '5022[DEX]!',
208
- 10 => '5023[F]!',
209
- 11 => '5024[D]!',
210
- 12 => '5025[DEGX]!',
211
- 13 => '5027[B]!',
212
- 14 => '5033[ADJOX]!',
213
- 15 => '5034[D]!',
214
- 16 => '5036[D]!',
215
- 17 => '5038[ADEX]!',
216
- 18 => '5039[D]!',
217
- 19 => '5041[C]!',
218
- 20 => '5042[ADEFGTWXY]!',
219
- 21 => '5044[ADGIOSTY]!',
220
- 22 => '5045[ADFGJTXY]!',
221
- 23 => '5046[DGIJUY]!',
222
- 24 => '5047[DIUY]!',
223
- 25 => '5049[EGSWZ]!',
224
- 26 => '5050[ASYX]!',
225
- 27 => '5051[ADJMX]!',
226
- 28 => '5052[DY]!',
227
- 29 => '5053[D]!',
228
- 30 => '5054[ADOSTX]!',
229
- 31 => '5054[NW]!',
230
- 32 => '5056[ADEINUWX]!',
231
- 33 => '5056[O]!',
232
- 34 => '5057[M]!',
233
- 35 => '5058[I]!',
234
- 36 => '5059[ADJTXY]!',
235
- 37 => '5060[D]!',
236
- 38 => '5065[ADJNWX]!',
237
- 39 => '5070[DJX]!',
238
- 40 => '5080[A]!',
239
- 41 => '5080[DFQX]!',
240
- 42 => '5085[CDJNOYX]!',
241
- 43 => '5086[ADY]!',
242
- 44 => '5090[Y]!',
243
- 45 => '5095[BIKY]!',
244
- 46 => '5096[AI]!',
245
- 47 => '5098[OS]!',
246
- 48 => '5099[ADY]!',
247
- 49 => '504Q',
248
- 50 => '504Q+',
249
- 51 => '504QP',
250
- 52 => '501LV',
251
- 53 => '(48|50|55)AX600C!',
252
- 54 => '5080C Pro',
253
- 55 => '50[0-9]SO!!',
254
- 56 => '502ZT',
255
  ),
256
  '@55' =>
257
  array (
@@ -286,18 +266,11 @@ DeviceModels::$ANDROID_INDEX = array (
286
  9 => '6045[BFGIKOXY]!',
287
  10 => '6050[AFWY]!',
288
  11 => '6055[ABDHIKPUY]!',
289
- 12 => '6058[D]!',
290
- 13 => '6060[S]!',
291
- 14 => '6062[W]!',
292
- 15 => '6070[KOY]!',
293
- 16 => '602LV',
294
- 17 => '60[0-9]SO!!',
295
- 18 => '602ZT',
296
- 19 => '6034R ORANGE Niva',
297
- ),
298
- '@66' =>
299
- array (
300
- 0 => 6607,
301
  ),
302
  '@70' =>
303
  array (
@@ -469,12 +442,11 @@ DeviceModels::$ANDROID_INDEX = array (
469
  7 => 'A31',
470
  8 => 'A31c',
471
  9 => 'A31t',
472
- 10 => 'A31u',
473
- 11 => 'A33f',
474
- 12 => 'A33w',
475
- 13 => 'A37f',
476
- 14 => 'A37fw',
477
- 15 => 'A3',
478
  ),
479
  '@A4' =>
480
  array (
@@ -515,11 +487,10 @@ DeviceModels::$ANDROID_INDEX = array (
515
  17 => 'A500CG',
516
  18 => 'A55i',
517
  19 => 'A52',
518
- 20 => 'A51',
519
- 21 => 'A51f',
520
- 22 => 'A51w',
521
- 23 => 'A5000',
522
- 24 => 'a5',
523
  ),
524
  '@A6' =>
525
  array (
@@ -554,10 +525,9 @@ DeviceModels::$ANDROID_INDEX = array (
554
  16 => 'A750',
555
  17 => 'A7000-a',
556
  18 => 'A7010a48',
557
- 19 => 'A73',
558
- 20 => 'A7272+',
559
- 21 => 'A70(CY6T)',
560
- 22 => 'A78h四核(C1V3)',
561
  ),
562
  '@A8' =>
563
  array (
@@ -763,8 +733,8 @@ DeviceModels::$ANDROID_INDEX = array (
763
  33 => '(Allview|Alldro)!!',
764
  34 => 'Allwinner A10',
765
  35 => '(Highscreen|Alpha|Bay|Boost|Cosmo|Explosion|Power|Prime|Zera)!!',
766
- 36 => '(HUAWEI )?(ALP|BLA|CRR|EVR|HMA|LIO|LON|LYA|MATE|MHA|MT1|MT2|MT7|M200|NXT|SNE|TAS|Z100)!!',
767
- 37 => '(HW-|HUAWEI )?(ALE|ANE|CLT|D2|DAV|ELE|EML|EVA|FIG|G6|G7|GRA|M100|P2|P6|P7|PRA|RIO|SC|Sophia|STK|VIE|VKY|VNS|VOG|VTR|WAS)!!',
768
  38 => 'Alfa A93 POP',
769
  39 => 'Alfa L',
770
  40 => 'Ally',
@@ -849,7 +819,7 @@ DeviceModels::$ANDROID_INDEX = array (
849
  41 => 'AN10G2-LZ',
850
  42 => 'AN10BG3-LZ',
851
  43 => 'AN7DG3C',
852
- 44 => '(HW-|HUAWEI )?(ALE|ANE|CLT|D2|DAV|ELE|EML|EVA|FIG|G6|G7|GRA|M100|P2|P6|P7|PRA|RIO|SC|Sophia|STK|VIE|VKY|VNS|VOG|VTR|WAS)!!',
853
  45 => '(iBall )?Andi!!',
854
  46 => 'AND1',
855
  47 => 'AND1E',
@@ -995,44 +965,43 @@ DeviceModels::$ANDROID_INDEX = array (
995
  13 => 'AT1G*',
996
  14 => 'AT7E',
997
  15 => 'ATP515CKIT',
998
- 16 => '(HW-|HUAWEI )?(ATU|DRA|FLA|JKM|TIT|TAG||MRD|NCE|POT|TRT|SLA)!!',
999
- 17 => '(HW-|HUAWEI |HONOR )?(ATH|BLN|BKL|BKK|BND|CHE|CHM|COL|DUA|DUK|DLI|EDI|FRD|HLK|HN3|H30|H60|HOL|JMM|JSN|LRA|KIW|LLD|NEM|NMO|OXF|PE|PCT|PLK|RNE|SCL|TNY|KNT|CAM|STF|HDN|YAL)!!',
1000
- 18 => 'aTab9.7 IPS',
1001
- 19 => 'AT735',
1002
- 20 => 'Atrix 2',
1003
- 21 => 'Atrix 2 WeifanZ',
1004
- 22 => 'Atrix 4G',
1005
- 23 => 'Atrix 4G ME860',
1006
- 24 => 'Atrix 4G MB860',
1007
- 25 => 'Atrix HD',
1008
- 26 => 'AtrixHD',
1009
- 27 => 'ATLANTIS',
1010
- 28 => 'ATP7526',
1011
- 29 => 'ATP7683',
1012
- 30 => 'AT1S0',
1013
- 31 => 'AT7-A',
1014
- 32 => 'AT7-B',
1015
- 33 => 'AT7-C',
1016
- 34 => 'AT10-A',
1017
- 35 => 'AT10LE-A',
1018
- 36 => 'AT10PE-A',
1019
- 37 => 'AT100',
1020
- 38 => 'AT200',
1021
- 39 => 'AT270',
1022
- 40 => 'AT300',
1023
- 41 => 'AT300SE',
1024
- 42 => 'AT330',
1025
- 43 => 'AT374',
1026
- 44 => 'AT400',
1027
- 45 => 'AT470',
1028
- 46 => 'AT500',
1029
- 47 => 'AT500a',
1030
- 48 => 'AT503',
1031
- 49 => 'AT570',
1032
- 50 => 'AT703',
1033
- 51 => 'AT830',
1034
- 52 => 'AT-A[QS][0-9]{2,2}!!',
1035
- 53 => 'ATLAS W',
1036
  ),
1037
  '@AU' =>
1038
  array (
@@ -1092,13 +1061,12 @@ DeviceModels::$ANDROID_INDEX = array (
1092
  5 => 'Barnes & Noble Nook HD+',
1093
  6 => '(Highscreen|Alpha|Bay|Boost|Cosmo|Explosion|Power|Prime|Zera)!!',
1094
  7 => 'BAH-(W09|AL00|L09)!',
1095
- 8 => 'BAH2-(AL10|L09|W09|W19)!',
1096
- 9 => '(HW-|HUAWEI )?BAC-(AL00|L03|L21|L22|TL00)!',
1097
- 10 => 'Backflip',
1098
- 11 => 'Backflip Me600',
1099
- 12 => 'Bambook S1',
1100
- 13 => 'BARRY',
1101
- 14 => 'BASE!!',
1102
  ),
1103
  '@BB' =>
1104
  array (
@@ -1193,7 +1161,7 @@ DeviceModels::$ANDROID_INDEX = array (
1193
  '@BK' =>
1194
  array (
1195
  0 => '(BDS|BHX|BKO)\\-!!',
1196
- 1 => '(HW-|HUAWEI |HONOR )?(ATH|BLN|BKL|BKK|BND|CHE|CHM|COL|DUA|DUK|DLI|EDI|FRD|HLK|HN3|H30|H60|HOL|JMM|JSN|LRA|KIW|LLD|NEM|NMO|OXF|PE|PCT|PLK|RNE|SCL|TNY|KNT|CAM|STF|HDN|YAL)!!',
1197
  ),
1198
  '@BL' =>
1199
  array (
@@ -1206,8 +1174,8 @@ DeviceModels::$ANDROID_INDEX = array (
1206
  6 => 'Bluboo S1',
1207
  7 => 'Blaze S180',
1208
  8 => 'BLADE LE 70',
1209
- 9 => '(HUAWEI )?(ALP|BLA|CRR|EVR|HMA|LIO|LON|LYA|MATE|MHA|MT1|MT2|MT7|M200|NXT|SNE|TAS|Z100)!!',
1210
- 10 => '(HW-|HUAWEI |HONOR )?(ATH|BLN|BKL|BKK|BND|CHE|CHM|COL|DUA|DUK|DLI|EDI|FRD|HLK|HN3|H30|H60|HOL|JMM|JSN|LRA|KIW|LLD|NEM|NMO|OXF|PE|PCT|PLK|RNE|SCL|TNY|KNT|CAM|STF|HDN|YAL)!!',
1211
  11 => '(HW-|HUAWEI )?(BLL|CHC|TAG|KII)!!',
1212
  12 => '(BLF-)?lephone!!',
1213
  13 => 'Blackphone 2',
@@ -1233,7 +1201,7 @@ DeviceModels::$ANDROID_INDEX = array (
1233
  6 => '(NOOK )?BNTV(800)!',
1234
  7 => 'BN Nook HD',
1235
  8 => 'BN NookHD+',
1236
- 9 => '(HW-|HUAWEI |HONOR )?(ATH|BLN|BKL|BKK|BND|CHE|CHM|COL|DUA|DUK|DLI|EDI|FRD|HLK|HN3|H30|H60|HOL|JMM|JSN|LRA|KIW|LLD|NEM|NMO|OXF|PE|PCT|PLK|RNE|SCL|TNY|KNT|CAM|STF|HDN|YAL)!!',
1237
  ),
1238
  '@BO' =>
1239
  array (
@@ -1388,7 +1356,7 @@ DeviceModels::$ANDROID_INDEX = array (
1388
  9 => 'Casper VIA!!',
1389
  10 => 'CAT!!',
1390
  11 => 'Candy TV',
1391
- 12 => '(HW-|HUAWEI |HONOR )?(ATH|BLN|BKL|BKK|BND|CHE|CHM|COL|DUA|DUK|DLI|EDI|FRD|HLK|HN3|H30|H60|HOL|JMM|JSN|LRA|KIW|LLD|NEM|NMO|OXF|PE|PCT|PLK|RNE|SCL|TNY|KNT|CAM|STF|HDN|YAL)!!',
1392
  13 => '(HW-|HUAWEI )?(CRO|LUA|CUN|SCC|SCU|CAM|LDN|LYO|MYA)!!',
1393
  14 => '(HW-|HUAWEI )?CAZ-(AL10|TL10|TL20)!',
1394
  15 => '(HW-|HUAWEI )?CAN-(L01|L11|L12)!',
@@ -1423,7 +1391,7 @@ DeviceModels::$ANDROID_INDEX = array (
1423
  11 => 'Cherry w500',
1424
  12 => 'CHUWI!!',
1425
  13 => 'CHONG!!',
1426
- 14 => '(HW-|HUAWEI |HONOR )?(ATH|BLN|BKL|BKK|BND|CHE|CHM|COL|DUA|DUK|DLI|EDI|FRD|HLK|HN3|H30|H60|HOL|JMM|JSN|LRA|KIW|LLD|NEM|NMO|OXF|PE|PCT|PLK|RNE|SCL|TNY|KNT|CAM|STF|HDN|YAL)!!',
1427
  15 => '(HW-|HUAWEI )?(BLL|CHC|TAG|KII)!!',
1428
  16 => 'chagall',
1429
  17 => 'chiron',
@@ -1458,19 +1426,17 @@ DeviceModels::$ANDROID_INDEX = array (
1458
  4 => 'Clanga SE 097-1008',
1459
  5 => 'CLP281X',
1460
  6 => 'Click',
1461
- 7 => '(HW-|HUAWEI )?(ALE|ANE|CLT|D2|DAV|ELE|EML|EVA|FIG|G6|G7|GRA|M100|P2|P6|P7|PRA|RIO|SC|Sophia|STK|VIE|VKY|VNS|VOG|VTR|WAS)!!',
1462
- 8 => '(Intex )?Cloud!!',
1463
- 9 => 'CLIQ',
1464
- 10 => 'CLIQ XT',
1465
- 11 => 'CLIQ2',
1466
  ),
1467
  '@CM' =>
1468
  array (
1469
  0 => 'CMP!!',
1470
  1 => '(cm|aokp) tenderloin!',
1471
- 2 => 'CMR-(AL09|AL19|W09|W19)!',
1472
- 3 => 'CM980',
1473
- 4 => 'CM990',
1474
  ),
1475
  '@CN' =>
1476
  array (
@@ -1497,7 +1463,7 @@ DeviceModels::$ANDROID_INDEX = array (
1497
  15 => 'Connect-2G-2.0',
1498
  16 => '(Highscreen|Alpha|Bay|Boost|Cosmo|Explosion|Power|Prime|Zera)!!',
1499
  17 => 'Coquettish Red',
1500
- 18 => '(HW-|HUAWEI |HONOR )?(ATH|BLN|BKL|BKK|BND|CHE|CHM|COL|DUA|DUK|DLI|EDI|FRD|HLK|HN3|H30|H60|HOL|JMM|JSN|LRA|KIW|LLD|NEM|NMO|OXF|PE|PCT|PLK|RNE|SCL|TNY|KNT|CAM|STF|HDN|YAL)!!',
1501
  19 => 'Comet',
1502
  20 => 'Corvair',
1503
  21 => 'COOLPIX S800c',
@@ -1511,32 +1477,13 @@ DeviceModels::$ANDROID_INDEX = array (
1511
  2 => 'CP8676!',
1512
  3 => 'CP8298!',
1513
  4 => 'CPN-(W09|AL00|L09)!',
1514
- 5 => 'CPH1803',
1515
- 6 => 'CPH1809',
1516
- 7 => 'CPH1901',
1517
- 8 => 'CPH1937',
1518
- 9 => 'CPH1941',
1519
- 10 => 'CPH1605',
1520
- 11 => 'CPH1701',
1521
- 12 => 'CPH1717',
1522
- 13 => 'CPH1801',
1523
- 14 => 'CPH1729',
1524
- 15 => 'CPH1827',
1525
- 16 => 'CPH1609',
1526
- 17 => 'CPH1613',
1527
- 18 => 'CPH1723',
1528
- 19 => 'CPH1727',
1529
- 20 => 'CPH1819',
1530
- 21 => 'CPH1821',
1531
- 22 => 'CPH1859',
1532
- 23 => 'CPH1881',
1533
- 24 => 'CPH1823',
1534
- 25 => 'CPH1969',
1535
- 26 => 'CPH1721',
1536
- 27 => 'CPH1611',
1537
- 28 => 'CPH1879',
1538
- 29 => 'CPH1861',
1539
- 30 => 'CPH1979',
1540
  ),
1541
  '@CR' =>
1542
  array (
@@ -1544,7 +1491,7 @@ DeviceModels::$ANDROID_INDEX = array (
1544
  1 => 'CRESTA.CTP888',
1545
  2 => 'Cross!!',
1546
  3 => 'Crosscall!!',
1547
- 4 => '(HUAWEI )?(ALP|BLA|CRR|EVR|HMA|LIO|LON|LYA|MATE|MHA|MT1|MT2|MT7|M200|NXT|SNE|TAS|Z100)!!',
1548
  5 => '(HW-|HUAWEI )?(CRO|LUA|CUN|SCC|SCU|CAM|LDN|LYO|MYA)!!',
1549
  6 => 'CRONO 22',
1550
  7 => 'Crescent',
@@ -1617,7 +1564,7 @@ DeviceModels::$ANDROID_INDEX = array (
1617
  '@D2' =>
1618
  array (
1619
  0 => 'D2-[0-9]{3,3}!!',
1620
- 1 => '(HW-|HUAWEI )?(ALE|ANE|CLT|D2|DAV|ELE|EML|EVA|FIG|G6|G7|GRA|M100|P2|P6|P7|PRA|RIO|SC|Sophia|STK|VIE|VKY|VNS|VOG|VTR|WAS)!!',
1621
  ),
1622
  '@D5' =>
1623
  array (
@@ -1650,7 +1597,7 @@ DeviceModels::$ANDROID_INDEX = array (
1650
  1 => '(BLU|DASH|LIFE|NEO|STUDIO|VIVO)!!',
1651
  2 => 'Dakele A380',
1652
  3 => 'DAKELE MC001',
1653
- 4 => '(HW-|HUAWEI )?(ALE|ANE|CLT|D2|DAV|ELE|EML|EVA|FIG|G6|G7|GRA|M100|P2|P6|P7|PRA|RIO|SC|Sophia|STK|VIE|VKY|VNS|VOG|VTR|WAS)!!',
1654
  5 => 'DATAM803HC',
1655
  6 => 'DATAM805HC',
1656
  7 => 'DATAM819HD!',
@@ -1733,21 +1680,18 @@ DeviceModels::$ANDROID_INDEX = array (
1733
  1 => 'DL8006',
1734
  2 => 'DLX',
1735
  3 => 'DLXU',
1736
- 4 => '(HW-|HUAWEI |HONOR )?(ATH|BLN|BKL|BKK|BND|CHE|CHM|COL|DUA|DUK|DLI|EDI|FRD|HLK|HN3|H30|H60|HOL|JMM|JSN|LRA|KIW|LLD|NEM|NMO|OXF|PE|PCT|PLK|RNE|SCL|TNY|KNT|CAM|STF|HDN|YAL)!!',
1737
  5 => 'dL1',
1738
  ),
1739
  '@DM' =>
1740
  array (
1741
  0 => 'DM0[0-9]{2,2}(K|SH)!!',
1742
- 1 => 'DM001c Frozen',
1743
- 2 => 'DM001c Mickey',
1744
- 3 => 'DM001c Princess',
1745
- 4 => 'DM-01G',
1746
- 5 => 'DM-01K',
1747
- 6 => 'DM-02H',
1748
- 7 => 'DMC-CM1',
1749
- 8 => 'DM-01H',
1750
- 9 => 'DM-01J',
1751
  ),
1752
  '@DN' =>
1753
  array (
@@ -1783,7 +1727,7 @@ DeviceModels::$ANDROID_INDEX = array (
1783
  0 => 'Dream',
1784
  1 => '(GIO-)?(GiONEE[- ])?Dream D1!',
1785
  2 => 'Droid Incredible',
1786
- 3 => '(HW-|HUAWEI )?(ATU|DRA|FLA|JKM|TIT|TAG||MRD|NCE|POT|TRT|SLA)!!',
1787
  4 => 'DroniX-0.5',
1788
  5 => 'Droid',
1789
  6 => 'DROID',
@@ -1827,7 +1771,7 @@ DeviceModels::$ANDROID_INDEX = array (
1827
  ),
1828
  '@DU' =>
1829
  array (
1830
- 0 => '(HW-|HUAWEI |HONOR )?(ATH|BLN|BKL|BKK|BND|CHE|CHM|COL|DUA|DUK|DLI|EDI|FRD|HLK|HN3|H30|H60|HOL|JMM|JSN|LRA|KIW|LLD|NEM|NMO|OXF|PE|PCT|PLK|RNE|SCL|TNY|KNT|CAM|STF|HDN|YAL)!!',
1831
  ),
1832
  '@DW' =>
1833
  array (
@@ -1950,7 +1894,7 @@ DeviceModels::$ANDROID_INDEX = array (
1950
  array (
1951
  0 => '(bq|Aquaris|Edison|Maxwell)!!',
1952
  1 => 'edgejr',
1953
- 2 => '(HW-|HUAWEI |HONOR )?(ATH|BLN|BKL|BKK|BND|CHE|CHM|COL|DUA|DUK|DLI|EDI|FRD|HLK|HN3|H30|H60|HOL|JMM|JSN|LRA|KIW|LLD|NEM|NMO|OXF|PE|PCT|PLK|RNE|SCL|TNY|KNT|CAM|STF|HDN|YAL)!!',
1954
  3 => 'edenTAB ET-701',
1955
  ),
1956
  '@EE' =>
@@ -1986,38 +1930,37 @@ DeviceModels::$ANDROID_INDEX = array (
1986
  4 => 'ELIFE-E3',
1987
  5 => 'Elife E5',
1988
  6 => 'ElifeE6',
1989
- 7 => '(HW-|HUAWEI )?(ALE|ANE|CLT|D2|DAV|ELE|EML|EVA|FIG|G6|G7|GRA|M100|P2|P6|P7|PRA|RIO|SC|Sophia|STK|VIE|VKY|VNS|VOG|VTR|WAS)!!',
1990
- 8 => 'Elektra L',
1991
- 9 => 'Elektra XL',
1992
- 10 => 'Electrify',
1993
- 11 => 'Eluga A2',
1994
- 12 => 'ELUGA A3',
1995
- 13 => 'ELUGA A3 Pro',
1996
- 14 => 'ELUGA I2',
1997
- 15 => 'ELUGA I2 Activ',
1998
- 16 => 'ELUGA I4',
1999
- 17 => 'Eluga Arc 2',
2000
- 18 => 'Eluga Mark 2',
2001
- 19 => 'ELUGA Note',
2002
- 20 => 'ELUGA Prim',
2003
- 21 => 'ELUGA Pulse X',
2004
- 22 => 'ELUGA Ray',
2005
- 23 => 'ELUGA Ray Max',
2006
- 24 => 'ELUGA Ray X',
2007
- 25 => 'Eluga Ray 700',
2008
- 26 => 'ELUGA Turbo',
2009
- 27 => 'Elite',
2010
- 28 => 'Elite 11',
2011
- 29 => '(SENCOR )?ELEMENT!!',
2012
- 30 => 'Elite 5.5L+',
2013
- 31 => 'Elite 6.0L',
2014
  ),
2015
  '@EM' =>
2016
  array (
2017
  0 => 'EMBT3C',
2018
  1 => 'EM63',
2019
  2 => 'EM01F',
2020
- 3 => '(HW-|HUAWEI )?(ALE|ANE|CLT|D2|DAV|ELE|EML|EVA|FIG|G6|G7|GRA|M100|P2|P6|P7|PRA|RIO|SC|Sophia|STK|VIE|VKY|VNS|VOG|VTR|WAS)!!',
2021
  4 => 'eMAX mini',
2022
  5 => 'EMR1879',
2023
  ),
@@ -2080,11 +2023,10 @@ DeviceModels::$ANDROID_INDEX = array (
2080
  8 => 'EVO ?3D!',
2081
  9 => 'EVO 4G',
2082
  10 => 'Evo V 4G',
2083
- 11 => '(HUAWEI )?(ALP|BLA|CRR|EVR|HMA|LIO|LON|LYA|MATE|MHA|MT1|MT2|MT7|M200|NXT|SNE|TAS|Z100)!!',
2084
- 12 => '(HW-|HUAWEI )?(ALE|ANE|CLT|D2|DAV|ELE|EML|EVA|FIG|G6|G7|GRA|M100|P2|P6|P7|PRA|RIO|SC|Sophia|STK|VIE|VKY|VNS|VOG|VTR|WAS)!!',
2085
- 13 => '(EV|KM)-[ES][0-9]{3,3}!!',
2086
- 14 => 'Event',
2087
- 15 => 'EVERY35',
2088
  ),
2089
  '@EX' =>
2090
  array (
@@ -2160,7 +2102,7 @@ DeviceModels::$ANDROID_INDEX = array (
2160
  array (
2161
  0 => 'FIH-FB0',
2162
  1 => 'FIH-!!',
2163
- 2 => '(HW-|HUAWEI )?(ALE|ANE|CLT|D2|DAV|ELE|EML|EVA|FIG|G6|G7|GRA|M100|P2|P6|P7|PRA|RIO|SC|Sophia|STK|VIE|VKY|VNS|VOG|VTR|WAS)!!',
2164
  3 => 'Find 5',
2165
  4 => 'FIND7',
2166
  ),
@@ -2199,7 +2141,7 @@ DeviceModels::$ANDROID_INDEX = array (
2199
  25 => 'Flylife!!',
2200
  26 => 'Fly Flylife Web 7.85 Slim',
2201
  27 => 'Flyer',
2202
- 28 => '(HW-|HUAWEI )?(ATU|DRA|FLA|JKM|TIT|TAG||MRD|NCE|POT|TRT|SLA)!!',
2203
  29 => 'Flair E1',
2204
  30 => 'Flair E2',
2205
  31 => 'FlairE3',
@@ -2245,7 +2187,7 @@ DeviceModels::$ANDROID_INDEX = array (
2245
  '@FR' =>
2246
  array (
2247
  0 => 'Freelander I20',
2248
- 1 => '(HW-|HUAWEI |HONOR )?(ATH|BLN|BKL|BKK|BND|CHE|CHM|COL|DUA|DUK|DLI|EDI|FRD|HLK|HN3|H30|H60|HOL|JMM|JSN|LRA|KIW|LLD|NEM|NMO|OXF|PE|PCT|PLK|RNE|SCL|TNY|KNT|CAM|STF|HDN|YAL)!!',
2249
  2 => '(MODECOM )?FreeTAB!!',
2250
  ),
2251
  '@FS' =>
@@ -2326,11 +2268,11 @@ DeviceModels::$ANDROID_INDEX = array (
2326
  ),
2327
  '@G6' =>
2328
  array (
2329
- 0 => '(HW-|HUAWEI )?(ALE|ANE|CLT|D2|DAV|ELE|EML|EVA|FIG|G6|G7|GRA|M100|P2|P6|P7|PRA|RIO|SC|Sophia|STK|VIE|VKY|VNS|VOG|VTR|WAS)!!',
2330
  ),
2331
  '@G7' =>
2332
  array (
2333
- 0 => '(HW-|HUAWEI )?(ALE|ANE|CLT|D2|DAV|ELE|EML|EVA|FIG|G6|G7|GRA|M100|P2|P6|P7|PRA|RIO|SC|Sophia|STK|VIE|VKY|VNS|VOG|VTR|WAS)!!',
2334
  ),
2335
  '@G9' =>
2336
  array (
@@ -2497,21 +2439,18 @@ DeviceModels::$ANDROID_INDEX = array (
2497
  ),
2498
  '@GM' =>
2499
  array (
2500
- 0 => 'GM190[0135]!',
2501
- 1 => 'GM191[01357]!',
2502
- 2 => 'Gm Discovery',
2503
- 3 => 'GM Discovery II',
2504
- 4 => 'GM Discovery II+',
2505
- 5 => 'GM FOX',
2506
- 6 => 'GM Ultimate Slim',
2507
- 7 => 'GM 5',
2508
- 8 => 'GM 5 d',
2509
- 9 => 'GM 5 Plus',
2510
- 10 => 'GM 5 Plus d',
2511
- 11 => 'GM 6',
2512
- 12 => 'GM 6 d',
2513
- 13 => 'GM 8 d',
2514
- 14 => 'GM Discovery tab 8',
2515
  ),
2516
  '@GN' =>
2517
  array (
@@ -2587,22 +2526,23 @@ DeviceModels::$ANDROID_INDEX = array (
2587
  10 => '(Google )?Nexus ?9!',
2588
  11 => '(Google )?Nexus ?10!',
2589
  12 => 'Google Pixel',
2590
- 13 => 'Google Pixel 2',
2591
- 14 => 'Google Pixel 2XL',
2592
- 15 => 'Google Chromebook Pixel (2015)',
2593
- 16 => 'google cube',
2594
- 17 => 'GOCL!!',
2595
- 18 => 'GO Live!!',
2596
- 19 => 'GOOPHONE!!',
2597
- 20 => 'GO !!',
2598
- 21 => 'GOA',
2599
- 22 => 'GO504',
2600
- 23 => 'GO778',
2601
- 24 => 'GO960',
2602
- 25 => 'GO963',
2603
- 26 => 'GO980',
2604
- 27 => 'GO984',
2605
- 28 => 'Gomobile GO1001',
 
2606
  ),
2607
  '@GP' =>
2608
  array (
@@ -2620,7 +2560,7 @@ DeviceModels::$ANDROID_INDEX = array (
2620
  array (
2621
  0 => 'Grouper',
2622
  1 => 'GR-TB!!',
2623
- 2 => '(HW-|HUAWEI )?(ALE|ANE|CLT|D2|DAV|ELE|EML|EVA|FIG|G6|G7|GRA|M100|P2|P6|P7|PRA|RIO|SC|Sophia|STK|VIE|VKY|VNS|VOG|VTR|WAS)!!',
2624
  3 => 'greenridge',
2625
  4 => 'Graphos A10',
2626
  5 => '(ZTE )?(Grand|Mimosa)!!',
@@ -2682,11 +2622,11 @@ DeviceModels::$ANDROID_INDEX = array (
2682
  ),
2683
  '@H3' =>
2684
  array (
2685
- 0 => '(HW-|HUAWEI |HONOR )?(ATH|BLN|BKL|BKK|BND|CHE|CHM|COL|DUA|DUK|DLI|EDI|FRD|HLK|HN3|H30|H60|HOL|JMM|JSN|LRA|KIW|LLD|NEM|NMO|OXF|PE|PCT|PLK|RNE|SCL|TNY|KNT|CAM|STF|HDN|YAL)!!',
2686
  ),
2687
  '@H6' =>
2688
  array (
2689
- 0 => '(HW-|HUAWEI |HONOR )?(ATH|BLN|BKL|BKK|BND|CHE|CHM|COL|DUA|DUK|DLI|EDI|FRD|HLK|HN3|H30|H60|HOL|JMM|JSN|LRA|KIW|LLD|NEM|NMO|OXF|PE|PCT|PLK|RNE|SCL|TNY|KNT|CAM|STF|HDN|YAL)!!',
2690
  ),
2691
  '@H7' =>
2692
  array (
@@ -2732,9 +2672,7 @@ DeviceModels::$ANDROID_INDEX = array (
2732
  0 => 'HD2',
2733
  1 => 'HD2 LEO',
2734
  2 => 'HD7 Pro',
2735
- 3 => '(HW-|HUAWEI |HONOR )?(ATH|BLN|BKL|BKK|BND|CHE|CHM|COL|DUA|DUK|DLI|EDI|FRD|HLK|HN3|H30|H60|HOL|JMM|JSN|LRA|KIW|LLD|NEM|NMO|OXF|PE|PCT|PLK|RNE|SCL|TNY|KNT|CAM|STF|HDN|YAL)!!',
2736
- 4 => 'HD190[01]!',
2737
- 5 => 'HD191[03]!',
2738
  ),
2739
  '@HE' =>
2740
  array (
@@ -2770,25 +2708,23 @@ DeviceModels::$ANDROID_INDEX = array (
2770
  '@HL' =>
2771
  array (
2772
  0 => 'HLV-T!!',
2773
- 1 => '(HW-|HUAWEI |HONOR )?(ATH|BLN|BKL|BKK|BND|CHE|CHM|COL|DUA|DUK|DLI|EDI|FRD|HLK|HN3|H30|H60|HOL|JMM|JSN|LRA|KIW|LLD|NEM|NMO|OXF|PE|PCT|PLK|RNE|SCL|TNY|KNT|CAM|STF|HDN|YAL)!!',
2774
  ),
2775
  '@HM' =>
2776
  array (
2777
- 0 => '(HUAWEI )?(ALP|BLA|CRR|EVR|HMA|LIO|LON|LYA|MATE|MHA|MT1|MT2|MT7|M200|NXT|SNE|TAS|Z100)!!',
2778
- 1 => 'HMP8100 ATV 93',
2779
- 2 => 'HMP8100 ATV INT',
2780
- 3 => '(Xiaomi )?(Redmi|RedRice|HM)!!',
2781
- 4 => '(Xiaomi )?(Redmi|HM)[ \\-]?Note!!',
2782
- 5 => '(Xiaomi |HM)?20!!',
2783
  ),
2784
  '@HN' =>
2785
  array (
2786
- 0 => '(HW-|HUAWEI |HONOR )?(ATH|BLN|BKL|BKK|BND|CHE|CHM|COL|DUA|DUK|DLI|EDI|FRD|HLK|HN3|H30|H60|HOL|JMM|JSN|LRA|KIW|LLD|NEM|NMO|OXF|PE|PCT|PLK|RNE|SCL|TNY|KNT|CAM|STF|HDN|YAL)!!',
2787
  ),
2788
  '@HO' =>
2789
  array (
2790
  0 => 'HOSIN!!',
2791
- 1 => '(HW-|HUAWEI |HONOR )?(ATH|BLN|BKL|BKK|BND|CHE|CHM|COL|DUA|DUK|DLI|EDI|FRD|HLK|HN3|H30|H60|HOL|JMM|JSN|LRA|KIW|LLD|NEM|NMO|OXF|PE|PCT|PLK|RNE|SCL|TNY|KNT|CAM|STF|HDN|YAL)!!',
2792
  2 => 'Honor3c2G-T',
2793
  3 => 'Honor Bee',
2794
  4 => 'HOMESYNCT2WIFI',
@@ -2845,11 +2781,11 @@ DeviceModels::$ANDROID_INDEX = array (
2845
  6 => 'Huawei MediaPad T1 10 4G',
2846
  7 => '(Huawei )?[MSTX](1|2|7|8|10)\\-[A-Z0-9][0-9]{2,2}!!',
2847
  8 => 'HUAWEI GEM-703L',
2848
- 9 => '(HUAWEI )?(ALP|BLA|CRR|EVR|HMA|LIO|LON|LYA|MATE|MHA|MT1|MT2|MT7|M200|NXT|SNE|TAS|Z100)!!',
2849
- 10 => '(HW-|HUAWEI )?(ATU|DRA|FLA|JKM|TIT|TAG||MRD|NCE|POT|TRT|SLA)!!',
2850
- 11 => '(HW-|HUAWEI |HONOR )?(ATH|BLN|BKL|BKK|BND|CHE|CHM|COL|DUA|DUK|DLI|EDI|FRD|HLK|HN3|H30|H60|HOL|JMM|JSN|LRA|KIW|LLD|NEM|NMO|OXF|PE|PCT|PLK|RNE|SCL|TNY|KNT|CAM|STF|HDN|YAL)!!',
2851
  12 => '(HW-|HUAWEI )?(BLL|CHC|TAG|KII)!!',
2852
- 13 => '(HW-|HUAWEI )?(ALE|ANE|CLT|D2|DAV|ELE|EML|EVA|FIG|G6|G7|GRA|M100|P2|P6|P7|PRA|RIO|SC|Sophia|STK|VIE|VKY|VNS|VOG|VTR|WAS)!!',
2853
  14 => 'HUAWEI A168-(AL10|DL09|L09|L29)!',
2854
  15 => '(HW-|HUAWEI )?(CRO|LUA|CUN|SCC|SCU|CAM|LDN|LYO|MYA)!!',
2855
  16 => '(HW-|HUAWEI )?CAZ-(AL10|TL10|TL20)!',
@@ -2858,27 +2794,24 @@ DeviceModels::$ANDROID_INDEX = array (
2858
  19 => '(HW-|HUAWEI )?DIG-(AL00|L01|L03|L21|TL10)!',
2859
  20 => '(HW-|HUAWEI )?BAC-(AL00|L03|L21|L22|TL00)!',
2860
  21 => '(HW-|HUAWEI )?HWI-(AL00|TL00)!',
2861
- 22 => '(HW-|HUAWEI )?PAR-(AL00|LX1|LX1M|LX9|TL00)!',
2862
- 23 => '(HW-|HUAWEI )?INE-(AL00|LX1|LX1r|LX2||LX2r|TL00)!',
2863
- 24 => '(HW-|HUAWEI )?MAR-(AL00|LX1A|LX1M|LX2|LX3A|TL00)!',
2864
- 25 => '(HW-|HUAWEI )?MLA-(AL00|AL10)!',
2865
- 26 => '(HW-|HUAWEI )?MLA-(TL00|TL10|UL00)!',
2866
- 27 => 'Huawei P7 mini',
2867
- 28 => 'Huawei P8max',
2868
- 29 => '(Huawei|Ascend|HW-)!!',
2869
- 30 => 'HUAWEI Honor 3c w',
2870
- 31 => 'Huawei S7',
2871
- 32 => 'Hudl HT7S3',
2872
- 33 => 'Hudl 2',
2873
- 34 => 'HUAWEI U8686',
2874
- 35 => 'Huawei 858',
2875
  ),
2876
  '@HW' =>
2877
  array (
2878
- 0 => '(HW-|HUAWEI )?(ATU|DRA|FLA|JKM|TIT|TAG||MRD|NCE|POT|TRT|SLA)!!',
2879
- 1 => '(HW-|HUAWEI |HONOR )?(ATH|BLN|BKL|BKK|BND|CHE|CHM|COL|DUA|DUK|DLI|EDI|FRD|HLK|HN3|H30|H60|HOL|JMM|JSN|LRA|KIW|LLD|NEM|NMO|OXF|PE|PCT|PLK|RNE|SCL|TNY|KNT|CAM|STF|HDN|YAL)!!',
2880
  2 => '(HW-|HUAWEI )?(BLL|CHC|TAG|KII)!!',
2881
- 3 => '(HW-|HUAWEI )?(ALE|ANE|CLT|D2|DAV|ELE|EML|EVA|FIG|G6|G7|GRA|M100|P2|P6|P7|PRA|RIO|SC|Sophia|STK|VIE|VKY|VNS|VOG|VTR|WAS)!!',
2882
  4 => '(HW-|HUAWEI )?(CRO|LUA|CUN|SCC|SCU|CAM|LDN|LYO|MYA)!!',
2883
  5 => '(HW-|HUAWEI )?CAZ-(AL10|TL10|TL20)!',
2884
  6 => '(HW-|HUAWEI )?CAN-(L01|L11|L12)!',
@@ -2886,18 +2819,15 @@ DeviceModels::$ANDROID_INDEX = array (
2886
  8 => '(HW-|HUAWEI )?DIG-(AL00|L01|L03|L21|TL10)!',
2887
  9 => '(HW-|HUAWEI )?BAC-(AL00|L03|L21|L22|TL00)!',
2888
  10 => '(HW-|HUAWEI )?HWI-(AL00|TL00)!',
2889
- 11 => '(HW-|HUAWEI )?PAR-(AL00|LX1|LX1M|LX9|TL00)!',
2890
- 12 => '(HW-|HUAWEI )?INE-(AL00|LX1|LX1r|LX2||LX2r|TL00)!',
2891
- 13 => '(HW-|HUAWEI )?MAR-(AL00|LX1A|LX1M|LX2|LX3A|TL00)!',
2892
- 14 => '(HW-|HUAWEI )?MLA-(AL00|AL10)!',
2893
- 15 => '(HW-|HUAWEI )?MLA-(TL00|TL10|UL00)!',
2894
- 16 => '(Huawei|Ascend|HW-)!!',
2895
- 17 => 'hwu8812D',
2896
- 18 => 'HW-01E',
2897
- 19 => 'HW-01K',
2898
- 20 => 'HW-03E',
2899
- 21 => 'HWT31',
2900
- 22 => 'HWV32',
2901
  ),
2902
  '@HY' =>
2903
  array (
@@ -3021,23 +2951,22 @@ DeviceModels::$ANDROID_INDEX = array (
3021
  7 => 'Incredible ?2!',
3022
  8 => 'Incredible 4G LTE',
3023
  9 => 'Inspire 4G',
3024
- 10 => '(HW-|HUAWEI )?INE-(AL00|LX1|LX1r|LX2||LX2r|TL00)!',
3025
- 11 => 'INFOBAR!!',
3026
- 12 => 'Infinix!!',
3027
- 13 => 'IN[0-9]{3,3}!!',
3028
- 14 => 'Infocus!!',
3029
- 15 => 'INHON PAPILIO G1',
3030
- 16 => 'intki E86',
3031
- 17 => 'Innos!!',
3032
- 18 => '(Intex )?Aqua!!',
3033
- 19 => '(Intex )?Cloud!!',
3034
- 20 => 'INTEX IRIS-II',
3035
- 21 => 'INQ Cloud Touch',
3036
- 22 => 'INQ Mayfair (EU)',
3037
- 23 => '(iNote|itel)!!',
3038
- 24 => 'Infinity',
3039
- 25 => 'Internet TV',
3040
- 26 => 'Internet TV Box',
3041
  ),
3042
  '@IO' =>
3043
  array (
@@ -3119,8 +3048,6 @@ DeviceModels::$ANDROID_INDEX = array (
3119
  '@JD' =>
3120
  array (
3121
  0 => 'JDN-W09',
3122
- 1 => 'JDN2-AL00HN',
3123
- 2 => 'JDN2-W09HN',
3124
  ),
3125
  '@JI' =>
3126
  array (
@@ -3131,13 +3058,9 @@ DeviceModels::$ANDROID_INDEX = array (
3131
  array (
3132
  0 => 'JJ5S+',
3133
  ),
3134
- '@JK' =>
3135
- array (
3136
- 0 => '(HW-|HUAWEI )?(ATU|DRA|FLA|JKM|TIT|TAG||MRD|NCE|POT|TRT|SLA)!!',
3137
- ),
3138
  '@JM' =>
3139
  array (
3140
- 0 => '(HW-|HUAWEI |HONOR )?(ATH|BLN|BKL|BKK|BND|CHE|CHM|COL|DUA|DUK|DLI|EDI|FRD|HLK|HN3|H30|H60|HOL|JMM|JSN|LRA|KIW|LLD|NEM|NMO|OXF|PE|PCT|PLK|RNE|SCL|TNY|KNT|CAM|STF|HDN|YAL)!!',
3141
  ),
3142
  '@JO' =>
3143
  array (
@@ -3145,10 +3068,6 @@ DeviceModels::$ANDROID_INDEX = array (
3145
  1 => 'Joy',
3146
  2 => 'JOIN',
3147
  ),
3148
- '@JS' =>
3149
- array (
3150
- 0 => '(HW-|HUAWEI |HONOR )?(ATH|BLN|BKL|BKK|BND|CHE|CHM|COL|DUA|DUK|DLI|EDI|FRD|HLK|HN3|H30|H60|HOL|JMM|JSN|LRA|KIW|LLD|NEM|NMO|OXF|PE|PCT|PLK|RNE|SCL|TNY|KNT|CAM|STF|HDN|YAL)!!',
3151
- ),
3152
  '@JT' =>
3153
  array (
3154
  0 => 'JT SmartPC02',
@@ -3267,13 +3186,11 @@ DeviceModels::$ANDROID_INDEX = array (
3267
  14 => 'KFGIWI',
3268
  15 => 'KFDOWI',
3269
  16 => 'KFSUWI',
3270
- 17 => 'KFMAWI',
3271
- 18 => 'KFMUWI',
3272
  ),
3273
  '@KI' =>
3274
  array (
3275
  0 => 'Kindle Fire',
3276
- 1 => '(HW-|HUAWEI |HONOR )?(ATH|BLN|BKL|BKK|BND|CHE|CHM|COL|DUA|DUK|DLI|EDI|FRD|HLK|HN3|H30|H60|HOL|JMM|JSN|LRA|KIW|LLD|NEM|NMO|OXF|PE|PCT|PLK|RNE|SCL|TNY|KNT|CAM|STF|HDN|YAL)!!',
3277
  2 => '(HW-|HUAWEI )?(BLL|CHC|TAG|KII)!!',
3278
  3 => 'KIOTO 793',
3279
  4 => 'KITE',
@@ -3285,7 +3202,7 @@ DeviceModels::$ANDROID_INDEX = array (
3285
  ),
3286
  '@KN' =>
3287
  array (
3288
- 0 => '(HW-|HUAWEI |HONOR )?(ATH|BLN|BKL|BKK|BND|CHE|CHM|COL|DUA|DUK|DLI|EDI|FRD|HLK|HN3|H30|H60|HOL|JMM|JSN|LRA|KIW|LLD|NEM|NMO|OXF|PE|PCT|PLK|RNE|SCL|TNY|KNT|CAM|STF|HDN|YAL)!!',
3289
  ),
3290
  '@KO' =>
3291
  array (
@@ -3524,123 +3441,95 @@ DeviceModels::$ANDROID_INDEX = array (
3524
  12 => 'LG-DS1203',
3525
  13 => 'LG-?E[0-9]{3,3}!!',
3526
  14 => 'LG-F[0-9]{3,3}!!',
3527
- 15 => 'LG-FL40L!',
3528
- 16 => 'LG-GT540!',
3529
- 17 => 'LG-GW620!',
3530
- 18 => 'LG-H[0-9]{3,3}!!',
3531
- 19 => 'LG-K[0-9]{3,3}!!',
3532
- 20 => 'LG-KH5200',
3533
- 21 => 'LG-KS1024',
3534
- 22 => 'LG-KU[0-9]{4,4}!!',
3535
- 23 => 'LG-?L[0-9]{2,3}[A-Z]!!',
3536
- 24 => 'LG-LG[0-9]{3,3}!!',
3537
- 25 => 'LGLK430',
3538
- 26 => 'LG-LK460',
3539
- 27 => 'LG-?LS[0-9]{3,3}!!',
3540
- 28 => 'LG-LU[0-9]{4,4}!!',
3541
- 29 => 'LG-LW690',
3542
- 30 => 'LG-LW770',
3543
- 31 => 'LG-M[0-9]{3,3}!!',
3544
- 32 => 'LG-?MS[0-9]{3,3}!!',
3545
- 33 => 'LGMP260',
3546
- 34 => 'LG-P[0-9]{3,3}!!',
3547
- 35 => 'LG-Q710!',
3548
- 36 => 'LG-RS988!',
3549
- 37 => 'LG-SP[0-9]{3,3}!!',
3550
- 38 => 'LG-SU[0-9]{3,3}!!',
3551
- 39 => 'LG-T480!',
3552
- 40 => 'LG-T540!',
3553
- 41 => 'LG-TP260',
3554
- 42 => 'LG-TP450',
3555
- 43 => 'LG-SU-760',
3556
- 44 => 'LGUK410',
3557
- 45 => 'LG-UK495',
3558
- 46 => 'LGUK750',
3559
- 47 => 'LGUK932',
3560
- 48 => 'LG-UN350',
3561
- 49 => 'LG-?US[0-9]{3,3}!!',
3562
- 50 => 'LG-V[0-9]{3,3}!!',
3563
- 51 => 'LG-VK[0-9]{3,3}!!',
3564
- 52 => 'LG-VN[0-9]{3,3}!!',
3565
- 53 => 'LG-VM[0-9]{3,3}!!',
3566
- 54 => 'LG-VS[0-9]{3,3}!!',
3567
- 55 => 'LG-X[0-9]{3,3}!!',
3568
- 56 => 'LGM-[GKVX][0-9]{3,3}!!',
3569
- 57 => 'LGMP450',
3570
- 58 => 'lge-F160!',
3571
- 59 => 'LGE-E988!',
3572
- 60 => 'lgp-970',
3573
- 61 => 'LG[LSTV][0-9]{2,2}!!',
3574
- 62 => 'LG!!',
3575
- 63 => 'LG-Google TV!!',
3576
- 64 => 'LG-ANDROID MINI BOX',
3577
- 65 => 'LG-P999',
3578
- 66 => 'LG-E739',
3579
- 67 => 'LG-C800',
3580
  ),
3581
  '@LI' =>
3582
  array (
3583
  0 => 'Liquid!!',
3584
  1 => '(BLU|DASH|LIFE|NEO|STUDIO|VIVO)!!',
3585
  2 => 'Liberty',
3586
- 3 => '(HUAWEI )?(ALP|BLA|CRR|EVR|HMA|LIO|LON|LYA|MATE|MHA|MT1|MT2|MT7|M200|NXT|SNE|TAS|Z100)!!',
3587
- 4 => '(MEDION|(MD )?LIFETAB)!!',
3588
- 5 => 'Life',
3589
- 6 => 'Liberty Tab G100',
3590
- 7 => 'Live ?With ?Walkman!',
3591
- 8 => 'libra',
3592
- 9 => 'lithium',
3593
- 10 => 'Light Tab',
3594
- 11 => 'Light Tab 2',
3595
- 12 => 'Light Tab 2W',
3596
  ),
3597
  '@LL' =>
3598
  array (
3599
- 0 => '(HW-|HUAWEI |HONOR )?(ATH|BLN|BKL|BKK|BND|CHE|CHM|COL|DUA|DUK|DLI|EDI|FRD|HLK|HN3|H30|H60|HOL|JMM|JSN|LRA|KIW|LLD|NEM|NMO|OXF|PE|PCT|PLK|RNE|SCL|TNY|KNT|CAM|STF|HDN|YAL)!!',
3600
  1 => '(Lanix )?(Ilium|llium)!!',
3601
  ),
3602
  '@LM' =>
3603
  array (
3604
  0 => 'LM-G710!',
3605
  1 => 'LM-G715!',
3606
- 2 => 'LM-G810!',
3607
- 3 => 'LM-G820!',
3608
- 4 => 'LM-Q610!',
3609
- 5 => 'LM-Q617!',
3610
- 6 => 'LM-Q710!',
3611
- 7 => 'LM-Q720!',
3612
- 8 => 'LM-Q725!',
3613
- 9 => 'LM-Q815!',
3614
- 10 => 'LM-Q850!',
3615
- 11 => 'LM-Q910!',
3616
- 12 => 'LM-Q925!',
3617
- 13 => 'LM-V350!',
3618
- 14 => 'LM-V40[59]!',
3619
- 15 => 'LM-V450!',
3620
- 16 => 'LM-V500!',
3621
- 17 => 'LM-X120!',
3622
- 18 => 'LM-X210!',
3623
- 19 => 'LM-X212!',
3624
- 20 => 'LM-X220!',
3625
- 21 => 'LM-X320!',
3626
- 22 => 'LM-X410!',
3627
- 23 => 'LM-X415!',
3628
- 24 => 'LM-X420!',
3629
- 25 => 'LM-X510!',
3630
- 26 => 'LM-X525!',
3631
- 27 => 'LM-X625!',
3632
- 28 => 'LM-Y110!',
3633
  ),
3634
  '@LO' =>
3635
  array (
3636
  0 => 'LogicPD Zoom2',
3637
- 1 => '(HUAWEI )?(ALP|BLA|CRR|EVR|HMA|LIO|LON|LYA|MATE|MHA|MT1|MT2|MT7|M200|NXT|SNE|TAS|Z100)!!',
3638
  2 => 'Loox',
3639
  ),
3640
- '@LR' =>
3641
- array (
3642
- 0 => '(HW-|HUAWEI |HONOR )?(ATH|BLN|BKL|BKK|BND|CHE|CHM|COL|DUA|DUK|DLI|EDI|FRD|HLK|HN3|H30|H60|HOL|JMM|JSN|LRA|KIW|LLD|NEM|NMO|OXF|PE|PCT|PLK|RNE|SCL|TNY|KNT|CAM|STF|HDN|YAL)!!',
3643
- ),
3644
  '@LS' =>
3645
  array (
3646
  0 => 'LS670',
@@ -3711,10 +3600,9 @@ DeviceModels::$ANDROID_INDEX = array (
3711
  ),
3712
  '@LY' =>
3713
  array (
3714
- 0 => '(HUAWEI )?(ALP|BLA|CRR|EVR|HMA|LIO|LON|LYA|MATE|MHA|MT1|MT2|MT7|M200|NXT|SNE|TAS|Z100)!!',
3715
- 1 => '(HW-|HUAWEI )?(CRO|LUA|CUN|SCC|SCU|CAM|LDN|LYO|MYA)!!',
3716
- 2 => 'LYF LS-4006',
3717
- 3 => 'LYF LS-5009',
3718
  ),
3719
  '@M' =>
3720
  array (
@@ -3745,7 +3633,7 @@ DeviceModels::$ANDROID_INDEX = array (
3745
  '@M1' =>
3746
  array (
3747
  0 => 'M19',
3748
- 1 => '(HW-|HUAWEI )?(ALE|ANE|CLT|D2|DAV|ELE|EML|EVA|FIG|G6|G7|GRA|M100|P2|P6|P7|PRA|RIO|SC|Sophia|STK|VIE|VKY|VNS|VOG|VTR|WAS)!!',
3749
  2 => 'M1050S',
3750
  3 => 'M1',
3751
  4 => 'm1 metal',
@@ -3755,7 +3643,7 @@ DeviceModels::$ANDROID_INDEX = array (
3755
  ),
3756
  '@M2' =>
3757
  array (
3758
- 0 => '(HUAWEI )?(ALP|BLA|CRR|EVR|HMA|LIO|LON|LYA|MATE|MHA|MT1|MT2|MT7|M200|NXT|SNE|TAS|Z100)!!',
3759
  1 => 'M210',
3760
  2 => 'm2 note',
3761
  3 => 'm2',
@@ -3843,20 +3731,18 @@ DeviceModels::$ANDROID_INDEX = array (
3843
  2 => 'manta',
3844
  3 => '(bq|Aquaris|Edison|Maxwell)!!',
3845
  4 => '(DNS )?(Airtab )?(E|ES|M|MA|MC|MF|MW|P|PC|PF)[0-9]{2,4}!!',
3846
- 5 => '(HUAWEI )?(ALP|BLA|CRR|EVR|HMA|LIO|LON|LYA|MATE|MHA|MT1|MT2|MT7|M200|NXT|SNE|TAS|Z100)!!',
3847
- 6 => '(HW-|HUAWEI )?MAR-(AL00|LX1A|LX1M|LX2|LX3A|TL00)!',
3848
- 7 => 'MAX FIND 5.0',
3849
- 8 => 'Malata!!',
3850
- 9 => 'Masstel!!',
3851
- 10 => 'MASTONE!!',
3852
- 11 => 'Maxtron!!',
3853
- 12 => 'magi',
3854
- 13 => 'MagicBox',
3855
- 14 => '(Xiaomi )?(MI )?MAX$!',
3856
- 15 => '(Xiaomi )?(MI )?MAX 2$!',
3857
- 16 => '(Xiaomi )?(MI )?MAX 3$!',
3858
- 17 => 'markf',
3859
- 18 => 'markw',
3860
  ),
3861
  '@MB' =>
3862
  array (
@@ -3930,7 +3816,7 @@ DeviceModels::$ANDROID_INDEX = array (
3930
  '@MH' =>
3931
  array (
3932
  0 => 'MH350',
3933
- 1 => '(HUAWEI )?(ALP|BLA|CRR|EVR|HMA|LIO|LON|LYA|MATE|MHA|MT1|MT2|MT7|M200|NXT|SNE|TAS|Z100)!!',
3934
  ),
3935
  '@MI' =>
3936
  array (
@@ -3970,25 +3856,17 @@ DeviceModels::$ANDROID_INDEX = array (
3970
  33 => '(CSL[- ])?(Spice[- ]?)?Mi(-| )?[0-9]{3,3}!!',
3971
  34 => 'miTab!!',
3972
  35 => '(Xiaomi )?(Xiaomi|Xiaomi M|MI)!!',
3973
- 36 => 'MI 8',
3974
- 37 => 'MI 8 SE',
3975
- 38 => 'MI 8 UD',
3976
- 39 => 'MI 8 Lite',
3977
- 40 => 'MI 9',
3978
- 41 => 'Mi 9T Pro',
3979
- 42 => 'Mi9 Pro 5G',
3980
- 43 => '(Xiaomi|Xiaomi Mi|MI) Note!!',
3981
- 44 => '(Xiaomi )?(MI )?MAX$!',
3982
- 45 => '(Xiaomi )?(MI )?MAX 2$!',
3983
- 46 => '(Xiaomi )?(MI )?MAX 3$!',
3984
- 47 => '(Xiaomi )?(MI )?MIX$!',
3985
- 48 => '(Xiaomi )?(MI )?MIX 2$!',
3986
- 49 => '(Xiaomi )?(MI )?MIX 2S$!',
3987
- 50 => 'mido',
3988
- 51 => '(Xiaomi|Xiaomi Mi|MI) Pad!!',
3989
- 52 => '(Xiaomi|Xiaomi Mi|MI)Box!!',
3990
- 53 => '(Xiaomi|Xiaomi Mi|MI)TV!!',
3991
- 54 => '(ZTE )?(Grand|Mimosa)!!',
3992
  ),
3993
  '@MK' =>
3994
  array (
@@ -4031,80 +3909,51 @@ DeviceModels::$ANDROID_INDEX = array (
4031
  13 => 'MOGU!!',
4032
  14 => 'moii!!',
4033
  15 => 'MORAL N01',
4034
- 16 => 'motorola one',
4035
- 17 => 'motorola one action',
4036
- 18 => 'motorola one macro',
4037
- 19 => 'motorola one power',
4038
- 20 => 'motorola one vision',
4039
- 21 => 'motorola one zoom',
4040
- 22 => 'Moto Droid',
4041
- 23 => 'Motorola Pro XT610',
4042
- 24 => 'Motorola Milestone MAXX',
4043
- 25 => 'Motorola Backflip Me600',
4044
- 26 => 'Moto ME860',
4045
- 27 => 'Moto C',
4046
- 28 => 'Moto C Plus',
4047
- 29 => '(Moto)?E2$!',
4048
- 30 => '(Moto)?E2\\(4G-LTE\\)$!',
4049
- 31 => 'Motorola MotoE2!',
4050
- 32 => 'Moto E4',
4051
- 33 => 'Moto E (4)',
4052
- 34 => 'Moto E (4) Plus',
4053
- 35 => 'moto e5 cruise',
4054
- 36 => 'moto e5 play',
4055
- 37 => '(Moto)?G3$!',
4056
- 38 => '(Moto)?G3-TE$!',
4057
- 39 => 'Moto G 2015',
4058
- 40 => 'Moto G (2015)',
4059
- 41 => 'Moto G (2014',
4060
- 42 => 'MOTOROLA MOTOG',
4061
- 43 => 'Moto G Play',
4062
- 44 => 'Moto G Turbo',
4063
- 45 => 'Moto G4',
4064
- 46 => 'Moto G (4',
4065
- 47 => 'Moto G (4)',
4066
- 48 => 'Moto G4 Plus',
4067
- 49 => 'Moto G 5',
4068
- 50 => 'Moto G (5',
4069
- 51 => 'Moto G (5)',
4070
- 52 => 'Moto G (5) Plus',
4071
- 53 => 'Moto G (5S',
4072
- 54 => 'Moto G (5S)',
4073
- 55 => 'Moto G (5S) Plus',
4074
- 56 => 'moto g(6',
4075
- 57 => 'moto g(6)',
4076
- 58 => 'moto g(6) (XT1925DL)',
4077
- 59 => 'moto g(6) forge',
4078
- 60 => 'moto g(6) play',
4079
- 61 => 'moto g(6) plus',
4080
- 62 => 'moto g(7',
4081
- 63 => 'moto g(7)',
4082
- 64 => 'moto g(7) optimo (XT1952DL)',
4083
- 65 => 'moto g(7) play',
4084
- 66 => 'moto g(7) plus',
4085
- 67 => 'moto g(7) power',
4086
- 68 => 'moto g(7) supra',
4087
- 69 => 'moto g(8',
4088
- 70 => 'Moto Z (2)',
4089
- 71 => 'Moto Z2 Play',
4090
- 72 => 'Moto X Pro',
4091
- 73 => 'moto x4',
4092
- 74 => 'Moto Backflip',
4093
- 75 => 'MOTOROLA XOOM MZ606',
4094
- 76 => 'MOTOROLA RAZR',
4095
- 77 => 'MOTWX435KT',
4096
- 78 => '(PLOYER-)?MOMO!!',
4097
- 79 => 'MOB-5045',
4098
- 80 => 'Mobii 7',
4099
- 81 => 'MoFing',
4100
- 82 => 'mocha',
4101
- 83 => 'MO-01J',
4102
- 84 => 'MO-01K',
4103
- 85 => 'Movistar Express',
4104
- 86 => 'Movistar Link',
4105
- 87 => 'Movistar Motion',
4106
- 88 => 'Movistar Prime',
4107
- 89 => 'MOVE',
4108
  ),
4109
  '@MP' =>
4110
  array (
@@ -4128,10 +3977,6 @@ DeviceModels::$ANDROID_INDEX = array (
4128
  17 => 'MPQC804HD',
4129
  18 => 'MPQC1010',
4130
  ),
4131
- '@MR' =>
4132
- array (
4133
- 0 => '(HW-|HUAWEI )?(ATU|DRA|FLA|JKM|TIT|TAG||MRD|NCE|POT|TRT|SLA)!!',
4134
- ),
4135
  '@MS' =>
4136
  array (
4137
  0 => 'MStar Amber3',
@@ -4188,7 +4033,7 @@ DeviceModels::$ANDROID_INDEX = array (
4188
  28 => 'mt8580!',
4189
  29 => 'mt8658!',
4190
  30 => '(AC|BC|LC|MT|RC|QS|VM|TS|OC)[0-9]{4,4}[A-Z]!!',
4191
- 31 => '(HUAWEI )?(ALP|BLA|CRR|EVR|HMA|LIO|LON|LYA|MATE|MHA|MT1|MT2|MT7|M200|NXT|SNE|TAS|Z100)!!',
4192
  32 => 'MTC Android',
4193
  33 => 'MT791',
4194
  34 => 'MT70[0-9]{2,2}!!',
@@ -4399,7 +4244,7 @@ DeviceModels::$ANDROID_INDEX = array (
4399
  ),
4400
  '@NC' =>
4401
  array (
4402
- 0 => '(HW-|HUAWEI )?(ATU|DRA|FLA|JKM|TIT|TAG||MRD|NCE|POT|TRT|SLA)!!',
4403
  ),
4404
  '@NE' =>
4405
  array (
@@ -4436,7 +4281,7 @@ DeviceModels::$ANDROID_INDEX = array (
4436
  30 => '(BLU|DASH|LIFE|NEO|STUDIO|VIVO)!!',
4437
  31 => 'NexusHD2',
4438
  32 => 'Nexus HD2',
4439
- 33 => '(HW-|HUAWEI |HONOR )?(ATH|BLN|BKL|BKK|BND|CHE|CHM|COL|DUA|DUK|DLI|EDI|FRD|HLK|HN3|H30|H60|HOL|JMM|JSN|LRA|KIW|LLD|NEM|NMO|OXF|PE|PCT|PLK|RNE|SCL|TNY|KNT|CAM|STF|HDN|YAL)!!',
4440
  34 => 'Neon7',
4441
  35 => 'Neon9',
4442
  36 => '(NetTab|NT-)!!',
@@ -4527,7 +4372,7 @@ DeviceModels::$ANDROID_INDEX = array (
4527
  ),
4528
  '@NM' =>
4529
  array (
4530
- 0 => '(HW-|HUAWEI |HONOR )?(ATH|BLN|BKL|BKK|BND|CHE|CHM|COL|DUA|DUK|DLI|EDI|FRD|HLK|HN3|H30|H60|HOL|JMM|JSN|LRA|KIW|LLD|NEM|NMO|OXF|PE|PCT|PLK|RNE|SCL|TNY|KNT|CAM|STF|HDN|YAL)!!',
4531
  1 => '(NMP|MBR|XDK|XDS|XMP)\\-!!',
4532
  ),
4533
  '@NO' =>
@@ -4587,42 +4432,22 @@ DeviceModels::$ANDROID_INDEX = array (
4587
  52 => 'Now',
4588
  53 => 'NO1 S6',
4589
  54 => 'NOAIN!!',
4590
- 55 => 'Nokia 1 Plus',
4591
- 56 => 'Nokia 1',
4592
- 57 => 'Nokia 2.1',
4593
- 58 => 'Nokia 2',
4594
- 59 => 'Nokia 3.1 Plus',
4595
- 60 => 'Nokia 3.1',
4596
- 61 => 'Nokia 4.2',
4597
- 62 => 'Nokia 5.1 Plus',
4598
- 63 => 'Nokia 5.1',
4599
- 64 => 'Nokia 6.1 Plus',
4600
- 65 => 'Nokia 6.1',
4601
- 66 => 'Nokia 6.2',
4602
- 67 => 'Nokia 6',
4603
- 68 => 'Nokia 7.1',
4604
- 69 => 'Nokia 7 Plus',
4605
- 70 => 'Nokia 8.1',
4606
- 71 => 'Nokia 8 Sirocco',
4607
- 72 => 'Nokia 8',
4608
- 73 => 'Nokia 9',
4609
- 74 => 'Nokia 10.1',
4610
- 75 => 'Nokia N9',
4611
- 76 => 'Nokia N900',
4612
- 77 => 'Nokia X',
4613
- 78 => 'Nokia X Dual SIM',
4614
- 79 => 'Nokia X+',
4615
- 80 => 'Nokia Xplus',
4616
- 81 => 'Nokia XL 4G',
4617
- 82 => 'Nokia XL',
4618
- 83 => 'Nokia XL Dual SIM',
4619
- 84 => 'Nokia X2',
4620
- 85 => 'NokiaX2DS',
4621
- 86 => 'Notion Ink ADAM',
4622
- 87 => 'Note III',
4623
- 88 => 'Nozomi',
4624
- 89 => 'Noble TAB07-485',
4625
- 90 => '(QMobile|QTab|Q-Smart|Noir)!!',
4626
  ),
4627
  '@NP' =>
4628
  array (
@@ -4656,7 +4481,7 @@ DeviceModels::$ANDROID_INDEX = array (
4656
  ),
4657
  '@NX' =>
4658
  array (
4659
- 0 => '(HUAWEI )?(ALP|BLA|CRR|EVR|HMA|LIO|LON|LYA|MATE|MHA|MT1|MT2|MT7|M200|NXT|SNE|TAS|Z100)!!',
4660
  1 => '(Nexian )?NX-A[0-9]{3,3}!!',
4661
  2 => 'NXA8QC116',
4662
  3 => 'NX16A8116K',
@@ -4690,12 +4515,8 @@ DeviceModels::$ANDROID_INDEX = array (
4690
  '@OB' =>
4691
  array (
4692
  0 => 'OB-OPPO A31c',
4693
- 1 => 'OB-OPPO R8205',
4694
- 2 => 'OB-OPPO R7005',
4695
- 3 => 'OB-OPPO R7c',
4696
- 4 => 'OB-OPPO 1105',
4697
- 5 => 'OB-OPPO 3005',
4698
- 6 => 'Obreey SURFpad',
4699
  ),
4700
  '@OC' =>
4701
  array (
@@ -4888,20 +4709,17 @@ DeviceModels::$ANDROID_INDEX = array (
4888
  138 => 'ONEPLUS A5000',
4889
  139 => 'ONEPLUS A5010',
4890
  140 => 'ONEPLUS A6000',
4891
- 141 => 'ONEPLUS A6003',
4892
- 142 => 'ONEPLUS A6010',
4893
- 143 => 'ONEPLUS A6013',
4894
- 144 => 'ONE E1000',
4895
- 145 => 'ONE E1001',
4896
- 146 => 'ONE E1003',
4897
- 147 => 'ONE E1005',
4898
- 148 => 'ONDA MID',
4899
- 149 => 'ONDA A9 Core4',
4900
- 150 => 'ONDA VI10',
4901
- 151 => 'Onda V812',
4902
- 152 => 'ONDA v975m',
4903
- 153 => 'ONDA V989',
4904
- 154 => 'ONDA V989 Core8',
4905
  ),
4906
  '@OP' =>
4907
  array (
@@ -4910,109 +4728,84 @@ DeviceModels::$ANDROID_INDEX = array (
4910
  2 => 'Opus One',
4911
  3 => 'OPS-DRD Digital Signage Player',
4912
  4 => 'OP110',
4913
- 5 => 'OPPO PBAM00',
4914
- 6 => 'OPPO PBFT00',
4915
- 7 => 'OPPO A30',
4916
- 8 => 'OPPO A31',
4917
- 9 => 'OPPO A31t',
4918
- 10 => 'OPPO A33',
4919
- 11 => 'OPPO A33m',
4920
- 12 => 'OPPO A37m',
4921
- 13 => 'OPPO A53',
4922
- 14 => 'OPPO A53m',
4923
- 15 => 'OPPO A53t',
4924
- 16 => 'OPPO A57',
4925
- 17 => 'OPPO A57t',
4926
- 18 => 'OPPO A59m',
4927
- 19 => 'OPPO A59s',
4928
- 20 => 'OPPO A59st',
4929
- 21 => 'OPPO A73',
4930
- 22 => 'OPPO A73t',
4931
- 23 => 'OPPO A77',
4932
- 24 => 'OPPO A77t',
4933
- 25 => 'OPPO A79',
4934
- 26 => 'OPPO A79kt',
4935
- 27 => 'OPPO A79t',
4936
- 28 => 'OPPO A83',
4937
- 29 => 'OPPO A83t',
4938
- 30 => 'OPPO A800',
4939
- 31 => 'OPPOX905',
4940
- 32 => 'OPPOX907',
4941
- 33 => 'OPPO Find5',
4942
- 34 => 'OPPOX909',
4943
- 35 => 'OPPO X909',
4944
- 36 => 'OPPO X9007',
4945
- 37 => 'OPPOX9015',
4946
- 38 => 'OPPOX9017',
4947
- 39 => 'OPPO find7',
4948
- 40 => 'OPPOR601',
4949
- 41 => 'OPPOR801',
4950
- 42 => 'OPPOR803',
4951
- 43 => 'OPPOR805',
4952
- 44 => 'OPPOR807',
4953
- 45 => 'OPPO R811',
4954
- 46 => 'OPPO R813T',
4955
- 47 => 'OPPO R815',
4956
- 48 => 'OPPOR817',
4957
- 49 => 'Oppo R819',
4958
- 50 => 'OPPO R821',
4959
- 51 => 'OPPO R831',
4960
- 52 => 'Oppo R831 Limited Edition',
4961
- 53 => 'OPPO R1001',
4962
- 54 => 'OPPOR8015',
4963
- 55 => 'OPPOR8111',
4964
- 56 => 'OPPOT29',
4965
- 57 => '(OPPO-?)?T703!',
4966
- 58 => 'OPPOU701',
4967
- 59 => 'OPPOU7011',
4968
- 60 => 'OPPOU7015',
4969
- 61 => 'OPPO PBCM30',
4970
- 62 => 'OPPO PBCT10',
4971
- 63 => 'OPPO N1',
4972
- 64 => 'OPPO R7',
4973
- 65 => 'OPPO R7Plus',
4974
- 66 => 'OPPO R7s',
4975
- 67 => 'OPPO R7sm',
4976
- 68 => 'OPPO R7st',
4977
- 69 => 'OPPO R7t',
4978
- 70 => 'OPPO R9k',
4979
- 71 => 'OPPO R9m',
4980
- 72 => 'OPPO R9tm',
4981
- 73 => 'OPPO R9km',
4982
- 74 => 'OPPO R9s',
4983
- 75 => 'OPPO R9sk',
4984
- 76 => 'OPPO R9st',
4985
- 77 => 'OPPO R9skt',
4986
- 78 => 'OPPO R9t',
4987
- 79 => 'OPPO R11',
4988
- 80 => 'OPPO R11t',
4989
- 81 => 'OPPO R7 Plus',
4990
- 82 => 'OPPO R7sPlus',
4991
- 83 => 'OPPO R9 Plusm A',
4992
- 84 => 'OPPO R9 Plustm A',
4993
- 85 => 'OPPO R9s Plus',
4994
- 86 => 'OPPO R9s Plust',
4995
- 87 => 'OPPO R11 Plus',
4996
- 88 => 'OPPO R11 Plusk',
4997
- 89 => 'OPPO R11 Pluskt',
4998
- 90 => 'OPPO R11s',
4999
- 91 => 'OPPO R11s Plus',
5000
- 92 => 'OPPO R11st',
5001
- 93 => 'OPPO R11s Plust',
5002
- 94 => 'OPPO PAAM00',
5003
- 95 => 'OPPO PACM00',
5004
- 96 => 'OPPO PACT00',
5005
- 97 => 'OPPO PBDM00',
5006
- 98 => 'OPPO PAFM00',
5007
- 99 => 'OPSSON!!',
5008
- 100 => 'OP0118-12',
5009
- 101 => 'Optimus Barcelona',
5010
- 102 => 'Optimus Boston',
5011
- 103 => 'Optimus Madrid',
5012
- 104 => 'Optimus Monte Carlo',
5013
- 105 => 'Optimus San Francisco',
5014
- 106 => 'Optimus San Remo',
5015
- 107 => 'Optimus Zali',
5016
  ),
5017
  '@OR' =>
5018
  array (
@@ -5064,10 +4857,6 @@ DeviceModels::$ANDROID_INDEX = array (
5064
  array (
5065
  0 => '(OV-|Overmax|Vertis)!!',
5066
  ),
5067
- '@OX' =>
5068
- array (
5069
- 0 => '(HW-|HUAWEI |HONOR )?(ATH|BLN|BKL|BKK|BND|CHE|CHM|COL|DUA|DUK|DLI|EDI|FRD|HLK|HN3|H30|H60|HOL|JMM|JSN|LRA|KIW|LLD|NEM|NMO|OXF|PE|PCT|PLK|RNE|SCL|TNY|KNT|CAM|STF|HDN|YAL)!!',
5070
- ),
5071
  '@OY' =>
5072
  array (
5073
  0 => 'Oysters Pacific 800',
@@ -5131,7 +4920,7 @@ DeviceModels::$ANDROID_INDEX = array (
5131
  array (
5132
  0 => 'P2A700',
5133
  1 => 'P2Lite',
5134
- 2 => '(HW-|HUAWEI )?(ALE|ANE|CLT|D2|DAV|ELE|EML|EVA|FIG|G6|G7|GRA|M100|P2|P6|P7|PRA|RIO|SC|Sophia|STK|VIE|VKY|VNS|VOG|VTR|WAS)!!',
5135
  ),
5136
  '@P3' =>
5137
  array (
@@ -5160,11 +4949,11 @@ DeviceModels::$ANDROID_INDEX = array (
5160
  2 => 'P6 Pro',
5161
  3 => 'P6 Qmax',
5162
  4 => 'P6 Quad',
5163
- 5 => '(HW-|HUAWEI )?(ALE|ANE|CLT|D2|DAV|ELE|EML|EVA|FIG|G6|G7|GRA|M100|P2|P6|P7|PRA|RIO|SC|Sophia|STK|VIE|VKY|VNS|VOG|VTR|WAS)!!',
5164
  ),
5165
  '@P7' =>
5166
  array (
5167
- 0 => '(HW-|HUAWEI )?(ALE|ANE|CLT|D2|DAV|ELE|EML|EVA|FIG|G6|G7|GRA|M100|P2|P6|P7|PRA|RIO|SC|Sophia|STK|VIE|VKY|VNS|VOG|VTR|WAS)!!',
5168
  1 => 'P700i',
5169
  2 => 'P701',
5170
  3 => 'P7',
@@ -5268,38 +5057,21 @@ DeviceModels::$ANDROID_INDEX = array (
5268
  15 => 'Patio100',
5269
  16 => 'Patio100 3G',
5270
  17 => 'PAD[0-9]{3,3}!!',
5271
- 18 => '(HW-|HUAWEI )?PAR-(AL00|LX1|LX1M|LX9|TL00)!',
5272
- 19 => 'PADM00',
5273
- 20 => 'PADT00',
5274
- 21 => 'PAAM00',
5275
- 22 => 'PACM00',
5276
- 23 => 'PACT00',
5277
- 24 => 'PAAT00',
5278
- 25 => 'PAFM00',
5279
- 26 => 'PAHM00',
5280
- 27 => 'Panasonic!!',
5281
- 28 => 'pandigital9hr',
5282
- 29 => 'pandigital9hr2',
5283
- 30 => 'pandigitalopc1',
5284
- 31 => 'pandigitalopp1',
5285
- 32 => 'pandigitalp1hr',
5286
- 33 => 'PantechP!!',
5287
- 34 => 'PAT712W',
5288
- 35 => 'PATG7506HD',
5289
- 36 => 'PAP[0-9]{4,4}!!',
5290
- 37 => 'PAD1001',
5291
  ),
5292
  '@PB' =>
5293
  array (
5294
  0 => 'PB99400',
5295
- 1 => 'PBAM00',
5296
- 2 => 'PBAT00',
5297
- 3 => 'PBFT00',
5298
- 4 => 'PBBM00',
5299
- 5 => 'PBCM30',
5300
- 6 => 'PBEM00',
5301
- 7 => 'PBET00',
5302
- 8 => 'PBDM00',
5303
  ),
5304
  '@PC' =>
5305
  array (
@@ -5307,16 +5079,11 @@ DeviceModels::$ANDROID_INDEX = array (
5307
  1 => '(DNS )?(Airtab )?(E|ES|M|MA|MC|MF|MW|P|PC|PF)[0-9]{2,4}!!',
5308
  2 => '(HTC|PCD|USCC)?ADR[0-9]{4,4}!!',
5309
  3 => 'PC36100!',
5310
- 4 => '(HW-|HUAWEI |HONOR )?(ATH|BLN|BKL|BKK|BND|CHE|CHM|COL|DUA|DUK|DLI|EDI|FRD|HLK|HN3|H30|H60|HOL|JMM|JSN|LRA|KIW|LLD|NEM|NMO|OXF|PE|PCT|PLK|RNE|SCL|TNY|KNT|CAM|STF|HDN|YAL)!!',
5311
- 5 => 'PC-TE307N1W',
5312
- 6 => 'PC-TE508BAW',
5313
- 7 => 'PC-TS508FAM',
5314
- 8 => 'PC-TS508T1W',
5315
- 9 => 'PC-TS708T1W',
5316
- 10 => 'PCGM00',
5317
- 11 => 'PCAM00',
5318
- 12 => 'PCAM10',
5319
- 13 => 'PCCM00',
5320
  ),
5321
  '@PD' =>
5322
  array (
@@ -5325,7 +5092,7 @@ DeviceModels::$ANDROID_INDEX = array (
5325
  ),
5326
  '@PE' =>
5327
  array (
5328
- 0 => '(HW-|HUAWEI |HONOR )?(ATH|BLN|BKL|BKK|BND|CHE|CHM|COL|DUA|DUK|DLI|EDI|FRD|HLK|HN3|H30|H60|HOL|JMM|JSN|LRA|KIW|LLD|NEM|NMO|OXF|PE|PCT|PLK|RNE|SCL|TNY|KNT|CAM|STF|HDN|YAL)!!',
5329
  1 => 'PEDI',
5330
  2 => 'Penta!!',
5331
  3 => 'Pentagram!!',
@@ -5418,40 +5185,34 @@ DeviceModels::$ANDROID_INDEX = array (
5418
  3 => 'Pixel 2',
5419
  4 => 'Pixel 2XL',
5420
  5 => 'Pixel 2 XL',
5421
- 6 => 'Pixel 3',
5422
- 7 => 'Pixel 3 XL',
5423
- 8 => 'Pixel 3a',
5424
- 9 => 'Pixel 3a XL',
5425
- 10 => 'Pixel 4',
5426
- 11 => 'Pixel 4 XL',
5427
- 12 => '(Axioo[\\- ])?PICO!!',
5428
- 13 => 'picoBit-L',
5429
- 14 => '(GIO-)?(GiONEE[- ])?Pioneer P1!',
5430
- 15 => '(GIO-)?(GiONEE[- ])?Pioneer P2!',
5431
- 16 => '(GIO-)?(GiONEE[- ])?Pioneer P3!',
5432
- 17 => '(GIO-)?(GiONEE[- ])?Pioneer P4!',
5433
- 18 => 'PixelV1',
5434
- 19 => 'Pixel V2',
5435
- 20 => 'Pixel V2+',
5436
- 21 => 'PI2000',
5437
- 22 => 'PI2010',
5438
- 23 => 'PI2011',
5439
- 24 => 'PI3100',
5440
- 25 => 'PI3100-93',
5441
- 26 => 'PI3100Z3 93',
5442
- 27 => 'PI3105',
5443
- 28 => 'PI3106',
5444
- 29 => 'PI3110',
5445
- 30 => 'PI3205G',
5446
- 31 => 'PI3210G',
5447
- 32 => 'PI3900',
5448
- 33 => 'PI3900-93',
5449
- 34 => 'PI3910',
5450
- 35 => 'PI4010G',
5451
- 36 => 'PI7000',
5452
- 37 => 'PI7100 93',
5453
- 38 => '(PNR-)?Pioneer!!',
5454
- 39 => 'PIRANHA!!',
5455
  ),
5456
  '@PJ' =>
5457
  array (
@@ -5462,7 +5223,7 @@ DeviceModels::$ANDROID_INDEX = array (
5462
  array (
5463
  0 => 'PLE-701L',
5464
  1 => 'PLE-703L',
5465
- 2 => '(HW-|HUAWEI |HONOR )?(ATH|BLN|BKL|BKK|BND|CHE|CHM|COL|DUA|DUK|DLI|EDI|FRD|HLK|HN3|H30|H60|HOL|JMM|JSN|LRA|KIW|LLD|NEM|NMO|OXF|PE|PCT|PLK|RNE|SCL|TNY|KNT|CAM|STF|HDN|YAL)!!',
5466
  3 => 'Planet II v2',
5467
  4 => 'PLANET',
5468
  5 => 'Playboy PB-S3',
@@ -5495,90 +5256,88 @@ DeviceModels::$ANDROID_INDEX = array (
5495
  '@PO' =>
5496
  array (
5497
  0 => '(Highscreen|Alpha|Bay|Boost|Cosmo|Explosion|Power|Prime|Zera)!!',
5498
- 1 => '(HW-|HUAWEI )?(ATU|DRA|FLA|JKM|TIT|TAG||MRD|NCE|POT|TRT|SLA)!!',
5499
- 2 => 'PocketBook A7',
5500
- 3 => 'PocketBook A10',
5501
- 4 => 'PocketBook A10 3G',
5502
- 5 => 'PocketBook SURFpad2',
5503
- 6 => 'PocketBook SURFpad 3 (7,85")',
5504
- 7 => 'PocketBook SURFpad 4 S',
5505
- 8 => 'PocketBook SURFpad 4 M',
5506
- 9 => 'PocketBook SURFpad 4 L',
5507
- 10 => 'POV-Mobii-7',
5508
- 11 => 'POV Mobii 7',
5509
- 12 => 'POV TAB-P506!',
5510
- 13 => 'POV TAB-P517!',
5511
- 14 => 'POV TAB-P527!',
5512
- 15 => 'POV TAB-P629!',
5513
- 16 => 'POV TAB-P701!',
5514
- 17 => 'POV TAB-P703!',
5515
- 18 => 'POV TAB-P720!',
5516
- 19 => 'POV TAB-P721A!',
5517
- 20 => 'POV TAB-P721!',
5518
- 21 => 'POV TAB-P722C!',
5519
- 22 => 'POV TAB-P731N!',
5520
- 23 => 'POV TAB-P825!',
5521
- 24 => 'POV TAB-P925!',
5522
- 25 => 'POV TAB-PR945!',
5523
- 26 => 'POV TAB-P1025!',
5524
- 27 => 'POV TAB-P1030!',
5525
- 28 => 'POV TAB-PI1045!',
5526
- 29 => 'POV TAB-P1325!',
5527
- 30 => '(POV )?TAB-PLAYTABPRO!',
5528
- 31 => '(POV )?TAB-PROTAB25!',
5529
- 32 => '(POV )?TAB-PROTAB26!',
5530
- 33 => 'POV TAB-PROTAB27',
5531
- 34 => '(POV )?TAB-PROTAB30!',
5532
- 35 => '(POV )?TAB-PROTAB2XXL(4)!',
5533
- 36 => '(POV )?TAB NAVI7 3G M!',
5534
- 37 => 'POV_TAB-NAVI7-3G-M',
5535
- 38 => 'POV TAB-P547(v1.0)',
5536
- 39 => 'POV TV-HDMI-200BT',
5537
- 40 => 'POV TV-HDMI-200BT(V2.0)',
5538
- 41 => 'POV TV-HDMI-210',
5539
- 42 => 'POV TV-HDMI-KB-01',
5540
- 43 => 'POV TV-SMARTTV-500',
5541
- 44 => 'Polaroid PSPT401',
5542
- 45 => 'Polaroid PSPC505',
5543
- 46 => 'Polaroid PSPC550',
5544
- 47 => 'Polaroid P4005A',
5545
- 48 => 'Polaroid P5005A',
5546
- 49 => 'Polaroid P5046A',
5547
- 50 => 'Polaroid P5525A',
5548
- 51 => 'Polaroid P5526A',
5549
- 52 => 'POLY ?PAD!!',
5550
- 53 => 'POLYTRON!!',
5551
- 54 => 'POMP!!',
5552
- 55 => 'Positivo Mini',
5553
- 56 => 'POSITIVO YPY 07FTB',
5554
- 57 => 'Positivo Ypy AB7E',
5555
- 58 => 'Positivo Ypy AB7EC',
5556
- 59 => 'Positivo Ypy AB7F',
5557
- 60 => 'Positivo AB7F',
5558
- 61 => 'Positivo Ypy AB7H',
5559
- 62 => 'Positivo Ypy AB10E',
5560
- 63 => 'Positivo Ypy AB10EC',
5561
- 64 => 'Positivo Ypy AB10H',
5562
- 65 => 'Positivo BGH Ypy L700',
5563
- 66 => 'Positivo Ypy L700',
5564
- 67 => 'Positivo Ypy L700 Ed. Especial',
5565
- 68 => 'Positivo Ypy L700+',
5566
- 69 => 'Positivo Ypy L700 Kids',
5567
- 70 => 'Positivo BGH Ypy L700 Kids',
5568
- 71 => 'Positivo Ypy L700+ Kids',
5569
- 72 => 'Positivo Ypy L1000',
5570
- 73 => 'Positivo Ypy L1000AB',
5571
- 74 => 'Positivo Ypy L1000F',
5572
- 75 => 'Positivo Ypy L1050',
5573
- 76 => 'Positivo Ypy L1050E',
5574
- 77 => 'Positivo Ypy L1050F',
5575
- 78 => 'Positivo S380',
5576
- 79 => 'Positivo S440',
5577
- 80 => 'Positivo S480',
5578
- 81 => 'Positivo S550',
5579
- 82 => 'Positivo X400',
5580
- 83 => 'Positivo X800',
5581
- 84 => 'POCOPHONE F1',
5582
  ),
5583
  '@PP' =>
5584
  array (
@@ -5589,7 +5348,7 @@ DeviceModels::$ANDROID_INDEX = array (
5589
  array (
5590
  0 => 'Project Tango Tablet Development Kit',
5591
  1 => '(Highscreen|Alpha|Bay|Boost|Cosmo|Explosion|Power|Prime|Zera)!!',
5592
- 2 => '(HW-|HUAWEI )?(ALE|ANE|CLT|D2|DAV|ELE|EML|EVA|FIG|G6|G7|GRA|M100|P2|P6|P7|PRA|RIO|SC|Sophia|STK|VIE|VKY|VNS|VOG|VTR|WAS)!!',
5593
  3 => 'Pro 10 dual core',
5594
  4 => 'Prada 3.0',
5595
  5 => 'PRO 5',
@@ -5878,10 +5637,9 @@ DeviceModels::$ANDROID_INDEX = array (
5878
  3 => 'R7i',
5879
  4 => 'R7kf',
5880
  5 => 'R7sf',
5881
- 6 => 'R7t',
5882
- 7 => 'R7Plus',
5883
- 8 => 'R7plusf',
5884
- 9 => 'R7Plusm',
5885
  ),
5886
  '@R8' =>
5887
  array (
@@ -6028,7 +5786,7 @@ DeviceModels::$ANDROID_INDEX = array (
6028
  2 => 'Rikomagic MK802III',
6029
  3 => 'Rikomagic MK802IIIS',
6030
  4 => '(Gsmart|Gigabyte|Rio)!!',
6031
- 5 => '(HW-|HUAWEI )?(ALE|ANE|CLT|D2|DAV|ELE|EML|EVA|FIG|G6|G7|GRA|M100|P2|P6|P7|PRA|RIO|SC|Sophia|STK|VIE|VKY|VNS|VOG|VTR|WAS)!!',
6032
  6 => 'Rise',
6033
  7 => '(Ritmix )?RM[DP]-?[0-9]{3,3}!!',
6034
  8 => 'RIDGE',
@@ -6078,7 +5836,7 @@ DeviceModels::$ANDROID_INDEX = array (
6078
  ),
6079
  '@RN' =>
6080
  array (
6081
- 0 => '(HW-|HUAWEI |HONOR )?(ATH|BLN|BKL|BKK|BND|CHE|CHM|COL|DUA|DUK|DLI|EDI|FRD|HLK|HN3|H30|H60|HOL|JMM|JSN|LRA|KIW|LLD|NEM|NMO|OXF|PE|PCT|PLK|RNE|SCL|TNY|KNT|CAM|STF|HDN|YAL)!!',
6082
  ),
6083
  '@RO' =>
6084
  array (
@@ -6201,24 +5959,23 @@ DeviceModels::$ANDROID_INDEX = array (
6201
  ),
6202
  '@SC' =>
6203
  array (
6204
- 0 => 'SCM-(AL09|W09)!',
6205
- 1 => '(HW-|HUAWEI |HONOR )?(ATH|BLN|BKL|BKK|BND|CHE|CHM|COL|DUA|DUK|DLI|EDI|FRD|HLK|HN3|H30|H60|HOL|JMM|JSN|LRA|KIW|LLD|NEM|NMO|OXF|PE|PCT|PLK|RNE|SCL|TNY|KNT|CAM|STF|HDN|YAL)!!',
6206
- 2 => '(HW-|HUAWEI )?(ALE|ANE|CLT|D2|DAV|ELE|EML|EVA|FIG|G6|G7|GRA|M100|P2|P6|P7|PRA|RIO|SC|Sophia|STK|VIE|VKY|VNS|VOG|VTR|WAS)!!',
6207
- 3 => '(HW-|HUAWEI )?(CRO|LUA|CUN|SCC|SCU|CAM|LDN|LYO|MYA)!!',
6208
- 4 => 'SCH-[iI][0-9]{3,3}!!',
6209
- 5 => 'SCH-L710!',
6210
- 6 => 'SCH-M828!',
6211
- 7 => 'SCH-N719',
6212
- 8 => 'SCH-P[0-9]{3,3}!!',
6213
- 9 => 'SCH-R[0-9]{3,3}!!',
6214
- 10 => 'SCH-S[0-9]{3,3}!!',
6215
- 11 => 'SCH-V727',
6216
- 12 => 'SCH-W[0-9]{3,4}!!',
6217
- 13 => 'SC-?0[0-9][A-Z]!!',
6218
- 14 => 'SC[LTV][23][0-9]!!',
6219
- 15 => 'Scroll!!',
6220
- 16 => 'SC-!!',
6221
- 17 => 'scorpio',
6222
  ),
6223
  '@SD' =>
6224
  array (
@@ -6306,7 +6063,7 @@ DeviceModels::$ANDROID_INDEX = array (
6306
  0 => 'Slider SL101',
6307
  1 => 'SL930',
6308
  2 => '(HP|Slate)!!',
6309
- 3 => '(HW-|HUAWEI )?(ATU|DRA|FLA|JKM|TIT|TAG||MRD|NCE|POT|TRT|SLA)!!',
6310
  4 => 'Slidepad!!',
6311
  5 => 'SLIDE',
6312
  ),
@@ -6336,36 +6093,33 @@ DeviceModels::$ANDROID_INDEX = array (
6336
  21 => 'SM-A[0-9]{3,3}!!',
6337
  22 => 'SM-C[0-9]{3,3}!!',
6338
  23 => 'SM-E[0-9]{3,3}!!',
6339
- 24 => 'SM-F[0-9]{3,3}!!',
6340
- 25 => 'SM-G[0-9]{3,3}!!',
6341
- 26 => 'SM-I9500',
6342
- 27 => 'SM-J[0-9]{3,3}!!',
6343
- 28 => 'SM-M[0-9]{3,4}!!',
6344
- 29 => 'SM-N[0-9]{3,4}!!',
6345
- 30 => 'SM-P[0-9]{3,3}!!',
6346
- 31 => 'SM-S[0-9]{3,3}!!',
6347
- 32 => 'SM-T[0-9]{3,3}!!',
6348
- 33 => 'SM-V700',
6349
- 34 => 'SM-W[0-9]{4,4}!!',
6350
- 35 => 'Smartphone Android by SFR STARADDICT II',
6351
- 36 => '(Smartfren|Andromax)!!',
6352
- 37 => 'Smartfren Tab 7',
6353
- 38 => 'SM919',
6354
- 39 => 'SM701',
6355
- 40 => 'SM801',
6356
- 41 => 'SmartQ!!',
6357
- 42 => 'SMART Sprint',
6358
- 43 => 'SMART Start',
6359
- 44 => 'SMART Surf2 4G',
6360
- 45 => 'SmartTab!!',
6361
  ),
6362
  '@SN' =>
6363
  array (
6364
  0 => 'SN[0-9]!!',
6365
- 1 => '(HUAWEI )?(ALP|BLA|CRR|EVR|HMA|LIO|LON|LYA|MATE|MHA|MT1|MT2|MT7|M200|NXT|SNE|TAS|Z100)!!',
6366
- 2 => 'Snexian!!',
6367
- 3 => '(SNM\\-)?LT[0-9]{2,2}[a-z]?!!',
6368
- 4 => '(SNM\\-)?M[0-9]{2,2}[a-z]!!',
6369
  ),
6370
  '@SO' =>
6371
  array (
@@ -6379,7 +6133,7 @@ DeviceModels::$ANDROID_INDEX = array (
6379
  7 => 'Softwinerf900',
6380
  8 => 'SoftwinerEvbV13',
6381
  9 => 'soho',
6382
- 10 => '(HW-|HUAWEI )?(ALE|ANE|CLT|D2|DAV|ELE|EML|EVA|FIG|G6|G7|GRA|M100|P2|P6|P7|PRA|RIO|SC|Sophia|STK|VIE|VKY|VNS|VOG|VTR|WAS)!!',
6383
  11 => 'SONIC',
6384
  12 => 'Sonim!!',
6385
  13 => 'SO-0[0-9][A-Z]!!',
@@ -6445,64 +6199,63 @@ DeviceModels::$ANDROID_INDEX = array (
6445
  12 => 'ST7001',
6446
  13 => 'ST8000',
6447
  14 => 'ST9001',
6448
- 15 => '(HW-|HUAWEI |HONOR )?(ATH|BLN|BKL|BKK|BND|CHE|CHM|COL|DUA|DUK|DLI|EDI|FRD|HLK|HN3|H30|H60|HOL|JMM|JSN|LRA|KIW|LLD|NEM|NMO|OXF|PE|PCT|PLK|RNE|SCL|TNY|KNT|CAM|STF|HDN|YAL)!!',
6449
- 16 => '(HW-|HUAWEI )?(ALE|ANE|CLT|D2|DAV|ELE|EML|EVA|FIG|G6|G7|GRA|M100|P2|P6|P7|PRA|RIO|SC|Sophia|STK|VIE|VKY|VNS|VOG|VTR|WAS)!!',
6450
- 17 => 'ST10',
6451
- 18 => 'ST940I-UP',
6452
- 19 => 'STM[0-9]{3,3}H!!',
6453
- 20 => 'Stylo',
6454
- 21 => 'STARACTIVE',
6455
- 22 => 'STARACTIVE 2',
6456
- 23 => 'STARADDICT II',
6457
- 24 => 'STARADDICT II Plus',
6458
- 25 => 'STARADDICT III',
6459
- 26 => 'STARADDICT 4',
6460
- 27 => 'STARADDICT 5',
6461
- 28 => 'STARADDICT 6',
6462
- 29 => 'STARNAUTE II',
6463
- 30 => 'STARNAUTE 3',
6464
- 31 => 'STARNAUTE3',
6465
- 32 => 'STARNAUTE4',
6466
- 33 => 'Starshine',
6467
- 34 => 'STARSHINE II',
6468
- 35 => 'STARSHINE III',
6469
- 36 => 'STARSHINE 4',
6470
- 37 => 'STARSHINE5',
6471
- 38 => 'STARTEXT II',
6472
- 39 => 'STARTRAIL II',
6473
- 40 => 'StarTrail III',
6474
- 41 => 'STARTRAIL4',
6475
- 42 => 'STARTRAIL 4',
6476
- 43 => 'STARTRAIL5',
6477
- 44 => 'STARTRAIL 6 4G',
6478
- 45 => 'STARTRAIL6',
6479
- 46 => 'STARTRAIL7',
6480
- 47 => 'STARTRAIL 8',
6481
- 48 => 'STARTRAIL 9',
6482
- 49 => 'STARXTREM',
6483
- 50 => 'STARXTREM II',
6484
- 51 => 'STARXTREM3',
6485
- 52 => 'STARXTREM 4',
6486
- 53 => 'STARXTREM5',
6487
- 54 => 'STARXTREM 6',
6488
- 55 => 'STARTAB',
6489
- 56 => 'ST[0-9]{2,2}[a-z]?!!',
6490
- 57 => 'Star N8000',
6491
- 58 => 'Star N9500',
6492
- 59 => 'Star N9589',
6493
- 60 => 'Star Q9000',
6494
- 61 => 'STAR S5',
6495
- 62 => 'STAR S7589',
6496
- 63 => 'Starmobile!!',
6497
- 64 => '(Starway )?Andromeda!!',
6498
- 65 => 'STX!!',
6499
- 66 => 'STOREX LinkBox',
6500
- 67 => 'StarTab 715x',
6501
- 68 => 'ST[0-9]{5,5}-[0-9]!!',
6502
- 69 => 'ST-PAD',
6503
- 70 => 'ST-PAD2',
6504
- 71 => 'STAIRWAY',
6505
- 72 => 'StarTrail TT',
6506
  ),
6507
  '@SU' =>
6508
  array (
@@ -6648,81 +6401,80 @@ DeviceModels::$ANDROID_INDEX = array (
6648
  5 => 'Tablet-P27',
6649
  6 => 'TA10CA3',
6650
  7 => '(tablet )?fnac!!',
6651
- 8 => '(HUAWEI )?(ALP|BLA|CRR|EVR|HMA|LIO|LON|LYA|MATE|MHA|MT1|MT2|MT7|M200|NXT|SNE|TAS|Z100)!!',
6652
- 9 => '(HW-|HUAWEI )?(ATU|DRA|FLA|JKM|TIT|TAG||MRD|NCE|POT|TRT|SLA)!!',
6653
- 10 => '(HW-|HUAWEI )?(BLL|CHC|TAG|KII)!!',
6654
- 11 => 'TA-FONE!!',
6655
- 12 => 'TAB1011',
6656
- 13 => 'TAB-1030',
6657
- 14 => '(Lenovo )?(Tab ?)?(2 ?)?[AS](7|8|10)!!',
6658
- 15 => 'TAB950',
6659
- 16 => 'TAB1062',
6660
- 17 => 'TAB192',
6661
- 18 => 'TA-10(07|29)!',
6662
- 19 => 'TA-10(84)!',
6663
- 20 => 'TA-10(20|28|32|38)!',
6664
- 21 => 'TA-10(24|27|44|53)!',
6665
- 22 => 'TA-10(61|75|81|88)!',
6666
- 23 => 'TA-10(00|03|21|25|33|39)!',
6667
- 24 => 'TA-10(43|50|54|68)!',
6668
- 25 => 'TA-10(41)!',
6669
- 26 => 'TA-10(62)!',
6670
- 27 => 'TA-10(04|12|52)!',
6671
- 28 => 'TA-10(99)!',
6672
- 29 => 'TA-11(03|16)!',
6673
- 30 => '(POV )?TAB-PLAYTABPRO!',
6674
- 31 => '(POV )?TAB-PROTAB25!',
6675
- 32 => '(POV )?TAB-PROTAB26!',
6676
- 33 => '(POV )?TAB-PROTAB30!',
6677
- 34 => 'TAB-PROTAB2-IPS9',
6678
- 35 => 'TAB-PROTAB2-IPS-3G',
6679
- 36 => 'TAB-PROTAB2-IPS-16',
6680
- 37 => 'TAB-PROTAB2.4',
6681
- 38 => 'TAB-PROTAB2XL',
6682
- 39 => 'TAB-PROTAB2.4XL',
6683
- 40 => 'TAB-PROTAB2XXL',
6684
- 41 => 'TAB-PROTAB2XXL(4)',
6685
- 42 => '(POV )?TAB-PROTAB2XXL(4)!',
6686
- 43 => '(POV )?TAB NAVI7 3G M!',
6687
- 44 => 'Tablet P',
6688
- 45 => 'Tablet S',
6689
- 46 => 'Tabra QAV801',
6690
- 47 => 'TAB 7 3G V8',
6691
- 48 => 'TAB 8 3G V8',
6692
- 49 => 'TAB9 3G',
6693
- 50 => 'TAB9 3G V8',
6694
- 51 => 'TAB 10 3G V16',
6695
- 52 => 'TAB 7i 3G',
6696
- 53 => 'TAB 10Q',
6697
- 54 => 'TAB09-410',
6698
- 55 => 'TAB10-410',
6699
- 56 => 'TAB07-485',
6700
- 57 => 'TAB07-200',
6701
- 58 => 'TAB9-200',
6702
- 59 => 'TAB10-201',
6703
- 60 => 'TAB210',
6704
- 61 => 'TAB220',
6705
- 62 => 'TAB224',
6706
- 63 => 'TAB250',
6707
- 64 => 'TAB275',
6708
- 65 => 'TAB260',
6709
- 66 => 'TAB264',
6710
- 67 => 'TAB360',
6711
- 68 => 'TAB364',
6712
- 69 => 'TAB410',
6713
- 70 => 'TAB411',
6714
- 71 => 'TAB420',
6715
- 72 => 'TAB424',
6716
- 73 => 'TAB450',
6717
- 74 => 'TAB460',
6718
- 75 => 'TAB461',
6719
- 76 => 'TAB464',
6720
- 77 => 'TAB465EUK',
6721
- 78 => 'TAB468',
6722
- 79 => 'TAB469',
6723
- 80 => 'TAB466EUK',
6724
- 81 => 'TAB467',
6725
- 82 => 'TAB462',
6726
  ),
6727
  '@TB' =>
6728
  array (
@@ -6830,7 +6582,7 @@ DeviceModels::$ANDROID_INDEX = array (
6830
  array (
6831
  0 => 'Tilapia',
6832
  1 => 'Titan TV S320',
6833
- 2 => '(HW-|HUAWEI )?(ATU|DRA|FLA|JKM|TIT|TAG||MRD|NCE|POT|TRT|SLA)!!',
6834
  3 => '(Karbonn|Titanium)!!',
6835
  4 => 'TI320-DU',
6836
  5 => 'TI320-DU TV',
@@ -6895,10 +6647,6 @@ DeviceModels::$ANDROID_INDEX = array (
6895
  49 => 'TM-1058',
6896
  50 => 'tmn!!',
6897
  ),
6898
- '@TN' =>
6899
- array (
6900
- 0 => '(HW-|HUAWEI |HONOR )?(ATH|BLN|BKL|BKK|BND|CHE|CHM|COL|DUA|DUK|DLI|EDI|FRD|HLK|HN3|H30|H60|HOL|JMM|JSN|LRA|KIW|LLD|NEM|NMO|OXF|PE|PCT|PLK|RNE|SCL|TNY|KNT|CAM|STF|HDN|YAL)!!',
6901
- ),
6902
  '@TO' =>
6903
  array (
6904
  0 => 'Toro',
@@ -6952,7 +6700,7 @@ DeviceModels::$ANDROID_INDEX = array (
6952
  14 => 'TR720F',
6953
  15 => 'TR10CS1',
6954
  16 => 'TripNiCE Pyramid',
6955
- 17 => '(HW-|HUAWEI )?(ATU|DRA|FLA|JKM|TIT|TAG||MRD|NCE|POT|TRT|SLA)!!',
6956
  18 => 'TR10RS1',
6957
  19 => '(KAZAM|Thunder|Tornado|Trooper)!!',
6958
  20 => 'Triumph',
@@ -7302,7 +7050,7 @@ DeviceModels::$ANDROID_INDEX = array (
7302
  20 => 'Vibo-A688',
7303
  21 => 'VitMod ExtraLite 1.6.5.fullodex for HTC HD7 Pro',
7304
  22 => 'Vivid 4G',
7305
- 23 => '(HW-|HUAWEI )?(ALE|ANE|CLT|D2|DAV|ELE|EML|EVA|FIG|G6|G7|GRA|M100|P2|P6|P7|PRA|RIO|SC|Sophia|STK|VIE|VKY|VNS|VOG|VTR|WAS)!!',
7306
  24 => 'Vibe K5 Plus',
7307
  25 => 'VIBE X2 (X2)',
7308
  26 => 'VIBE X3',
@@ -7354,7 +7102,7 @@ DeviceModels::$ANDROID_INDEX = array (
7354
  ),
7355
  '@VK' =>
7356
  array (
7357
- 0 => '(HW-|HUAWEI )?(ALE|ANE|CLT|D2|DAV|ELE|EML|EVA|FIG|G6|G7|GRA|M100|P2|P6|P7|PRA|RIO|SC|Sophia|STK|VIE|VKY|VNS|VOG|VTR|WAS)!!',
7358
  1 => 'VK410',
7359
  2 => 'VK700',
7360
  3 => 'VK810 4G',
@@ -7372,7 +7120,7 @@ DeviceModels::$ANDROID_INDEX = array (
7372
  ),
7373
  '@VN' =>
7374
  array (
7375
- 0 => '(HW-|HUAWEI )?(ALE|ANE|CLT|D2|DAV|ELE|EML|EVA|FIG|G6|G7|GRA|M100|P2|P6|P7|PRA|RIO|SC|Sophia|STK|VIE|VKY|VNS|VOG|VTR|WAS)!!',
7376
  ),
7377
  '@VO' =>
7378
  array (
@@ -7381,25 +7129,24 @@ DeviceModels::$ANDROID_INDEX = array (
7381
  2 => 'Volantisg',
7382
  3 => 'VOYAGER DG300',
7383
  4 => 'VOYAGER2 DG310',
7384
- 5 => '(HW-|HUAWEI )?(ALE|ANE|CLT|D2|DAV|ELE|EML|EVA|FIG|G6|G7|GRA|M100|P2|P6|P7|PRA|RIO|SC|Sophia|STK|VIE|VKY|VNS|VOG|VTR|WAS)!!',
7385
- 6 => 'Vox',
7386
- 7 => 'Vortex',
7387
- 8 => 'vollo Vi86',
7388
- 9 => 'VOTO GT2++',
7389
- 10 => 'VOTO GT7',
7390
- 11 => 'VOTO GT11',
7391
- 12 => 'VOTO GT11 Pro',
7392
- 13 => 'VOTO GT18',
7393
- 14 => 'VOTO V5',
7394
- 15 => 'VOTO VT868',
7395
- 16 => 'VOTO VT888',
7396
- 17 => 'VOTO VT898',
7397
- 18 => 'VOTO VT898S',
7398
- 19 => 'VOTO W5300',
7399
- 20 => 'VOTO X2',
7400
- 21 => 'VOYO A15',
7401
- 22 => 'voyo X6',
7402
- 23 => 'Vodafone!!',
7403
  ),
7404
  '@VS' =>
7405
  array (
@@ -7427,7 +7174,7 @@ DeviceModels::$ANDROID_INDEX = array (
7427
  ),
7428
  '@VT' =>
7429
  array (
7430
- 0 => '(HW-|HUAWEI )?(ALE|ANE|CLT|D2|DAV|ELE|EML|EVA|FIG|G6|G7|GRA|M100|P2|P6|P7|PRA|RIO|SC|Sophia|STK|VIE|VKY|VNS|VOG|VTR|WAS)!!',
7431
  1 => 'VT6078',
7432
  2 => 'VT75C',
7433
  3 => 'VT77C',
@@ -7522,7 +7269,7 @@ DeviceModels::$ANDROID_INDEX = array (
7522
  ),
7523
  '@WA' =>
7524
  array (
7525
- 0 => '(HW-|HUAWEI )?(ALE|ANE|CLT|D2|DAV|ELE|EML|EVA|FIG|G6|G7|GRA|M100|P2|P6|P7|PRA|RIO|SC|Sophia|STK|VIE|VKY|VNS|VOG|VTR|WAS)!!',
7526
  1 => 'WA-U420D',
7527
  2 => 'WALSUN S1 Pro',
7528
  3 => 'WALSUN S2',
@@ -7920,21 +7667,20 @@ DeviceModels::$ANDROID_INDEX = array (
7920
  2 => '(Xiaomi|Xiaomi Mi|MI) Note!!',
7921
  3 => '(Xiaomi )?(MI )?MAX$!',
7922
  4 => '(Xiaomi )?(MI )?MAX 2$!',
7923
- 5 => '(Xiaomi )?(MI )?MAX 3$!',
7924
- 6 => '(Xiaomi )?(MI )?MIX$!',
7925
- 7 => '(Xiaomi )?(MI )?MIX 2$!',
7926
- 8 => '(Xiaomi )?(MI )?MIX 2S$!',
7927
- 9 => '(Xiaomi )?20!!',
7928
- 10 => '(Xiaomi )?(Redmi|RedRice|HM)!!',
7929
- 11 => '(Xiaomi )?(Redmi|HM)[ \\-]?Note!!',
7930
- 12 => '(Xiaomi |HM)?20!!',
7931
- 13 => 'Xiaomi MDT2!',
7932
- 14 => 'Xiaomi MCT1!',
7933
- 15 => 'Xiaomi MAT136!',
7934
- 16 => 'Xiaomi MBT6A5!',
7935
- 17 => '(Xiaomi|Xiaomi Mi|MI) Pad!!',
7936
- 18 => '(Xiaomi|Xiaomi Mi|MI)Box!!',
7937
- 19 => '(Xiaomi|Xiaomi Mi|MI)TV!!',
7938
  ),
7939
  '@XL' =>
7940
  array (
@@ -8041,10 +7787,6 @@ DeviceModels::$ANDROID_INDEX = array (
8041
  0 => 'Y6 Max',
8042
  1 => 'Y6 Piano',
8043
  ),
8044
- '@YA' =>
8045
- array (
8046
- 0 => '(HW-|HUAWEI |HONOR )?(ATH|BLN|BKL|BKK|BND|CHE|CHM|COL|DUA|DUK|DLI|EDI|FRD|HLK|HN3|H30|H60|HOL|JMM|JSN|LRA|KIW|LLD|NEM|NMO|OXF|PE|PCT|PLK|RNE|SCL|TNY|KNT|CAM|STF|HDN|YAL)!!',
8047
- ),
8048
  '@YD' =>
8049
  array (
8050
  0 => 'YD201',
@@ -8228,7 +7970,7 @@ DeviceModels::$ANDROID_INDEX = array (
8228
  array (
8229
  0 => '(BB )?Z10$!',
8230
  1 => 'Z1-H39LW',
8231
- 2 => '(HUAWEI )?(ALP|BLA|CRR|EVR|HMA|LIO|LON|LYA|MATE|MHA|MT1|MT2|MT7|M200|NXT|SNE|TAS|Z100)!!',
8232
  3 => 'Z1i',
8233
  ),
8234
  '@Z2' =>
15
  7 => '(Hisense )?(LED[0-9]{2,2}(G|K|L|EC|XT)[0-9]{2,3})!',
16
  8 => '[SX06][0-9]{2,2}HT!!',
17
  9 => '(Huawei )?[MSTX](1|2|7|8|10)\\-[A-Z0-9][0-9]{2,2}!!',
18
+ 10 => 'G[0-9]{3,3}!!',
19
+ 11 => 'Y[0-9]{3,3}!!',
20
+ 12 => '[0-9AS][0-9]{2,2}HW!!',
21
+ 13 => '(USCC-|KYOCERA-)?E[0-9]{4,4}!!',
22
+ 14 => '(USCC-|KYOCERA-)?C[0-9]{4,4}!!',
23
+ 15 => '[0-9]0[0-9]KC?!!',
24
+ 16 => 'K\\-?Touch!!',
25
+ 17 => '(Lenovo ?)?(IdeaTab ?)?[AB][0-9]{4,4}!!',
26
+ 18 => '(Lenovo )?(Tab ?)?(2 ?)?[AS](7|8|10)!!',
27
+ 19 => '(Lenovo ?)?(IdeaTab ?)?[KSV][0-9]{4,4}!!',
28
+ 20 => '[0-9]0[0-9]LG!!',
29
+ 21 => 'M\\-PP!!',
30
+ 22 => 'M\\-MP!!',
31
+ 23 => 'M\\-IPRO!!',
32
+ 24 => '(MEDION|(MD )?LIFETAB)!!',
33
+ 25 => 'M\\.T\\.T\\.!!',
34
+ 26 => 'O\\+!!',
35
+ 27 => '[0-9]{2,2}PFH6[0-9]{3,3}!',
36
+ 28 => '(?:RIVO )?RHYTHM RX ?([0-9]+)!',
37
+ 29 => '[4567A]0[0-9]SH!!',
38
+ 30 => '(3|5|6|7)0[0-9]SH!!',
39
+ 31 => 'C[0-9]{4,4}!!',
40
+ 32 => 'D[0-9]{4,4}!!',
41
+ 33 => 'E[0-9]{4,4}!!',
42
+ 34 => 'F[0-9]{4,4}!!',
43
+ 35 => 'G[0-9]{4,4}!!',
44
+ 36 => 'H[0-9]{4,4}!!',
45
+ 37 => 'E[0-9]{2,2}[a-z]!!',
46
+ 38 => 'L[0-9]{2,2}[a-z]!!',
47
+ 39 => '(SNM\\-)?M[0-9]{2,2}[a-z]!!',
48
+ 40 => 'S[0-9]{2,2}[a-z]!!',
49
+ 41 => '(XOLO )?[ABQX][0-9]{3,4}!!',
50
+ 42 => '(ZTE ?)?N[0-9]{3,3}!!',
51
+ 43 => '(ZXY-)?(ZTE )?N[0-9]{4,4}!!',
52
+ 44 => '(ZTE ?)?U[0-9]{3,3}!!',
53
+ 45 => '(ZTE ?)?V[0-9]{3,3}[A-Z]!!',
54
+ 46 => '(ZTE ?)?V ?[0-9]{3,3}!!',
55
+ 47 => '(ZTE ?)?X[0-9]{3,3}!!',
56
+ 48 => '(ZTE )?Z[0-9]!!',
57
+ 49 => '[a-z][a-z](?:-[a-z][a-z])?, SmartTabII7!',
 
 
58
  ),
59
  '@00' =>
60
  array (
133
  array (
134
  0 => '(3|5|6|7)0[0-9]SH!!',
135
  ),
 
 
 
 
136
  '@36' =>
137
  array (
138
  0 => '360 N4S',
162
  13 => '4027[ADNX]!',
163
  14 => '4028[AEJS]!',
164
  15 => '4032[ADEX]!',
165
+ 16 => '4033[AL]!',
166
  17 => '4034[ADEFGX]!',
167
  18 => '4035[ADYX]!',
168
  19 => '4036[E]!',
170
  21 => '4037[T]!',
171
  22 => '4037[V]!',
172
  23 => '4045[ADEFLOYX]!',
173
+ 24 => '4055[JU]!',
174
+ 25 => '4060[A]!',
175
+ 26 => '4060[W]!',
176
+ 27 => '40[0-9]SC!!',
177
+ 28 => '40[0-9]SO!!',
178
+ 29 => '402ZT',
 
 
179
  ),
180
  '@48' =>
181
  array (
188
  '@50' =>
189
  array (
190
  0 => '5010[DEGSUX]!',
191
+ 1 => '5012[G]!',
192
+ 2 => '5015[ADEX]!',
193
+ 3 => '5016[AJ]!',
194
+ 4 => '5017[B]!',
195
+ 5 => '5017[ADEOX]!',
196
+ 6 => '5019[D]!',
197
+ 7 => '5020[A]!',
198
+ 8 => '5022[DEX]!',
199
+ 9 => '5023[F]!',
200
+ 10 => '5025[DEGX]!',
201
+ 11 => '5027[B]!',
202
+ 12 => '5036[D]!',
203
+ 13 => '5038[ADEX]!',
204
+ 14 => '5042[ADEFGTWXY]!',
205
+ 15 => '5044[ADOY]!',
206
+ 16 => '5045[ADGJTX]!',
207
+ 17 => '5046[DGJY]!',
208
+ 18 => '5047[DUY]!',
209
+ 19 => '5049[EGSWZ]!',
210
+ 20 => '5050[ASYX]!',
211
+ 21 => '5051[ADJMX]!',
212
+ 22 => '5052[D]!',
213
+ 23 => '5054[ADOSTX]!',
214
+ 24 => '5054[NW]!',
215
+ 25 => '5056[ADENUWX]!',
216
+ 26 => '5056[O]!',
217
+ 27 => '5057[M]!',
218
+ 28 => '5065[ADJNWX]!',
219
+ 29 => '5070[DJX]!',
220
+ 30 => '5080[DFQX]!',
221
+ 31 => '5085[CDJNY]!',
222
+ 32 => '5090[Y]!',
223
+ 33 => '5095[BIKY]!',
224
+ 34 => '5096[AI]!',
225
+ 35 => '5098[OS]!',
226
+ 36 => '5099[ADY]!',
227
+ 37 => '504Q',
228
+ 38 => '504Q+',
229
+ 39 => '504QP',
230
+ 40 => '501LV',
231
+ 41 => '(48|50|55)AX600C!',
232
+ 42 => '5080C Pro',
233
+ 43 => '50[0-9]SO!!',
234
+ 44 => '502ZT',
 
 
 
 
 
 
 
 
 
 
 
 
235
  ),
236
  '@55' =>
237
  array (
266
  9 => '6045[BFGIKOXY]!',
267
  10 => '6050[AFWY]!',
268
  11 => '6055[ABDHIKPUY]!',
269
+ 12 => '6070[KOY]!',
270
+ 13 => '602LV',
271
+ 14 => '60[0-9]SO!!',
272
+ 15 => '602ZT',
273
+ 16 => '6034R ORANGE Niva',
 
 
 
 
 
 
 
274
  ),
275
  '@70' =>
276
  array (
442
  7 => 'A31',
443
  8 => 'A31c',
444
  9 => 'A31t',
445
+ 10 => 'A33f',
446
+ 11 => 'A33w',
447
+ 12 => 'A37f',
448
+ 13 => 'A37fw',
449
+ 14 => 'A3',
 
450
  ),
451
  '@A4' =>
452
  array (
487
  17 => 'A500CG',
488
  18 => 'A55i',
489
  19 => 'A52',
490
+ 20 => 'A51f',
491
+ 21 => 'A51w',
492
+ 22 => 'A5000',
493
+ 23 => 'a5',
 
494
  ),
495
  '@A6' =>
496
  array (
525
  16 => 'A750',
526
  17 => 'A7000-a',
527
  18 => 'A7010a48',
528
+ 19 => 'A7272+',
529
+ 20 => 'A70(CY6T)',
530
+ 21 => 'A78h四核(C1V3)',
 
531
  ),
532
  '@A8' =>
533
  array (
733
  33 => '(Allview|Alldro)!!',
734
  34 => 'Allwinner A10',
735
  35 => '(Highscreen|Alpha|Bay|Boost|Cosmo|Explosion|Power|Prime|Zera)!!',
736
+ 36 => '(HUAWEI )?(ALP|BLA|CRR|LON|MATE|MHA|MT1|MT2|MT7|M200|NXT|Z100)!!',
737
+ 37 => '(HW-|HUAWEI )?(ALE|ANE|D2|DAV|EML|EVA|FIG|G6|G7|GRA|M100|P2|P6|P7|PRA|RIO|SC|Sophia|VIE|VKY|VNS|VTR|WAS)!!',
738
  38 => 'Alfa A93 POP',
739
  39 => 'Alfa L',
740
  40 => 'Ally',
819
  41 => 'AN10G2-LZ',
820
  42 => 'AN10BG3-LZ',
821
  43 => 'AN7DG3C',
822
+ 44 => '(HW-|HUAWEI )?(ALE|ANE|D2|DAV|EML|EVA|FIG|G6|G7|GRA|M100|P2|P6|P7|PRA|RIO|SC|Sophia|VIE|VKY|VNS|VTR|WAS)!!',
823
  45 => '(iBall )?Andi!!',
824
  46 => 'AND1',
825
  47 => 'AND1E',
965
  13 => 'AT1G*',
966
  14 => 'AT7E',
967
  15 => 'ATP515CKIT',
968
+ 16 => '(HW-|HUAWEI |HONOR )?(ATH|BLN|BKL|BND|CHE|CHM|COL|DUA|DUK|DLI|EDI|FRD|HN3|H30|H60|HOL|JMM|KIW|LLD|NEM|NMO|PE|PLK|RNE|SCL|KNT|CAM|STF|HDN)!!',
969
+ 17 => 'aTab9.7 IPS',
970
+ 18 => 'AT735',
971
+ 19 => 'Atrix 2',
972
+ 20 => 'Atrix 2 WeifanZ',
973
+ 21 => 'Atrix 4G',
974
+ 22 => 'Atrix 4G ME860',
975
+ 23 => 'Atrix 4G MB860',
976
+ 24 => 'Atrix HD',
977
+ 25 => 'AtrixHD',
978
+ 26 => 'ATLANTIS',
979
+ 27 => 'ATP7526',
980
+ 28 => 'ATP7683',
981
+ 29 => 'AT1S0',
982
+ 30 => 'AT7-A',
983
+ 31 => 'AT7-B',
984
+ 32 => 'AT7-C',
985
+ 33 => 'AT10-A',
986
+ 34 => 'AT10LE-A',
987
+ 35 => 'AT10PE-A',
988
+ 36 => 'AT100',
989
+ 37 => 'AT200',
990
+ 38 => 'AT270',
991
+ 39 => 'AT300',
992
+ 40 => 'AT300SE',
993
+ 41 => 'AT330',
994
+ 42 => 'AT374',
995
+ 43 => 'AT400',
996
+ 44 => 'AT470',
997
+ 45 => 'AT500',
998
+ 46 => 'AT500a',
999
+ 47 => 'AT503',
1000
+ 48 => 'AT570',
1001
+ 49 => 'AT703',
1002
+ 50 => 'AT830',
1003
+ 51 => 'AT-A[QS][0-9]{2,2}!!',
1004
+ 52 => 'ATLAS W',
 
1005
  ),
1006
  '@AU' =>
1007
  array (
1061
  5 => 'Barnes & Noble Nook HD+',
1062
  6 => '(Highscreen|Alpha|Bay|Boost|Cosmo|Explosion|Power|Prime|Zera)!!',
1063
  7 => 'BAH-(W09|AL00|L09)!',
1064
+ 8 => '(HW-|HUAWEI )?BAC-(AL00|L03|L21|L22|TL00)!',
1065
+ 9 => 'Backflip',
1066
+ 10 => 'Backflip Me600',
1067
+ 11 => 'Bambook S1',
1068
+ 12 => 'BARRY',
1069
+ 13 => 'BASE!!',
 
1070
  ),
1071
  '@BB' =>
1072
  array (
1161
  '@BK' =>
1162
  array (
1163
  0 => '(BDS|BHX|BKO)\\-!!',
1164
+ 1 => '(HW-|HUAWEI |HONOR )?(ATH|BLN|BKL|BND|CHE|CHM|COL|DUA|DUK|DLI|EDI|FRD|HN3|H30|H60|HOL|JMM|KIW|LLD|NEM|NMO|PE|PLK|RNE|SCL|KNT|CAM|STF|HDN)!!',
1165
  ),
1166
  '@BL' =>
1167
  array (
1174
  6 => 'Bluboo S1',
1175
  7 => 'Blaze S180',
1176
  8 => 'BLADE LE 70',
1177
+ 9 => '(HUAWEI )?(ALP|BLA|CRR|LON|MATE|MHA|MT1|MT2|MT7|M200|NXT|Z100)!!',
1178
+ 10 => '(HW-|HUAWEI |HONOR )?(ATH|BLN|BKL|BND|CHE|CHM|COL|DUA|DUK|DLI|EDI|FRD|HN3|H30|H60|HOL|JMM|KIW|LLD|NEM|NMO|PE|PLK|RNE|SCL|KNT|CAM|STF|HDN)!!',
1179
  11 => '(HW-|HUAWEI )?(BLL|CHC|TAG|KII)!!',
1180
  12 => '(BLF-)?lephone!!',
1181
  13 => 'Blackphone 2',
1201
  6 => '(NOOK )?BNTV(800)!',
1202
  7 => 'BN Nook HD',
1203
  8 => 'BN NookHD+',
1204
+ 9 => '(HW-|HUAWEI |HONOR )?(ATH|BLN|BKL|BND|CHE|CHM|COL|DUA|DUK|DLI|EDI|FRD|HN3|H30|H60|HOL|JMM|KIW|LLD|NEM|NMO|PE|PLK|RNE|SCL|KNT|CAM|STF|HDN)!!',
1205
  ),
1206
  '@BO' =>
1207
  array (
1356
  9 => 'Casper VIA!!',
1357
  10 => 'CAT!!',
1358
  11 => 'Candy TV',
1359
+ 12 => '(HW-|HUAWEI |HONOR )?(ATH|BLN|BKL|BND|CHE|CHM|COL|DUA|DUK|DLI|EDI|FRD|HN3|H30|H60|HOL|JMM|KIW|LLD|NEM|NMO|PE|PLK|RNE|SCL|KNT|CAM|STF|HDN)!!',
1360
  13 => '(HW-|HUAWEI )?(CRO|LUA|CUN|SCC|SCU|CAM|LDN|LYO|MYA)!!',
1361
  14 => '(HW-|HUAWEI )?CAZ-(AL10|TL10|TL20)!',
1362
  15 => '(HW-|HUAWEI )?CAN-(L01|L11|L12)!',
1391
  11 => 'Cherry w500',
1392
  12 => 'CHUWI!!',
1393
  13 => 'CHONG!!',
1394
+ 14 => '(HW-|HUAWEI |HONOR )?(ATH|BLN|BKL|BND|CHE|CHM|COL|DUA|DUK|DLI|EDI|FRD|HN3|H30|H60|HOL|JMM|KIW|LLD|NEM|NMO|PE|PLK|RNE|SCL|KNT|CAM|STF|HDN)!!',
1395
  15 => '(HW-|HUAWEI )?(BLL|CHC|TAG|KII)!!',
1396
  16 => 'chagall',
1397
  17 => 'chiron',
1426
  4 => 'Clanga SE 097-1008',
1427
  5 => 'CLP281X',
1428
  6 => 'Click',
1429
+ 7 => '(Intex )?Cloud!!',
1430
+ 8 => 'CLIQ',
1431
+ 9 => 'CLIQ XT',
1432
+ 10 => 'CLIQ2',
 
1433
  ),
1434
  '@CM' =>
1435
  array (
1436
  0 => 'CMP!!',
1437
  1 => '(cm|aokp) tenderloin!',
1438
+ 2 => 'CM980',
1439
+ 3 => 'CM990',
 
1440
  ),
1441
  '@CN' =>
1442
  array (
1463
  15 => 'Connect-2G-2.0',
1464
  16 => '(Highscreen|Alpha|Bay|Boost|Cosmo|Explosion|Power|Prime|Zera)!!',
1465
  17 => 'Coquettish Red',
1466
+ 18 => '(HW-|HUAWEI |HONOR )?(ATH|BLN|BKL|BND|CHE|CHM|COL|DUA|DUK|DLI|EDI|FRD|HN3|H30|H60|HOL|JMM|KIW|LLD|NEM|NMO|PE|PLK|RNE|SCL|KNT|CAM|STF|HDN)!!',
1467
  19 => 'Comet',
1468
  20 => 'Corvair',
1469
  21 => 'COOLPIX S800c',
1477
  2 => 'CP8676!',
1478
  3 => 'CP8298!',
1479
  4 => 'CPN-(W09|AL00|L09)!',
1480
+ 5 => 'CPH1605',
1481
+ 6 => 'CPH1701',
1482
+ 7 => 'CPH1717',
1483
+ 8 => 'CPH1609',
1484
+ 9 => 'CPH1613',
1485
+ 10 => 'CPH1723',
1486
+ 11 => 'CPH1611',
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1487
  ),
1488
  '@CR' =>
1489
  array (
1491
  1 => 'CRESTA.CTP888',
1492
  2 => 'Cross!!',
1493
  3 => 'Crosscall!!',
1494
+ 4 => '(HUAWEI )?(ALP|BLA|CRR|LON|MATE|MHA|MT1|MT2|MT7|M200|NXT|Z100)!!',
1495
  5 => '(HW-|HUAWEI )?(CRO|LUA|CUN|SCC|SCU|CAM|LDN|LYO|MYA)!!',
1496
  6 => 'CRONO 22',
1497
  7 => 'Crescent',
1564
  '@D2' =>
1565
  array (
1566
  0 => 'D2-[0-9]{3,3}!!',
1567
+ 1 => '(HW-|HUAWEI )?(ALE|ANE|D2|DAV|EML|EVA|FIG|G6|G7|GRA|M100|P2|P6|P7|PRA|RIO|SC|Sophia|VIE|VKY|VNS|VTR|WAS)!!',
1568
  ),
1569
  '@D5' =>
1570
  array (
1597
  1 => '(BLU|DASH|LIFE|NEO|STUDIO|VIVO)!!',
1598
  2 => 'Dakele A380',
1599
  3 => 'DAKELE MC001',
1600
+ 4 => '(HW-|HUAWEI )?(ALE|ANE|D2|DAV|EML|EVA|FIG|G6|G7|GRA|M100|P2|P6|P7|PRA|RIO|SC|Sophia|VIE|VKY|VNS|VTR|WAS)!!',
1601
  5 => 'DATAM803HC',
1602
  6 => 'DATAM805HC',
1603
  7 => 'DATAM819HD!',
1680
  1 => 'DL8006',
1681
  2 => 'DLX',
1682
  3 => 'DLXU',
1683
+ 4 => '(HW-|HUAWEI |HONOR )?(ATH|BLN|BKL|BND|CHE|CHM|COL|DUA|DUK|DLI|EDI|FRD|HN3|H30|H60|HOL|JMM|KIW|LLD|NEM|NMO|PE|PLK|RNE|SCL|KNT|CAM|STF|HDN)!!',
1684
  5 => 'dL1',
1685
  ),
1686
  '@DM' =>
1687
  array (
1688
  0 => 'DM0[0-9]{2,2}(K|SH)!!',
1689
+ 1 => 'DM-01G',
1690
+ 2 => 'DM-01K',
1691
+ 3 => 'DM-02H',
1692
+ 4 => 'DMC-CM1',
1693
+ 5 => 'DM-01H',
1694
+ 6 => 'DM-01J',
 
 
 
1695
  ),
1696
  '@DN' =>
1697
  array (
1727
  0 => 'Dream',
1728
  1 => '(GIO-)?(GiONEE[- ])?Dream D1!',
1729
  2 => 'Droid Incredible',
1730
+ 3 => '(HW-|HUAWEI )?(DRA|FLA|TIT|TAG|NCE|TRT|SLA)!!',
1731
  4 => 'DroniX-0.5',
1732
  5 => 'Droid',
1733
  6 => 'DROID',
1771
  ),
1772
  '@DU' =>
1773
  array (
1774
+ 0 => '(HW-|HUAWEI |HONOR )?(ATH|BLN|BKL|BND|CHE|CHM|COL|DUA|DUK|DLI|EDI|FRD|HN3|H30|H60|HOL|JMM|KIW|LLD|NEM|NMO|PE|PLK|RNE|SCL|KNT|CAM|STF|HDN)!!',
1775
  ),
1776
  '@DW' =>
1777
  array (
1894
  array (
1895
  0 => '(bq|Aquaris|Edison|Maxwell)!!',
1896
  1 => 'edgejr',
1897
+ 2 => '(HW-|HUAWEI |HONOR )?(ATH|BLN|BKL|BND|CHE|CHM|COL|DUA|DUK|DLI|EDI|FRD|HN3|H30|H60|HOL|JMM|KIW|LLD|NEM|NMO|PE|PLK|RNE|SCL|KNT|CAM|STF|HDN)!!',
1898
  3 => 'edenTAB ET-701',
1899
  ),
1900
  '@EE' =>
1930
  4 => 'ELIFE-E3',
1931
  5 => 'Elife E5',
1932
  6 => 'ElifeE6',
1933
+ 7 => 'Elektra L',
1934
+ 8 => 'Elektra XL',
1935
+ 9 => 'Electrify',
1936
+ 10 => 'Eluga A2',
1937
+ 11 => 'ELUGA A3',
1938
+ 12 => 'ELUGA A3 Pro',
1939
+ 13 => 'ELUGA I2',
1940
+ 14 => 'ELUGA I2 Activ',
1941
+ 15 => 'ELUGA I4',
1942
+ 16 => 'Eluga Arc 2',
1943
+ 17 => 'Eluga Mark 2',
1944
+ 18 => 'ELUGA Note',
1945
+ 19 => 'ELUGA Prim',
1946
+ 20 => 'ELUGA Pulse X',
1947
+ 21 => 'ELUGA Ray',
1948
+ 22 => 'ELUGA Ray Max',
1949
+ 23 => 'ELUGA Ray X',
1950
+ 24 => 'Eluga Ray 700',
1951
+ 25 => 'ELUGA Turbo',
1952
+ 26 => 'Elite',
1953
+ 27 => 'Elite 11',
1954
+ 28 => '(SENCOR )?ELEMENT!!',
1955
+ 29 => 'Elite 5.5L+',
1956
+ 30 => 'Elite 6.0L',
 
1957
  ),
1958
  '@EM' =>
1959
  array (
1960
  0 => 'EMBT3C',
1961
  1 => 'EM63',
1962
  2 => 'EM01F',
1963
+ 3 => '(HW-|HUAWEI )?(ALE|ANE|D2|DAV|EML|EVA|FIG|G6|G7|GRA|M100|P2|P6|P7|PRA|RIO|SC|Sophia|VIE|VKY|VNS|VTR|WAS)!!',
1964
  4 => 'eMAX mini',
1965
  5 => 'EMR1879',
1966
  ),
2023
  8 => 'EVO ?3D!',
2024
  9 => 'EVO 4G',
2025
  10 => 'Evo V 4G',
2026
+ 11 => '(HW-|HUAWEI )?(ALE|ANE|D2|DAV|EML|EVA|FIG|G6|G7|GRA|M100|P2|P6|P7|PRA|RIO|SC|Sophia|VIE|VKY|VNS|VTR|WAS)!!',
2027
+ 12 => '(EV|KM)-[ES][0-9]{3,3}!!',
2028
+ 13 => 'Event',
2029
+ 14 => 'EVERY35',
 
2030
  ),
2031
  '@EX' =>
2032
  array (
2102
  array (
2103
  0 => 'FIH-FB0',
2104
  1 => 'FIH-!!',
2105
+ 2 => '(HW-|HUAWEI )?(ALE|ANE|D2|DAV|EML|EVA|FIG|G6|G7|GRA|M100|P2|P6|P7|PRA|RIO|SC|Sophia|VIE|VKY|VNS|VTR|WAS)!!',
2106
  3 => 'Find 5',
2107
  4 => 'FIND7',
2108
  ),
2141
  25 => 'Flylife!!',
2142
  26 => 'Fly Flylife Web 7.85 Slim',
2143
  27 => 'Flyer',
2144
+ 28 => '(HW-|HUAWEI )?(DRA|FLA|TIT|TAG|NCE|TRT|SLA)!!',
2145
  29 => 'Flair E1',
2146
  30 => 'Flair E2',
2147
  31 => 'FlairE3',
2187
  '@FR' =>
2188
  array (
2189
  0 => 'Freelander I20',
2190
+ 1 => '(HW-|HUAWEI |HONOR )?(ATH|BLN|BKL|BND|CHE|CHM|COL|DUA|DUK|DLI|EDI|FRD|HN3|H30|H60|HOL|JMM|KIW|LLD|NEM|NMO|PE|PLK|RNE|SCL|KNT|CAM|STF|HDN)!!',
2191
  2 => '(MODECOM )?FreeTAB!!',
2192
  ),
2193
  '@FS' =>
2268
  ),
2269
  '@G6' =>
2270
  array (
2271
+ 0 => '(HW-|HUAWEI )?(ALE|ANE|D2|DAV|EML|EVA|FIG|G6|G7|GRA|M100|P2|P6|P7|PRA|RIO|SC|Sophia|VIE|VKY|VNS|VTR|WAS)!!',
2272
  ),
2273
  '@G7' =>
2274
  array (
2275
+ 0 => '(HW-|HUAWEI )?(ALE|ANE|D2|DAV|EML|EVA|FIG|G6|G7|GRA|M100|P2|P6|P7|PRA|RIO|SC|Sophia|VIE|VKY|VNS|VTR|WAS)!!',
2276
  ),
2277
  '@G9' =>
2278
  array (
2439
  ),
2440
  '@GM' =>
2441
  array (
2442
+ 0 => 'Gm Discovery',
2443
+ 1 => 'GM Discovery II',
2444
+ 2 => 'GM Discovery II+',
2445
+ 3 => 'GM FOX',
2446
+ 4 => 'GM Ultimate Slim',
2447
+ 5 => 'GM 5',
2448
+ 6 => 'GM 5 d',
2449
+ 7 => 'GM 5 Plus',
2450
+ 8 => 'GM 5 Plus d',
2451
+ 9 => 'GM 6',
2452
+ 10 => 'GM 6 d',
2453
+ 11 => 'GM Discovery tab 8',
 
 
 
2454
  ),
2455
  '@GN' =>
2456
  array (
2526
  10 => '(Google )?Nexus ?9!',
2527
  11 => '(Google )?Nexus ?10!',
2528
  12 => 'Google Pixel',
2529
+ 13 => 'Google Pixel XL',
2530
+ 14 => 'Google Pixel 2',
2531
+ 15 => 'Google Pixel 2XL',
2532
+ 16 => 'Google Chromebook Pixel (2015)',
2533
+ 17 => 'google cube',
2534
+ 18 => 'GOCL!!',
2535
+ 19 => 'GO Live!!',
2536
+ 20 => 'GOOPHONE!!',
2537
+ 21 => 'GO !!',
2538
+ 22 => 'GOA',
2539
+ 23 => 'GO504',
2540
+ 24 => 'GO778',
2541
+ 25 => 'GO960',
2542
+ 26 => 'GO963',
2543
+ 27 => 'GO980',
2544
+ 28 => 'GO984',
2545
+ 29 => 'Gomobile GO1001',
2546
  ),
2547
  '@GP' =>
2548
  array (
2560
  array (
2561
  0 => 'Grouper',
2562
  1 => 'GR-TB!!',
2563
+ 2 => '(HW-|HUAWEI )?(ALE|ANE|D2|DAV|EML|EVA|FIG|G6|G7|GRA|M100|P2|P6|P7|PRA|RIO|SC|Sophia|VIE|VKY|VNS|VTR|WAS)!!',
2564
  3 => 'greenridge',
2565
  4 => 'Graphos A10',
2566
  5 => '(ZTE )?(Grand|Mimosa)!!',
2622
  ),
2623
  '@H3' =>
2624
  array (
2625
+ 0 => '(HW-|HUAWEI |HONOR )?(ATH|BLN|BKL|BND|CHE|CHM|COL|DUA|DUK|DLI|EDI|FRD|HN3|H30|H60|HOL|JMM|KIW|LLD|NEM|NMO|PE|PLK|RNE|SCL|KNT|CAM|STF|HDN)!!',
2626
  ),
2627
  '@H6' =>
2628
  array (
2629
+ 0 => '(HW-|HUAWEI |HONOR )?(ATH|BLN|BKL|BND|CHE|CHM|COL|DUA|DUK|DLI|EDI|FRD|HN3|H30|H60|HOL|JMM|KIW|LLD|NEM|NMO|PE|PLK|RNE|SCL|KNT|CAM|STF|HDN)!!',
2630
  ),
2631
  '@H7' =>
2632
  array (
2672
  0 => 'HD2',
2673
  1 => 'HD2 LEO',
2674
  2 => 'HD7 Pro',
2675
+ 3 => '(HW-|HUAWEI |HONOR )?(ATH|BLN|BKL|BND|CHE|CHM|COL|DUA|DUK|DLI|EDI|FRD|HN3|H30|H60|HOL|JMM|KIW|LLD|NEM|NMO|PE|PLK|RNE|SCL|KNT|CAM|STF|HDN)!!',
 
 
2676
  ),
2677
  '@HE' =>
2678
  array (
2708
  '@HL' =>
2709
  array (
2710
  0 => 'HLV-T!!',
 
2711
  ),
2712
  '@HM' =>
2713
  array (
2714
+ 0 => 'HMP8100 ATV 93',
2715
+ 1 => 'HMP8100 ATV INT',
2716
+ 2 => '(Xiaomi )?(Redmi|RedRice|HM)!!',
2717
+ 3 => '(Xiaomi )?(Redmi|HM)[ \\-]?Note!!',
2718
+ 4 => '(Xiaomi |HM)?20!!',
 
2719
  ),
2720
  '@HN' =>
2721
  array (
2722
+ 0 => '(HW-|HUAWEI |HONOR )?(ATH|BLN|BKL|BND|CHE|CHM|COL|DUA|DUK|DLI|EDI|FRD|HN3|H30|H60|HOL|JMM|KIW|LLD|NEM|NMO|PE|PLK|RNE|SCL|KNT|CAM|STF|HDN)!!',
2723
  ),
2724
  '@HO' =>
2725
  array (
2726
  0 => 'HOSIN!!',
2727
+ 1 => '(HW-|HUAWEI |HONOR )?(ATH|BLN|BKL|BND|CHE|CHM|COL|DUA|DUK|DLI|EDI|FRD|HN3|H30|H60|HOL|JMM|KIW|LLD|NEM|NMO|PE|PLK|RNE|SCL|KNT|CAM|STF|HDN)!!',
2728
  2 => 'Honor3c2G-T',
2729
  3 => 'Honor Bee',
2730
  4 => 'HOMESYNCT2WIFI',
2781
  6 => 'Huawei MediaPad T1 10 4G',
2782
  7 => '(Huawei )?[MSTX](1|2|7|8|10)\\-[A-Z0-9][0-9]{2,2}!!',
2783
  8 => 'HUAWEI GEM-703L',
2784
+ 9 => '(HUAWEI )?(ALP|BLA|CRR|LON|MATE|MHA|MT1|MT2|MT7|M200|NXT|Z100)!!',
2785
+ 10 => '(HW-|HUAWEI )?(DRA|FLA|TIT|TAG|NCE|TRT|SLA)!!',
2786
+ 11 => '(HW-|HUAWEI |HONOR )?(ATH|BLN|BKL|BND|CHE|CHM|COL|DUA|DUK|DLI|EDI|FRD|HN3|H30|H60|HOL|JMM|KIW|LLD|NEM|NMO|PE|PLK|RNE|SCL|KNT|CAM|STF|HDN)!!',
2787
  12 => '(HW-|HUAWEI )?(BLL|CHC|TAG|KII)!!',
2788
+ 13 => '(HW-|HUAWEI )?(ALE|ANE|D2|DAV|EML|EVA|FIG|G6|G7|GRA|M100|P2|P6|P7|PRA|RIO|SC|Sophia|VIE|VKY|VNS|VTR|WAS)!!',
2789
  14 => 'HUAWEI A168-(AL10|DL09|L09|L29)!',
2790
  15 => '(HW-|HUAWEI )?(CRO|LUA|CUN|SCC|SCU|CAM|LDN|LYO|MYA)!!',
2791
  16 => '(HW-|HUAWEI )?CAZ-(AL10|TL10|TL20)!',
2794
  19 => '(HW-|HUAWEI )?DIG-(AL00|L01|L03|L21|TL10)!',
2795
  20 => '(HW-|HUAWEI )?BAC-(AL00|L03|L21|L22|TL00)!',
2796
  21 => '(HW-|HUAWEI )?HWI-(AL00|TL00)!',
2797
+ 22 => '(HW-|HUAWEI )?MLA-(AL00|AL10)!',
2798
+ 23 => '(HW-|HUAWEI )?MLA-(TL00|TL10|UL00)!',
2799
+ 24 => 'Huawei P7 mini',
2800
+ 25 => 'Huawei P8max',
2801
+ 26 => '(Huawei|Ascend|HW-)!!',
2802
+ 27 => 'HUAWEI Honor 3c w',
2803
+ 28 => 'Huawei S7',
2804
+ 29 => 'Hudl HT7S3',
2805
+ 30 => 'Hudl 2',
2806
+ 31 => 'HUAWEI U8686',
2807
+ 32 => 'Huawei 858',
 
 
 
2808
  ),
2809
  '@HW' =>
2810
  array (
2811
+ 0 => '(HW-|HUAWEI )?(DRA|FLA|TIT|TAG|NCE|TRT|SLA)!!',
2812
+ 1 => '(HW-|HUAWEI |HONOR )?(ATH|BLN|BKL|BND|CHE|CHM|COL|DUA|DUK|DLI|EDI|FRD|HN3|H30|H60|HOL|JMM|KIW|LLD|NEM|NMO|PE|PLK|RNE|SCL|KNT|CAM|STF|HDN)!!',
2813
  2 => '(HW-|HUAWEI )?(BLL|CHC|TAG|KII)!!',
2814
+ 3 => '(HW-|HUAWEI )?(ALE|ANE|D2|DAV|EML|EVA|FIG|G6|G7|GRA|M100|P2|P6|P7|PRA|RIO|SC|Sophia|VIE|VKY|VNS|VTR|WAS)!!',
2815
  4 => '(HW-|HUAWEI )?(CRO|LUA|CUN|SCC|SCU|CAM|LDN|LYO|MYA)!!',
2816
  5 => '(HW-|HUAWEI )?CAZ-(AL10|TL10|TL20)!',
2817
  6 => '(HW-|HUAWEI )?CAN-(L01|L11|L12)!',
2819
  8 => '(HW-|HUAWEI )?DIG-(AL00|L01|L03|L21|TL10)!',
2820
  9 => '(HW-|HUAWEI )?BAC-(AL00|L03|L21|L22|TL00)!',
2821
  10 => '(HW-|HUAWEI )?HWI-(AL00|TL00)!',
2822
+ 11 => '(HW-|HUAWEI )?MLA-(AL00|AL10)!',
2823
+ 12 => '(HW-|HUAWEI )?MLA-(TL00|TL10|UL00)!',
2824
+ 13 => '(Huawei|Ascend|HW-)!!',
2825
+ 14 => 'hwu8812D',
2826
+ 15 => 'HW-01E',
2827
+ 16 => 'HW-01K',
2828
+ 17 => 'HW-03E',
2829
+ 18 => 'HWT31',
2830
+ 19 => 'HWV32',
 
 
 
2831
  ),
2832
  '@HY' =>
2833
  array (
2951
  7 => 'Incredible ?2!',
2952
  8 => 'Incredible 4G LTE',
2953
  9 => 'Inspire 4G',
2954
+ 10 => 'INFOBAR!!',
2955
+ 11 => 'Infinix!!',
2956
+ 12 => 'IN[0-9]{3,3}!!',
2957
+ 13 => 'Infocus!!',
2958
+ 14 => 'INHON PAPILIO G1',
2959
+ 15 => 'intki E86',
2960
+ 16 => 'Innos!!',
2961
+ 17 => '(Intex )?Aqua!!',
2962
+ 18 => '(Intex )?Cloud!!',
2963
+ 19 => 'INTEX IRIS-II',
2964
+ 20 => 'INQ Cloud Touch',
2965
+ 21 => 'INQ Mayfair (EU)',
2966
+ 22 => '(iNote|itel)!!',
2967
+ 23 => 'Infinity',
2968
+ 24 => 'Internet TV',
2969
+ 25 => 'Internet TV Box',
 
2970
  ),
2971
  '@IO' =>
2972
  array (
3048
  '@JD' =>
3049
  array (
3050
  0 => 'JDN-W09',
 
 
3051
  ),
3052
  '@JI' =>
3053
  array (
3058
  array (
3059
  0 => 'JJ5S+',
3060
  ),
 
 
 
 
3061
  '@JM' =>
3062
  array (
3063
+ 0 => '(HW-|HUAWEI |HONOR )?(ATH|BLN|BKL|BND|CHE|CHM|COL|DUA|DUK|DLI|EDI|FRD|HN3|H30|H60|HOL|JMM|KIW|LLD|NEM|NMO|PE|PLK|RNE|SCL|KNT|CAM|STF|HDN)!!',
3064
  ),
3065
  '@JO' =>
3066
  array (
3068
  1 => 'Joy',
3069
  2 => 'JOIN',
3070
  ),
 
 
 
 
3071
  '@JT' =>
3072
  array (
3073
  0 => 'JT SmartPC02',
3186
  14 => 'KFGIWI',
3187
  15 => 'KFDOWI',
3188
  16 => 'KFSUWI',
 
 
3189
  ),
3190
  '@KI' =>
3191
  array (
3192
  0 => 'Kindle Fire',
3193
+ 1 => '(HW-|HUAWEI |HONOR )?(ATH|BLN|BKL|BND|CHE|CHM|COL|DUA|DUK|DLI|EDI|FRD|HN3|H30|H60|HOL|JMM|KIW|LLD|NEM|NMO|PE|PLK|RNE|SCL|KNT|CAM|STF|HDN)!!',
3194
  2 => '(HW-|HUAWEI )?(BLL|CHC|TAG|KII)!!',
3195
  3 => 'KIOTO 793',
3196
  4 => 'KITE',
3202
  ),
3203
  '@KN' =>
3204
  array (
3205
+ 0 => '(HW-|HUAWEI |HONOR )?(ATH|BLN|BKL|BND|CHE|CHM|COL|DUA|DUK|DLI|EDI|FRD|HN3|H30|H60|HOL|JMM|KIW|LLD|NEM|NMO|PE|PLK|RNE|SCL|KNT|CAM|STF|HDN)!!',
3206
  ),
3207
  '@KO' =>
3208
  array (
3441
  12 => 'LG-DS1203',
3442
  13 => 'LG-?E[0-9]{3,3}!!',
3443
  14 => 'LG-F[0-9]{3,3}!!',
3444
+ 15 => 'LG-GT540!',
3445
+ 16 => 'LG-GW620!',
3446
+ 17 => 'LG-H[0-9]{3,3}!!',
3447
+ 18 => 'LG-K[0-9]{3,3}!!',
3448
+ 19 => 'LG-KH5200',
3449
+ 20 => 'LG-KS1024',
3450
+ 21 => 'LG-KU[0-9]{4,4}!!',
3451
+ 22 => 'LG-?L[0-9]{2,3}[A-Z]!!',
3452
+ 23 => 'LG-LG[0-9]{3,3}!!',
3453
+ 24 => 'LGLK430',
3454
+ 25 => 'LG-LK460',
3455
+ 26 => 'LG-?LS[0-9]{3,3}!!',
3456
+ 27 => 'LG-LU[0-9]{4,4}!!',
3457
+ 28 => 'LG-LW690',
3458
+ 29 => 'LG-LW770',
3459
+ 30 => 'LG-M[0-9]{3,3}!!',
3460
+ 31 => 'LG-?MS[0-9]{3,3}!!',
3461
+ 32 => 'LGMP260',
3462
+ 33 => 'LG-P[0-9]{3,3}!!',
3463
+ 34 => 'LG-SU[0-9]{3,3}!!',
3464
+ 35 => 'LG-T480!',
3465
+ 36 => 'LG-T540!',
3466
+ 37 => 'LG-TP260',
3467
+ 38 => 'LG-TP450',
3468
+ 39 => 'LG-SU-760',
3469
+ 40 => 'LGUK410',
3470
+ 41 => 'LG-UK495',
3471
+ 42 => 'LGUK750',
3472
+ 43 => 'LGUK932',
3473
+ 44 => 'LG-UN350',
3474
+ 45 => 'LG-?US[0-9]{3,3}!!',
3475
+ 46 => 'LG-V[0-9]{3,3}!!',
3476
+ 47 => 'LG-VK[0-9]{3,3}!!',
3477
+ 48 => 'LG-VN[0-9]{3,3}!!',
3478
+ 49 => 'LG-VM[0-9]{3,3}!!',
3479
+ 50 => 'LG-VS[0-9]{3,3}!!',
3480
+ 51 => 'LG-X[0-9]{3,3}!!',
3481
+ 52 => 'LGM-[GKVX][0-9]{3,3}!!',
3482
+ 53 => 'LGMP450',
3483
+ 54 => 'lge-F160!',
3484
+ 55 => 'LGE-E988!',
3485
+ 56 => 'lgp-970',
3486
+ 57 => 'LG[LSTV][0-9]{2,2}!!',
3487
+ 58 => 'LG!!',
3488
+ 59 => 'LG-Google TV!!',
3489
+ 60 => 'LG-ANDROID MINI BOX',
3490
+ 61 => 'LG-P999',
3491
+ 62 => 'LG-E739',
3492
+ 63 => 'LG-C800',
 
 
 
 
3493
  ),
3494
  '@LI' =>
3495
  array (
3496
  0 => 'Liquid!!',
3497
  1 => '(BLU|DASH|LIFE|NEO|STUDIO|VIVO)!!',
3498
  2 => 'Liberty',
3499
+ 3 => '(MEDION|(MD )?LIFETAB)!!',
3500
+ 4 => 'Life',
3501
+ 5 => 'Liberty Tab G100',
3502
+ 6 => 'Live ?With ?Walkman!',
3503
+ 7 => 'libra',
3504
+ 8 => 'lithium',
3505
+ 9 => 'Light Tab',
3506
+ 10 => 'Light Tab 2',
3507
+ 11 => 'Light Tab 2W',
 
3508
  ),
3509
  '@LL' =>
3510
  array (
3511
+ 0 => '(HW-|HUAWEI |HONOR )?(ATH|BLN|BKL|BND|CHE|CHM|COL|DUA|DUK|DLI|EDI|FRD|HN3|H30|H60|HOL|JMM|KIW|LLD|NEM|NMO|PE|PLK|RNE|SCL|KNT|CAM|STF|HDN)!!',
3512
  1 => '(Lanix )?(Ilium|llium)!!',
3513
  ),
3514
  '@LM' =>
3515
  array (
3516
  0 => 'LM-G710!',
3517
  1 => 'LM-G715!',
3518
+ 2 => 'LM-Q610!',
3519
+ 3 => 'LM-Q710!',
3520
+ 4 => 'LM-V350!',
3521
+ 5 => 'LM-X210!',
3522
+ 6 => 'LM-X410!',
3523
+ 7 => 'LM-X415!',
3524
+ 8 => 'LM-X510!',
3525
+ 9 => 'LM-Y110!',
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3526
  ),
3527
  '@LO' =>
3528
  array (
3529
  0 => 'LogicPD Zoom2',
3530
+ 1 => '(HUAWEI )?(ALP|BLA|CRR|LON|MATE|MHA|MT1|MT2|MT7|M200|NXT|Z100)!!',
3531
  2 => 'Loox',
3532
  ),
 
 
 
 
3533
  '@LS' =>
3534
  array (
3535
  0 => 'LS670',
3600
  ),
3601
  '@LY' =>
3602
  array (
3603
+ 0 => '(HW-|HUAWEI )?(CRO|LUA|CUN|SCC|SCU|CAM|LDN|LYO|MYA)!!',
3604
+ 1 => 'LYF LS-4006',
3605
+ 2 => 'LYF LS-5009',
 
3606
  ),
3607
  '@M' =>
3608
  array (
3633
  '@M1' =>
3634
  array (
3635
  0 => 'M19',
3636
+ 1 => '(HW-|HUAWEI )?(ALE|ANE|D2|DAV|EML|EVA|FIG|G6|G7|GRA|M100|P2|P6|P7|PRA|RIO|SC|Sophia|VIE|VKY|VNS|VTR|WAS)!!',
3637
  2 => 'M1050S',
3638
  3 => 'M1',
3639
  4 => 'm1 metal',
3643
  ),
3644
  '@M2' =>
3645
  array (
3646
+ 0 => '(HUAWEI )?(ALP|BLA|CRR|LON|MATE|MHA|MT1|MT2|MT7|M200|NXT|Z100)!!',
3647
  1 => 'M210',
3648
  2 => 'm2 note',
3649
  3 => 'm2',
3731
  2 => 'manta',
3732
  3 => '(bq|Aquaris|Edison|Maxwell)!!',
3733
  4 => '(DNS )?(Airtab )?(E|ES|M|MA|MC|MF|MW|P|PC|PF)[0-9]{2,4}!!',
3734
+ 5 => '(HUAWEI )?(ALP|BLA|CRR|LON|MATE|MHA|MT1|MT2|MT7|M200|NXT|Z100)!!',
3735
+ 6 => 'MAX FIND 5.0',
3736
+ 7 => 'Malata!!',
3737
+ 8 => 'Masstel!!',
3738
+ 9 => 'MASTONE!!',
3739
+ 10 => 'Maxtron!!',
3740
+ 11 => 'magi',
3741
+ 12 => 'MagicBox',
3742
+ 13 => '(Xiaomi )?(MI )?MAX$!',
3743
+ 14 => '(Xiaomi )?(MI )?MAX 2$!',
3744
+ 15 => 'markf',
3745
+ 16 => 'markw',
 
 
3746
  ),
3747
  '@MB' =>
3748
  array (
3816
  '@MH' =>
3817
  array (
3818
  0 => 'MH350',
3819
+ 1 => '(HUAWEI )?(ALP|BLA|CRR|LON|MATE|MHA|MT1|MT2|MT7|M200|NXT|Z100)!!',
3820
  ),
3821
  '@MI' =>
3822
  array (
3856
  33 => '(CSL[- ])?(Spice[- ]?)?Mi(-| )?[0-9]{3,3}!!',
3857
  34 => 'miTab!!',
3858
  35 => '(Xiaomi )?(Xiaomi|Xiaomi M|MI)!!',
3859
+ 36 => '(Xiaomi|Xiaomi Mi|MI) Note!!',
3860
+ 37 => '(Xiaomi )?(MI )?MAX$!',
3861
+ 38 => '(Xiaomi )?(MI )?MAX 2$!',
3862
+ 39 => '(Xiaomi )?(MI )?MIX$!',
3863
+ 40 => '(Xiaomi )?(MI )?MIX 2$!',
3864
+ 41 => '(Xiaomi )?(MI )?MIX 2S$!',
3865
+ 42 => 'mido',
3866
+ 43 => '(Xiaomi|Xiaomi Mi|MI) Pad!!',
3867
+ 44 => '(Xiaomi|Xiaomi Mi|MI)Box!!',
3868
+ 45 => '(Xiaomi|Xiaomi Mi|MI)TV!!',
3869
+ 46 => '(ZTE )?(Grand|Mimosa)!!',
 
 
 
 
 
 
 
 
3870
  ),
3871
  '@MK' =>
3872
  array (
3909
  13 => 'MOGU!!',
3910
  14 => 'moii!!',
3911
  15 => 'MORAL N01',
3912
+ 16 => 'Moto Droid',
3913
+ 17 => 'Motorola Pro XT610',
3914
+ 18 => 'Motorola Milestone MAXX',
3915
+ 19 => 'Motorola Backflip Me600',
3916
+ 20 => 'Moto ME860',
3917
+ 21 => 'Moto C',
3918
+ 22 => 'Moto C Plus',
3919
+ 23 => '(Moto)?E2$!',
3920
+ 24 => '(Moto)?E2\\(4G-LTE\\)$!',
3921
+ 25 => 'Motorola MotoE2!',
3922
+ 26 => 'Moto E (4)',
3923
+ 27 => 'Moto E (4) Plus',
3924
+ 28 => 'moto e5 cruise',
3925
+ 29 => '(Moto)?G3$!',
3926
+ 30 => '(Moto)?G3-TE$!',
3927
+ 31 => 'MOTOROLA MOTOG',
3928
+ 32 => 'Moto G Play',
3929
+ 33 => 'Moto G4',
3930
+ 34 => 'Moto G (4)',
3931
+ 35 => 'Moto G4 Plus',
3932
+ 36 => 'Moto G (5)',
3933
+ 37 => 'Moto G (5) Plus',
3934
+ 38 => 'Moto G (5S) Plus',
3935
+ 39 => 'moto g(6)',
3936
+ 40 => 'moto g(6) plus',
3937
+ 41 => 'Moto Z (2)',
3938
+ 42 => 'Moto Z2 Play',
3939
+ 43 => 'Moto X Pro',
3940
+ 44 => 'moto x4',
3941
+ 45 => 'Moto Backflip',
3942
+ 46 => 'MOTOROLA XOOM MZ606',
3943
+ 47 => 'MOTOROLA RAZR',
3944
+ 48 => 'MOTWX435KT',
3945
+ 49 => '(PLOYER-)?MOMO!!',
3946
+ 50 => 'MOB-5045',
3947
+ 51 => 'Mobii 7',
3948
+ 52 => 'MoFing',
3949
+ 53 => 'mocha',
3950
+ 54 => 'MO-01J',
3951
+ 55 => 'MO-01K',
3952
+ 56 => 'Movistar Express',
3953
+ 57 => 'Movistar Link',
3954
+ 58 => 'Movistar Motion',
3955
+ 59 => 'Movistar Prime',
3956
+ 60 => 'MOVE',
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3957
  ),
3958
  '@MP' =>
3959
  array (
3977
  17 => 'MPQC804HD',
3978
  18 => 'MPQC1010',
3979
  ),
 
 
 
 
3980
  '@MS' =>
3981
  array (
3982
  0 => 'MStar Amber3',
4033
  28 => 'mt8580!',
4034
  29 => 'mt8658!',
4035
  30 => '(AC|BC|LC|MT|RC|QS|VM|TS|OC)[0-9]{4,4}[A-Z]!!',
4036
+ 31 => '(HUAWEI )?(ALP|BLA|CRR|LON|MATE|MHA|MT1|MT2|MT7|M200|NXT|Z100)!!',
4037
  32 => 'MTC Android',
4038
  33 => 'MT791',
4039
  34 => 'MT70[0-9]{2,2}!!',
4244
  ),
4245
  '@NC' =>
4246
  array (
4247
+ 0 => '(HW-|HUAWEI )?(DRA|FLA|TIT|TAG|NCE|TRT|SLA)!!',
4248
  ),
4249
  '@NE' =>
4250
  array (
4281
  30 => '(BLU|DASH|LIFE|NEO|STUDIO|VIVO)!!',
4282
  31 => 'NexusHD2',
4283
  32 => 'Nexus HD2',
4284
+ 33 => '(HW-|HUAWEI |HONOR )?(ATH|BLN|BKL|BND|CHE|CHM|COL|DUA|DUK|DLI|EDI|FRD|HN3|H30|H60|HOL|JMM|KIW|LLD|NEM|NMO|PE|PLK|RNE|SCL|KNT|CAM|STF|HDN)!!',
4285
  34 => 'Neon7',
4286
  35 => 'Neon9',
4287
  36 => '(NetTab|NT-)!!',
4372
  ),
4373
  '@NM' =>
4374
  array (
4375
+ 0 => '(HW-|HUAWEI |HONOR )?(ATH|BLN|BKL|BND|CHE|CHM|COL|DUA|DUK|DLI|EDI|FRD|HN3|H30|H60|HOL|JMM|KIW|LLD|NEM|NMO|PE|PLK|RNE|SCL|KNT|CAM|STF|HDN)!!',
4376
  1 => '(NMP|MBR|XDK|XDS|XMP)\\-!!',
4377
  ),
4378
  '@NO' =>
4432
  52 => 'Now',
4433
  53 => 'NO1 S6',
4434
  54 => 'NOAIN!!',
4435
+ 55 => 'Nokia N9',
4436
+ 56 => 'Nokia N900',
4437
+ 57 => 'Nokia X',
4438
+ 58 => 'Nokia X Dual SIM',
4439
+ 59 => 'Nokia X+',
4440
+ 60 => 'Nokia Xplus',
4441
+ 61 => 'Nokia XL 4G',
4442
+ 62 => 'Nokia XL',
4443
+ 63 => 'Nokia XL Dual SIM',
4444
+ 64 => 'Nokia X2',
4445
+ 65 => 'NokiaX2DS',
4446
+ 66 => 'Notion Ink ADAM',
4447
+ 67 => 'Note III',
4448
+ 68 => 'Nozomi',
4449
+ 69 => 'Noble TAB07-485',
4450
+ 70 => '(QMobile|QTab|Q-Smart|Noir)!!',
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4451
  ),
4452
  '@NP' =>
4453
  array (
4481
  ),
4482
  '@NX' =>
4483
  array (
4484
+ 0 => '(HUAWEI )?(ALP|BLA|CRR|LON|MATE|MHA|MT1|MT2|MT7|M200|NXT|Z100)!!',
4485
  1 => '(Nexian )?NX-A[0-9]{3,3}!!',
4486
  2 => 'NXA8QC116',
4487
  3 => 'NX16A8116K',
4515
  '@OB' =>
4516
  array (
4517
  0 => 'OB-OPPO A31c',
4518
+ 1 => 'OB-OPPO 3005',
4519
+ 2 => 'Obreey SURFpad',
 
 
 
 
4520
  ),
4521
  '@OC' =>
4522
  array (
4709
  138 => 'ONEPLUS A5000',
4710
  139 => 'ONEPLUS A5010',
4711
  140 => 'ONEPLUS A6000',
4712
+ 141 => 'ONE E1000',
4713
+ 142 => 'ONE E1001',
4714
+ 143 => 'ONE E1003',
4715
+ 144 => 'ONE E1005',
4716
+ 145 => 'ONDA MID',
4717
+ 146 => 'ONDA A9 Core4',
4718
+ 147 => 'ONDA VI10',
4719
+ 148 => 'Onda V812',
4720
+ 149 => 'ONDA v975m',
4721
+ 150 => 'ONDA V989',
4722
+ 151 => 'ONDA V989 Core8',
 
 
 
4723
  ),
4724
  '@OP' =>
4725
  array (
4728
  2 => 'Opus One',
4729
  3 => 'OPS-DRD Digital Signage Player',
4730
  4 => 'OP110',
4731
+ 5 => 'OPPO A30',
4732
+ 6 => 'OPPO A31',
4733
+ 7 => 'OPPO A31t',
4734
+ 8 => 'OPPO A33',
4735
+ 9 => 'OPPO A33m',
4736
+ 10 => 'OPPO A37m',
4737
+ 11 => 'OPPO A53',
4738
+ 12 => 'OPPO A53m',
4739
+ 13 => 'OPPO A57',
4740
+ 14 => 'OPPO A57t',
4741
+ 15 => 'OPPO A59m',
4742
+ 16 => 'OPPO A59s',
4743
+ 17 => 'OPPO A59st',
4744
+ 18 => 'OPPO A77',
4745
+ 19 => 'OPPO A77t',
4746
+ 20 => 'OPPO A800',
4747
+ 21 => 'OPPOX905',
4748
+ 22 => 'OPPOX907',
4749
+ 23 => 'OPPO Find5',
4750
+ 24 => 'OPPOX909',
4751
+ 25 => 'OPPO X909',
4752
+ 26 => 'OPPOX9015',
4753
+ 27 => 'OPPOX9017',
4754
+ 28 => 'OPPO find7',
4755
+ 29 => 'OPPOR601',
4756
+ 30 => 'OPPOR801',
4757
+ 31 => 'OPPOR803',
4758
+ 32 => 'OPPOR805',
4759
+ 33 => 'OPPOR807',
4760
+ 34 => 'OPPO R811',
4761
+ 35 => 'OPPO R813T',
4762
+ 36 => 'OPPO R815',
4763
+ 37 => 'OPPOR817',
4764
+ 38 => 'Oppo R819',
4765
+ 39 => 'OPPO R821',
4766
+ 40 => 'OPPO R831',
4767
+ 41 => 'Oppo R831 Limited Edition',
4768
+ 42 => 'OPPO R1001',
4769
+ 43 => 'OPPOR8015',
4770
+ 44 => 'OPPOR8111',
4771
+ 45 => 'OPPOT29',
4772
+ 46 => '(OPPO-?)?T703!',
4773
+ 47 => 'OPPOU701',
4774
+ 48 => 'OPPOU7011',
4775
+ 49 => 'OPPOU7015',
4776
+ 50 => 'OPPO N1',
4777
+ 51 => 'OPPO R7',
4778
+ 52 => 'OPPO R7s',
4779
+ 53 => 'OPPO R7sm',
4780
+ 54 => 'OPPO R7st',
4781
+ 55 => 'OPPO R7t',
4782
+ 56 => 'OPPO R9m',
4783
+ 57 => 'OPPO R9tm',
4784
+ 58 => 'OPPO R9km',
4785
+ 59 => 'OPPO R9s',
4786
+ 60 => 'OPPO R9sk',
4787
+ 61 => 'OPPO R9st',
4788
+ 62 => 'OPPO R9t',
4789
+ 63 => 'OPPO R11',
4790
+ 64 => 'OPPO R11t',
4791
+ 65 => 'OPPO R7 Plus',
4792
+ 66 => 'OPPO R7sPlus',
4793
+ 67 => 'OPPO R9 Plusm A',
4794
+ 68 => 'OPPO R9 Plustm A',
4795
+ 69 => 'OPPO R9s Plus',
4796
+ 70 => 'OPPO R11 Plus',
4797
+ 71 => 'OPPO R11 Plusk',
4798
+ 72 => 'OPPO R11 Pluskt',
4799
+ 73 => 'OPPO R11s Plus',
4800
+ 74 => 'OPSSON!!',
4801
+ 75 => 'OP0118-12',
4802
+ 76 => 'Optimus Barcelona',
4803
+ 77 => 'Optimus Boston',
4804
+ 78 => 'Optimus Madrid',
4805
+ 79 => 'Optimus Monte Carlo',
4806
+ 80 => 'Optimus San Francisco',
4807
+ 81 => 'Optimus San Remo',
4808
+ 82 => 'Optimus Zali',
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4809
  ),
4810
  '@OR' =>
4811
  array (
4857
  array (
4858
  0 => '(OV-|Overmax|Vertis)!!',
4859
  ),
 
 
 
 
4860
  '@OY' =>
4861
  array (
4862
  0 => 'Oysters Pacific 800',
4920
  array (
4921
  0 => 'P2A700',
4922
  1 => 'P2Lite',
4923
+ 2 => '(HW-|HUAWEI )?(ALE|ANE|D2|DAV|EML|EVA|FIG|G6|G7|GRA|M100|P2|P6|P7|PRA|RIO|SC|Sophia|VIE|VKY|VNS|VTR|WAS)!!',
4924
  ),
4925
  '@P3' =>
4926
  array (
4949
  2 => 'P6 Pro',
4950
  3 => 'P6 Qmax',
4951
  4 => 'P6 Quad',
4952
+ 5 => '(HW-|HUAWEI )?(ALE|ANE|D2|DAV|EML|EVA|FIG|G6|G7|GRA|M100|P2|P6|P7|PRA|RIO|SC|Sophia|VIE|VKY|VNS|VTR|WAS)!!',
4953
  ),
4954
  '@P7' =>
4955
  array (
4956
+ 0 => '(HW-|HUAWEI )?(ALE|ANE|D2|DAV|EML|EVA|FIG|G6|G7|GRA|M100|P2|P6|P7|PRA|RIO|SC|Sophia|VIE|VKY|VNS|VTR|WAS)!!',
4957
  1 => 'P700i',
4958
  2 => 'P701',
4959
  3 => 'P7',
5057
  15 => 'Patio100',
5058
  16 => 'Patio100 3G',
5059
  17 => 'PAD[0-9]{3,3}!!',
5060
+ 18 => 'Panasonic!!',
5061
+ 19 => 'pandigital9hr',
5062
+ 20 => 'pandigital9hr2',
5063
+ 21 => 'pandigitalopc1',
5064
+ 22 => 'pandigitalopp1',
5065
+ 23 => 'pandigitalp1hr',
5066
+ 24 => 'PantechP!!',
5067
+ 25 => 'PAT712W',
5068
+ 26 => 'PATG7506HD',
5069
+ 27 => 'PAP[0-9]{4,4}!!',
5070
+ 28 => 'PAD1001',
 
 
 
 
 
 
 
 
 
5071
  ),
5072
  '@PB' =>
5073
  array (
5074
  0 => 'PB99400',
 
 
 
 
 
 
 
 
5075
  ),
5076
  '@PC' =>
5077
  array (
5079
  1 => '(DNS )?(Airtab )?(E|ES|M|MA|MC|MF|MW|P|PC|PF)[0-9]{2,4}!!',
5080
  2 => '(HTC|PCD|USCC)?ADR[0-9]{4,4}!!',
5081
  3 => 'PC36100!',
5082
+ 4 => 'PC-TE307N1W',
5083
+ 5 => 'PC-TE508BAW',
5084
+ 6 => 'PC-TS508FAM',
5085
+ 7 => 'PC-TS508T1W',
5086
+ 8 => 'PC-TS708T1W',
 
 
 
 
 
5087
  ),
5088
  '@PD' =>
5089
  array (
5092
  ),
5093
  '@PE' =>
5094
  array (
5095
+ 0 => '(HW-|HUAWEI |HONOR )?(ATH|BLN|BKL|BND|CHE|CHM|COL|DUA|DUK|DLI|EDI|FRD|HN3|H30|H60|HOL|JMM|KIW|LLD|NEM|NMO|PE|PLK|RNE|SCL|KNT|CAM|STF|HDN)!!',
5096
  1 => 'PEDI',
5097
  2 => 'Penta!!',
5098
  3 => 'Pentagram!!',
5185
  3 => 'Pixel 2',
5186
  4 => 'Pixel 2XL',
5187
  5 => 'Pixel 2 XL',
5188
+ 6 => '(Axioo[\\- ])?PICO!!',
5189
+ 7 => 'picoBit-L',
5190
+ 8 => '(GIO-)?(GiONEE[- ])?Pioneer P1!',
5191
+ 9 => '(GIO-)?(GiONEE[- ])?Pioneer P2!',
5192
+ 10 => '(GIO-)?(GiONEE[- ])?Pioneer P3!',
5193
+ 11 => '(GIO-)?(GiONEE[- ])?Pioneer P4!',
5194
+ 12 => 'PixelV1',
5195
+ 13 => 'Pixel V2',
5196
+ 14 => 'Pixel V2+',
5197
+ 15 => 'PI2000',
5198
+ 16 => 'PI2010',
5199
+ 17 => 'PI2011',
5200
+ 18 => 'PI3100',
5201
+ 19 => 'PI3100-93',
5202
+ 20 => 'PI3100Z3 93',
5203
+ 21 => 'PI3105',
5204
+ 22 => 'PI3106',
5205
+ 23 => 'PI3110',
5206
+ 24 => 'PI3205G',
5207
+ 25 => 'PI3210G',
5208
+ 26 => 'PI3900',
5209
+ 27 => 'PI3900-93',
5210
+ 28 => 'PI3910',
5211
+ 29 => 'PI4010G',
5212
+ 30 => 'PI7000',
5213
+ 31 => 'PI7100 93',
5214
+ 32 => '(PNR-)?Pioneer!!',
5215
+ 33 => 'PIRANHA!!',
 
 
 
 
 
 
5216
  ),
5217
  '@PJ' =>
5218
  array (
5223
  array (
5224
  0 => 'PLE-701L',
5225
  1 => 'PLE-703L',
5226
+ 2 => '(HW-|HUAWEI |HONOR )?(ATH|BLN|BKL|BND|CHE|CHM|COL|DUA|DUK|DLI|EDI|FRD|HN3|H30|H60|HOL|JMM|KIW|LLD|NEM|NMO|PE|PLK|RNE|SCL|KNT|CAM|STF|HDN)!!',
5227
  3 => 'Planet II v2',
5228
  4 => 'PLANET',
5229
  5 => 'Playboy PB-S3',
5256
  '@PO' =>
5257
  array (
5258
  0 => '(Highscreen|Alpha|Bay|Boost|Cosmo|Explosion|Power|Prime|Zera)!!',
5259
+ 1 => 'PocketBook A7',
5260
+ 2 => 'PocketBook A10',
5261
+ 3 => 'PocketBook A10 3G',
5262
+ 4 => 'PocketBook SURFpad2',
5263
+ 5 => 'PocketBook SURFpad 3 (7,85")',
5264
+ 6 => 'PocketBook SURFpad 4 S',
5265
+ 7 => 'PocketBook SURFpad 4 M',
5266
+ 8 => 'PocketBook SURFpad 4 L',
5267
+ 9 => 'POV-Mobii-7',
5268
+ 10 => 'POV Mobii 7',
5269
+ 11 => 'POV TAB-P506!',
5270
+ 12 => 'POV TAB-P517!',
5271
+ 13 => 'POV TAB-P527!',
5272
+ 14 => 'POV TAB-P629!',
5273
+ 15 => 'POV TAB-P701!',
5274
+ 16 => 'POV TAB-P703!',
5275
+ 17 => 'POV TAB-P720!',
5276
+ 18 => 'POV TAB-P721A!',
5277
+ 19 => 'POV TAB-P721!',
5278
+ 20 => 'POV TAB-P722C!',
5279
+ 21 => 'POV TAB-P731N!',
5280
+ 22 => 'POV TAB-P825!',
5281
+ 23 => 'POV TAB-P925!',
5282
+ 24 => 'POV TAB-PR945!',
5283
+ 25 => 'POV TAB-P1025!',
5284
+ 26 => 'POV TAB-P1030!',
5285
+ 27 => 'POV TAB-PI1045!',
5286
+ 28 => 'POV TAB-P1325!',
5287
+ 29 => '(POV )?TAB-PLAYTABPRO!',
5288
+ 30 => '(POV )?TAB-PROTAB25!',
5289
+ 31 => '(POV )?TAB-PROTAB26!',
5290
+ 32 => 'POV TAB-PROTAB27',
5291
+ 33 => '(POV )?TAB-PROTAB30!',
5292
+ 34 => '(POV )?TAB-PROTAB2XXL(4)!',
5293
+ 35 => '(POV )?TAB NAVI7 3G M!',
5294
+ 36 => 'POV_TAB-NAVI7-3G-M',
5295
+ 37 => 'POV TAB-P547(v1.0)',
5296
+ 38 => 'POV TV-HDMI-200BT',
5297
+ 39 => 'POV TV-HDMI-200BT(V2.0)',
5298
+ 40 => 'POV TV-HDMI-210',
5299
+ 41 => 'POV TV-HDMI-KB-01',
5300
+ 42 => 'POV TV-SMARTTV-500',
5301
+ 43 => 'Polaroid PSPT401',
5302
+ 44 => 'Polaroid PSPC505',
5303
+ 45 => 'Polaroid PSPC550',
5304
+ 46 => 'Polaroid P4005A',
5305
+ 47 => 'Polaroid P5005A',
5306
+ 48 => 'Polaroid P5046A',
5307
+ 49 => 'Polaroid P5525A',
5308
+ 50 => 'Polaroid P5526A',
5309
+ 51 => 'POLY ?PAD!!',
5310
+ 52 => 'POLYTRON!!',
5311
+ 53 => 'POMP!!',
5312
+ 54 => 'Positivo Mini',
5313
+ 55 => 'POSITIVO YPY 07FTB',
5314
+ 56 => 'Positivo Ypy AB7E',
5315
+ 57 => 'Positivo Ypy AB7EC',
5316
+ 58 => 'Positivo Ypy AB7F',
5317
+ 59 => 'Positivo AB7F',
5318
+ 60 => 'Positivo Ypy AB7H',
5319
+ 61 => 'Positivo Ypy AB10E',
5320
+ 62 => 'Positivo Ypy AB10EC',
5321
+ 63 => 'Positivo Ypy AB10H',
5322
+ 64 => 'Positivo BGH Ypy L700',
5323
+ 65 => 'Positivo Ypy L700',
5324
+ 66 => 'Positivo Ypy L700 Ed. Especial',
5325
+ 67 => 'Positivo Ypy L700+',
5326
+ 68 => 'Positivo Ypy L700 Kids',
5327
+ 69 => 'Positivo BGH Ypy L700 Kids',
5328
+ 70 => 'Positivo Ypy L700+ Kids',
5329
+ 71 => 'Positivo Ypy L1000',
5330
+ 72 => 'Positivo Ypy L1000AB',
5331
+ 73 => 'Positivo Ypy L1000F',
5332
+ 74 => 'Positivo Ypy L1050',
5333
+ 75 => 'Positivo Ypy L1050E',
5334
+ 76 => 'Positivo Ypy L1050F',
5335
+ 77 => 'Positivo S380',
5336
+ 78 => 'Positivo S440',
5337
+ 79 => 'Positivo S480',
5338
+ 80 => 'Positivo S550',
5339
+ 81 => 'Positivo X400',
5340
+ 82 => 'Positivo X800',
 
 
5341
  ),
5342
  '@PP' =>
5343
  array (
5348
  array (
5349
  0 => 'Project Tango Tablet Development Kit',
5350
  1 => '(Highscreen|Alpha|Bay|Boost|Cosmo|Explosion|Power|Prime|Zera)!!',
5351
+ 2 => '(HW-|HUAWEI )?(ALE|ANE|D2|DAV|EML|EVA|FIG|G6|G7|GRA|M100|P2|P6|P7|PRA|RIO|SC|Sophia|VIE|VKY|VNS|VTR|WAS)!!',
5352
  3 => 'Pro 10 dual core',
5353
  4 => 'Prada 3.0',
5354
  5 => 'PRO 5',
5637
  3 => 'R7i',
5638
  4 => 'R7kf',
5639
  5 => 'R7sf',
5640
+ 6 => 'R7Plus',
5641
+ 7 => 'R7plusf',
5642
+ 8 => 'R7Plusm',
 
5643
  ),
5644
  '@R8' =>
5645
  array (
5786
  2 => 'Rikomagic MK802III',
5787
  3 => 'Rikomagic MK802IIIS',
5788
  4 => '(Gsmart|Gigabyte|Rio)!!',
5789
+ 5 => '(HW-|HUAWEI )?(ALE|ANE|D2|DAV|EML|EVA|FIG|G6|G7|GRA|M100|P2|P6|P7|PRA|RIO|SC|Sophia|VIE|VKY|VNS|VTR|WAS)!!',
5790
  6 => 'Rise',
5791
  7 => '(Ritmix )?RM[DP]-?[0-9]{3,3}!!',
5792
  8 => 'RIDGE',
5836
  ),
5837
  '@RN' =>
5838
  array (
5839
+ 0 => '(HW-|HUAWEI |HONOR )?(ATH|BLN|BKL|BND|CHE|CHM|COL|DUA|DUK|DLI|EDI|FRD|HN3|H30|H60|HOL|JMM|KIW|LLD|NEM|NMO|PE|PLK|RNE|SCL|KNT|CAM|STF|HDN)!!',
5840
  ),
5841
  '@RO' =>
5842
  array (
5959
  ),
5960
  '@SC' =>
5961
  array (
5962
+ 0 => '(HW-|HUAWEI |HONOR )?(ATH|BLN|BKL|BND|CHE|CHM|COL|DUA|DUK|DLI|EDI|FRD|HN3|H30|H60|HOL|JMM|KIW|LLD|NEM|NMO|PE|PLK|RNE|SCL|KNT|CAM|STF|HDN)!!',
5963
+ 1 => '(HW-|HUAWEI )?(ALE|ANE|D2|DAV|EML|EVA|FIG|G6|G7|GRA|M100|P2|P6|P7|PRA|RIO|SC|Sophia|VIE|VKY|VNS|VTR|WAS)!!',
5964
+ 2 => '(HW-|HUAWEI )?(CRO|LUA|CUN|SCC|SCU|CAM|LDN|LYO|MYA)!!',
5965
+ 3 => 'SCH-[iI][0-9]{3,3}!!',
5966
+ 4 => 'SCH-L710!',
5967
+ 5 => 'SCH-M828!',
5968
+ 6 => 'SCH-N719',
5969
+ 7 => 'SCH-P[0-9]{3,3}!!',
5970
+ 8 => 'SCH-R[0-9]{3,3}!!',
5971
+ 9 => 'SCH-S[0-9]{3,3}!!',
5972
+ 10 => 'SCH-V727',
5973
+ 11 => 'SCH-W[0-9]{3,4}!!',
5974
+ 12 => 'SC-?0[0-9][A-Z]!!',
5975
+ 13 => 'SC[LTV][23][0-9]!!',
5976
+ 14 => 'Scroll!!',
5977
+ 15 => 'SC-!!',
5978
+ 16 => 'scorpio',
 
5979
  ),
5980
  '@SD' =>
5981
  array (
6063
  0 => 'Slider SL101',
6064
  1 => 'SL930',
6065
  2 => '(HP|Slate)!!',
6066
+ 3 => '(HW-|HUAWEI )?(DRA|FLA|TIT|TAG|NCE|TRT|SLA)!!',
6067
  4 => 'Slidepad!!',
6068
  5 => 'SLIDE',
6069
  ),
6093
  21 => 'SM-A[0-9]{3,3}!!',
6094
  22 => 'SM-C[0-9]{3,3}!!',
6095
  23 => 'SM-E[0-9]{3,3}!!',
6096
+ 24 => 'SM-G[0-9]{3,3}!!',
6097
+ 25 => 'SM-I9500',
6098
+ 26 => 'SM-J[0-9]{3,3}!!',
6099
+ 27 => 'SM-N[0-9]{3,4}!!',
6100
+ 28 => 'SM-P[0-9]{3,3}!!',
6101
+ 29 => 'SM-S[0-9]{3,3}!!',
6102
+ 30 => 'SM-T[0-9]{3,3}!!',
6103
+ 31 => 'SM-V700',
6104
+ 32 => 'SM-W[0-9]{4,4}!!',
6105
+ 33 => 'Smartphone Android by SFR STARADDICT II',
6106
+ 34 => '(Smartfren|Andromax)!!',
6107
+ 35 => 'Smartfren Tab 7',
6108
+ 36 => 'SM919',
6109
+ 37 => 'SM701',
6110
+ 38 => 'SM801',
6111
+ 39 => 'SmartQ!!',
6112
+ 40 => 'SMART Sprint',
6113
+ 41 => 'SMART Start',
6114
+ 42 => 'SMART Surf2 4G',
6115
+ 43 => 'SmartTab!!',
 
 
6116
  ),
6117
  '@SN' =>
6118
  array (
6119
  0 => 'SN[0-9]!!',
6120
+ 1 => 'Snexian!!',
6121
+ 2 => '(SNM\\-)?LT[0-9]{2,2}[a-z]?!!',
6122
+ 3 => '(SNM\\-)?M[0-9]{2,2}[a-z]!!',
 
6123
  ),
6124
  '@SO' =>
6125
  array (
6133
  7 => 'Softwinerf900',
6134
  8 => 'SoftwinerEvbV13',
6135
  9 => 'soho',
6136
+ 10 => '(HW-|HUAWEI )?(ALE|ANE|D2|DAV|EML|EVA|FIG|G6|G7|GRA|M100|P2|P6|P7|PRA|RIO|SC|Sophia|VIE|VKY|VNS|VTR|WAS)!!',
6137
  11 => 'SONIC',
6138
  12 => 'Sonim!!',
6139
  13 => 'SO-0[0-9][A-Z]!!',
6199
  12 => 'ST7001',
6200
  13 => 'ST8000',
6201
  14 => 'ST9001',
6202
+ 15 => '(HW-|HUAWEI |HONOR )?(ATH|BLN|BKL|BND|CHE|CHM|COL|DUA|DUK|DLI|EDI|FRD|HN3|H30|H60|HOL|JMM|KIW|LLD|NEM|NMO|PE|PLK|RNE|SCL|KNT|CAM|STF|HDN)!!',
6203
+ 16 => 'ST10',
6204
+ 17 => 'ST940I-UP',
6205
+ 18 => 'STM[0-9]{3,3}H!!',
6206
+ 19 => 'Stylo',
6207
+ 20 => 'STARACTIVE',
6208
+ 21 => 'STARACTIVE 2',
6209
+ 22 => 'STARADDICT II',
6210
+ 23 => 'STARADDICT II Plus',
6211
+ 24 => 'STARADDICT III',
6212
+ 25 => 'STARADDICT 4',
6213
+ 26 => 'STARADDICT 5',
6214
+ 27 => 'STARADDICT 6',
6215
+ 28 => 'STARNAUTE II',
6216
+ 29 => 'STARNAUTE 3',
6217
+ 30 => 'STARNAUTE3',
6218
+ 31 => 'STARNAUTE4',
6219
+ 32 => 'Starshine',
6220
+ 33 => 'STARSHINE II',
6221
+ 34 => 'STARSHINE III',
6222
+ 35 => 'STARSHINE 4',
6223
+ 36 => 'STARSHINE5',
6224
+ 37 => 'STARTEXT II',
6225
+ 38 => 'STARTRAIL II',
6226
+ 39 => 'StarTrail III',
6227
+ 40 => 'STARTRAIL4',
6228
+ 41 => 'STARTRAIL 4',
6229
+ 42 => 'STARTRAIL5',
6230
+ 43 => 'STARTRAIL 6 4G',
6231
+ 44 => 'STARTRAIL6',
6232
+ 45 => 'STARTRAIL7',
6233
+ 46 => 'STARTRAIL 8',
6234
+ 47 => 'STARTRAIL 9',
6235
+ 48 => 'STARXTREM',
6236
+ 49 => 'STARXTREM II',
6237
+ 50 => 'STARXTREM3',
6238
+ 51 => 'STARXTREM 4',
6239
+ 52 => 'STARXTREM5',
6240
+ 53 => 'STARXTREM 6',
6241
+ 54 => 'STARTAB',
6242
+ 55 => 'ST[0-9]{2,2}[a-z]?!!',
6243
+ 56 => 'Star N8000',
6244
+ 57 => 'Star N9500',
6245
+ 58 => 'Star N9589',
6246
+ 59 => 'Star Q9000',
6247
+ 60 => 'STAR S5',
6248
+ 61 => 'STAR S7589',
6249
+ 62 => 'Starmobile!!',
6250
+ 63 => '(Starway )?Andromeda!!',
6251
+ 64 => 'STX!!',
6252
+ 65 => 'STOREX LinkBox',
6253
+ 66 => 'StarTab 715x',
6254
+ 67 => 'ST[0-9]{5,5}-[0-9]!!',
6255
+ 68 => 'ST-PAD',
6256
+ 69 => 'ST-PAD2',
6257
+ 70 => 'STAIRWAY',
6258
+ 71 => 'StarTrail TT',
 
6259
  ),
6260
  '@SU' =>
6261
  array (
6401
  5 => 'Tablet-P27',
6402
  6 => 'TA10CA3',
6403
  7 => '(tablet )?fnac!!',
6404
+ 8 => '(HW-|HUAWEI )?(DRA|FLA|TIT|TAG|NCE|TRT|SLA)!!',
6405
+ 9 => '(HW-|HUAWEI )?(BLL|CHC|TAG|KII)!!',
6406
+ 10 => 'TA-FONE!!',
6407
+ 11 => 'TAB1011',
6408
+ 12 => 'TAB-1030',
6409
+ 13 => '(Lenovo )?(Tab ?)?(2 ?)?[AS](7|8|10)!!',
6410
+ 14 => 'TAB950',
6411
+ 15 => 'TAB1062',
6412
+ 16 => 'TAB192',
6413
+ 17 => 'TA-10(07|29)!',
6414
+ 18 => 'TA-10(84)!',
6415
+ 19 => 'TA-10(20|28|32|38)!',
6416
+ 20 => 'TA-10(24|27|44|53)!',
6417
+ 21 => 'TA-10(61|75|81|88)!',
6418
+ 22 => 'TA-10(00|03|21|25|33|39)!',
6419
+ 23 => 'TA-10(43|50|54|68)!',
6420
+ 24 => 'TA-10(41)!',
6421
+ 25 => 'TA-10(62)!',
6422
+ 26 => 'TA-10(04|12|52)!',
6423
+ 27 => 'TA-10(99)!',
6424
+ 28 => 'TA-11(03|16)!',
6425
+ 29 => '(POV )?TAB-PLAYTABPRO!',
6426
+ 30 => '(POV )?TAB-PROTAB25!',
6427
+ 31 => '(POV )?TAB-PROTAB26!',
6428
+ 32 => '(POV )?TAB-PROTAB30!',
6429
+ 33 => 'TAB-PROTAB2-IPS9',
6430
+ 34 => 'TAB-PROTAB2-IPS-3G',
6431
+ 35 => 'TAB-PROTAB2-IPS-16',
6432
+ 36 => 'TAB-PROTAB2.4',
6433
+ 37 => 'TAB-PROTAB2XL',
6434
+ 38 => 'TAB-PROTAB2.4XL',
6435
+ 39 => 'TAB-PROTAB2XXL',
6436
+ 40 => 'TAB-PROTAB2XXL(4)',
6437
+ 41 => '(POV )?TAB-PROTAB2XXL(4)!',
6438
+ 42 => '(POV )?TAB NAVI7 3G M!',
6439
+ 43 => 'Tablet P',
6440
+ 44 => 'Tablet S',
6441
+ 45 => 'Tabra QAV801',
6442
+ 46 => 'TAB 7 3G V8',
6443
+ 47 => 'TAB 8 3G V8',
6444
+ 48 => 'TAB9 3G',
6445
+ 49 => 'TAB9 3G V8',
6446
+ 50 => 'TAB 10 3G V16',
6447
+ 51 => 'TAB 7i 3G',
6448
+ 52 => 'TAB 10Q',
6449
+ 53 => 'TAB09-410',
6450
+ 54 => 'TAB10-410',
6451
+ 55 => 'TAB07-485',
6452
+ 56 => 'TAB07-200',
6453
+ 57 => 'TAB9-200',
6454
+ 58 => 'TAB10-201',
6455
+ 59 => 'TAB210',
6456
+ 60 => 'TAB220',
6457
+ 61 => 'TAB224',
6458
+ 62 => 'TAB250',
6459
+ 63 => 'TAB275',
6460
+ 64 => 'TAB260',
6461
+ 65 => 'TAB264',
6462
+ 66 => 'TAB360',
6463
+ 67 => 'TAB364',
6464
+ 68 => 'TAB410',
6465
+ 69 => 'TAB411',
6466
+ 70 => 'TAB420',
6467
+ 71 => 'TAB424',
6468
+ 72 => 'TAB450',
6469
+ 73 => 'TAB460',
6470
+ 74 => 'TAB461',
6471
+ 75 => 'TAB464',
6472
+ 76 => 'TAB465EUK',
6473
+ 77 => 'TAB468',
6474
+ 78 => 'TAB469',
6475
+ 79 => 'TAB466EUK',
6476
+ 80 => 'TAB467',
6477
+ 81 => 'TAB462',
 
6478
  ),
6479
  '@TB' =>
6480
  array (
6582
  array (
6583
  0 => 'Tilapia',
6584
  1 => 'Titan TV S320',
6585
+ 2 => '(HW-|HUAWEI )?(DRA|FLA|TIT|TAG|NCE|TRT|SLA)!!',
6586
  3 => '(Karbonn|Titanium)!!',
6587
  4 => 'TI320-DU',
6588
  5 => 'TI320-DU TV',
6647
  49 => 'TM-1058',
6648
  50 => 'tmn!!',
6649
  ),
 
 
 
 
6650
  '@TO' =>
6651
  array (
6652
  0 => 'Toro',
6700
  14 => 'TR720F',
6701
  15 => 'TR10CS1',
6702
  16 => 'TripNiCE Pyramid',
6703
+ 17 => '(HW-|HUAWEI )?(DRA|FLA|TIT|TAG|NCE|TRT|SLA)!!',
6704
  18 => 'TR10RS1',
6705
  19 => '(KAZAM|Thunder|Tornado|Trooper)!!',
6706
  20 => 'Triumph',
7050
  20 => 'Vibo-A688',
7051
  21 => 'VitMod ExtraLite 1.6.5.fullodex for HTC HD7 Pro',
7052
  22 => 'Vivid 4G',
7053
+ 23 => '(HW-|HUAWEI )?(ALE|ANE|D2|DAV|EML|EVA|FIG|G6|G7|GRA|M100|P2|P6|P7|PRA|RIO|SC|Sophia|VIE|VKY|VNS|VTR|WAS)!!',
7054
  24 => 'Vibe K5 Plus',
7055
  25 => 'VIBE X2 (X2)',
7056
  26 => 'VIBE X3',
7102
  ),
7103
  '@VK' =>
7104
  array (
7105
+ 0 => '(HW-|HUAWEI )?(ALE|ANE|D2|DAV|EML|EVA|FIG|G6|G7|GRA|M100|P2|P6|P7|PRA|RIO|SC|Sophia|VIE|VKY|VNS|VTR|WAS)!!',
7106
  1 => 'VK410',
7107
  2 => 'VK700',
7108
  3 => 'VK810 4G',
7120
  ),
7121
  '@VN' =>
7122
  array (
7123
+ 0 => '(HW-|HUAWEI )?(ALE|ANE|D2|DAV|EML|EVA|FIG|G6|G7|GRA|M100|P2|P6|P7|PRA|RIO|SC|Sophia|VIE|VKY|VNS|VTR|WAS)!!',
7124
  ),
7125
  '@VO' =>
7126
  array (
7129
  2 => 'Volantisg',
7130
  3 => 'VOYAGER DG300',
7131
  4 => 'VOYAGER2 DG310',
7132
+ 5 => 'Vox',
7133
+ 6 => 'Vortex',
7134
+ 7 => 'vollo Vi86',
7135
+ 8 => 'VOTO GT2++',
7136
+ 9 => 'VOTO GT7',
7137
+ 10 => 'VOTO GT11',
7138
+ 11 => 'VOTO GT11 Pro',
7139
+ 12 => 'VOTO GT18',
7140
+ 13 => 'VOTO V5',
7141
+ 14 => 'VOTO VT868',
7142
+ 15 => 'VOTO VT888',
7143
+ 16 => 'VOTO VT898',
7144
+ 17 => 'VOTO VT898S',
7145
+ 18 => 'VOTO W5300',
7146
+ 19 => 'VOTO X2',
7147
+ 20 => 'VOYO A15',
7148
+ 21 => 'voyo X6',
7149
+ 22 => 'Vodafone!!',
 
7150
  ),
7151
  '@VS' =>
7152
  array (
7174
  ),
7175
  '@VT' =>
7176
  array (
7177
+ 0 => '(HW-|HUAWEI )?(ALE|ANE|D2|DAV|EML|EVA|FIG|G6|G7|GRA|M100|P2|P6|P7|PRA|RIO|SC|Sophia|VIE|VKY|VNS|VTR|WAS)!!',
7178
  1 => 'VT6078',
7179
  2 => 'VT75C',
7180
  3 => 'VT77C',
7269
  ),
7270
  '@WA' =>
7271
  array (
7272
+ 0 => '(HW-|HUAWEI )?(ALE|ANE|D2|DAV|EML|EVA|FIG|G6|G7|GRA|M100|P2|P6|P7|PRA|RIO|SC|Sophia|VIE|VKY|VNS|VTR|WAS)!!',
7273
  1 => 'WA-U420D',
7274
  2 => 'WALSUN S1 Pro',
7275
  3 => 'WALSUN S2',
7667
  2 => '(Xiaomi|Xiaomi Mi|MI) Note!!',
7668
  3 => '(Xiaomi )?(MI )?MAX$!',
7669
  4 => '(Xiaomi )?(MI )?MAX 2$!',
7670
+ 5 => '(Xiaomi )?(MI )?MIX$!',
7671
+ 6 => '(Xiaomi )?(MI )?MIX 2$!',
7672
+ 7 => '(Xiaomi )?(MI )?MIX 2S$!',
7673
+ 8 => '(Xiaomi )?20!!',
7674
+ 9 => '(Xiaomi )?(Redmi|RedRice|HM)!!',
7675
+ 10 => '(Xiaomi )?(Redmi|HM)[ \\-]?Note!!',
7676
+ 11 => '(Xiaomi |HM)?20!!',
7677
+ 12 => 'Xiaomi MDT2!',
7678
+ 13 => 'Xiaomi MCT1!',
7679
+ 14 => 'Xiaomi MAT136!',
7680
+ 15 => 'Xiaomi MBT6A5!',
7681
+ 16 => '(Xiaomi|Xiaomi Mi|MI) Pad!!',
7682
+ 17 => '(Xiaomi|Xiaomi Mi|MI)Box!!',
7683
+ 18 => '(Xiaomi|Xiaomi Mi|MI)TV!!',
 
7684
  ),
7685
  '@XL' =>
7686
  array (
7787
  0 => 'Y6 Max',
7788
  1 => 'Y6 Piano',
7789
  ),
 
 
 
 
7790
  '@YD' =>
7791
  array (
7792
  0 => 'YD201',
7970
  array (
7971
  0 => '(BB )?Z10$!',
7972
  1 => 'Z1-H39LW',
7973
+ 2 => '(HUAWEI )?(ALP|BLA|CRR|LON|MATE|MHA|MT1|MT2|MT7|M200|NXT|Z100)!!',
7974
  3 => 'Z1i',
7975
  ),
7976
  '@Z2' =>
includes/vendor/whichbrowser/parser/data/models-android.php CHANGED
@@ -261,17 +261,12 @@ DeviceModels::$ANDROID_MODELS = [
261
  'Pixel' => [ 'Google', 'Pixel' ],
262
  'Google Pixel' => [ 'Google', 'Pixel' ],
263
  'Pixel XL' => [ 'Google', 'Pixel XL' ],
 
264
  'Pixel 2' => [ 'Google', 'Pixel 2' ],
265
  'Google Pixel 2' => [ 'Google', 'Pixel 2' ],
266
  'Pixel 2XL' => [ 'Google', 'Pixel 2 XL' ],
267
  'Pixel 2 XL' => [ 'Google', 'Pixel 2 XL' ],
268
  'Google Pixel 2XL' => [ 'Google', 'Pixel 2 XL' ],
269
- 'Pixel 3' => [ 'Google', 'Pixel 3' ],
270
- 'Pixel 3 XL' => [ 'Google', 'Pixel 3 XL' ],
271
- 'Pixel 3a' => [ 'Google', 'Pixel 3a' ],
272
- 'Pixel 3a XL' => [ 'Google', 'Pixel 3a XL' ],
273
- 'Pixel 4' => [ 'Google', 'Pixel 4' ],
274
- 'Pixel 4 XL' => [ 'Google', 'Pixel 4 XL' ],
275
 
276
  /* Google Edition */
277
  'HTC One' => [ 'HTC', 'One (Google Edition)' ],
@@ -964,7 +959,7 @@ DeviceModels::$ANDROID_MODELS = [
964
  'one ?touch 4032!' => [ 'Alcatel', 'One Touch Pop C2' ],
965
  '4032[ADEX]!' => [ 'Alcatel', 'One Touch Pop C2' ],
966
  'one ?touch 4033!' => [ 'Alcatel', 'One Touch Pop C3' ],
967
- '4033[ADLX]!' => [ 'Alcatel', 'One Touch Pop C3' ],
968
  'ONETOUCH POPC3' => [ 'Alcatel', 'One Touch Pop C3' ],
969
  '4034[ADEFGX]!' => [ 'Alcatel', 'One Touch Pixi 4 (4)' ],
970
  'one ?touch 40(35|36|37)!' => [ 'Alcatel', 'One Touch Pop D3' ],
@@ -975,13 +970,10 @@ DeviceModels::$ANDROID_MODELS = [
975
  '4037[V]!' => [ 'Alcatel', 'One Touch Elevate' ],
976
  'one ?touch 5045!' => [ 'Alcatel', 'One Touch Pop 2 (4)' ],
977
  '4045[ADEFLOYX]!' => [ 'Alcatel', 'One Touch Pop 2 (4)' ],
978
- '4047[ADFGX]!' => [ 'Alcatel', 'U5' ],
979
- '4049[DG]!' => [ 'Alcatel', 'U3' ],
980
  '4055[JU]!' => [ 'Alcatel', 'One Touch Pixi 5 (4)' ],
981
  '4060[A]!' => [ 'Alcatel', 'IDEAL' ],
982
- '4060[SW]!' => [ 'Alcatel', 'One Touch Pixi 4 (5)' ],
983
  '5010[DEGSUX]!' => [ 'Alcatel', 'One Touch Pixi 4 (5)' ],
984
- '5011[A]!' => [ 'Alcatel', 'A3 Plus' ],
985
  '5012[G]!' => [ 'Alcatel', 'One Touch Pixi 4 (5.5)' ],
986
  '5015[ADEX]!' => [ 'Alcatel', 'One Touch Pixi 3 (5)' ],
987
  '5016[AJ]!' => [ 'Alcatel', 'One Touch Pixi 3 (5)' ],
@@ -996,45 +988,34 @@ DeviceModels::$ANDROID_MODELS = [
996
  'one ?touch 5021!' => [ 'Alcatel', 'One Touch Soleil' ],
997
  '5022[DEX]!' => [ 'Alcatel', 'One Touch Pop Star' ],
998
  '5023[F]!' => [ 'Alcatel', 'One Touch Pixi 4 Plus Power' ],
999
- '5024[D]!' => [ 'Alcatel', '1S' ],
1000
  '5025[DEGX]!' => [ 'Alcatel', 'One Touch Pop 3' ],
1001
  '5027[B]!' => [ 'Alcatel', 'One Touch Dawn' ],
1002
- '5033[ADJOX]!' => [ 'Alcatel', '1' ],
1003
- '5034[D]!' => [ 'Alcatel', '3L' ],
1004
  'one ?touch 5035!' => [ 'Alcatel', 'One Touch X\'Pop' ],
1005
  '5036[D]!' => [ 'Alcatel', 'One Touch Pop C5' ],
1006
  'one ?touch 50(36|37)!' => [ 'Alcatel', 'One Touch Pop C5' ],
1007
  'ONETOUCH POPC5' => [ 'Alcatel', 'One Touch Pop C5' ],
1008
  'one ?touch 50(38)!' => [ 'Alcatel', 'One Touch Pop D5' ],
1009
  '5038[ADEX]!' => [ 'Alcatel', 'One Touch Pop D5' ],
1010
- '5039[D]!' => [ 'Alcatel', 'One Touch 3L' ],
1011
- '5041[C]!' => [ 'Alcatel', 'TETRA' ],
1012
  'one ?touch 5042!' => [ 'Alcatel', 'One Touch Pop 2 (4.5)' ],
1013
  '5042[ADEFGTWXY]!' => [ 'Alcatel', 'One Touch Pop 2 (4.5)' ],
1014
- '5044[ADGIOSTY]!' => [ 'Alcatel', 'U5' ],
1015
- '5045[ADFGJTXY]!' => [ 'Alcatel', 'One Touch Pixi 4 (5.0)' ],
1016
- '5046[DGIJUY]!' => [ 'Alcatel', 'A3' ],
1017
- '5047[DIUY]!' => [ 'Alcatel', 'U5 HD' ],
1018
  '5049[EGSWZ]!' => [ 'Alcatel', 'A30 Fierce' ],
1019
  'one ?touch 5050!' => [ 'Alcatel', 'One Touch Pop S3' ],
1020
  '5050[ASYX]!' => [ 'Alcatel', 'One Touch Pop S3' ],
1021
  '5051[ADJMX]!' => [ 'Alcatel', 'One Touch Pop 4 (5.0)' ],
1022
- '5052[DY]!' => [ 'Alcatel', '3' ],
1023
- '5053[D]!' => [ 'Alcatel', '3 (2019)' ],
1024
  '5054[ADOSTX]!' => [ 'Alcatel', 'One Touch Pixi 3 (5.5)' ],
1025
  '5054[NW]!' => [ 'Alcatel', 'One Touch Fierce XL' ],
1026
- '5056[ADEINUWX]!' => [ 'Alcatel', 'One Touch Pop 4+' ],
1027
  '5056[O]!' => [ 'Alcatel', 'One Touch Allura' ],
1028
  '5057[M]!' => [ 'Alcatel', 'One Touch Pop Mirage' ],
1029
- '5058[I]!' => [ 'Alcatel', '3X' ],
1030
- '5059[ADJTXY]!' => [ 'Alcatel', '1X' ],
1031
- '5060[D]!' => [ 'Alcatel', '5V' ],
1032
  '5065[ADJNWX]!' => [ 'Alcatel', 'One Touch Pixi 3 (5)' ],
1033
  '5070[DJX]!' => [ 'Alcatel', 'One Touch Pop Star' ],
1034
- '5080[A]!' => [ 'Alcatel', 'Shine Lite' ],
1035
  '5080[DFQX]!' => [ 'Alcatel', 'One Touch Pixi 4 (6)' ],
1036
- '5085[CDJNOYX]!' => [ 'Alcatel', 'A5 LED' ],
1037
- '5086[ADY]!' => [ 'Alcatel', '5' ],
1038
  '5090[Y]!' => [ 'Alcatel', 'A7' ],
1039
  '5095[BIKY]!' => [ 'Alcatel', 'One Touch Pop 4S' ],
1040
  '5096[AI]!' => [ 'Alcatel', 'One Touch Net' ],
@@ -1069,9 +1050,6 @@ DeviceModels::$ANDROID_MODELS = [
1069
  'one ?touch 6050!' => [ 'Alcatel', 'One Touch Idol 2S' ],
1070
  '6050[AFWY]!' => [ 'Alcatel', 'One Touch Idol 2S' ],
1071
  '6055[ABDHIKPUY]!' => [ 'Alcatel', 'One Touch Idol 4' ],
1072
- '6058[D]!' => [ 'Alcatel', 'One Touch Idol 5' ],
1073
- '6060[S]!' => [ 'Alcatel', 'One Touch Idol 5s' ],
1074
- '6062[W]!' => [ 'Alcatel', '7' ],
1075
  '6070[KOY]!' => [ 'Alcatel', 'One Touch Idol 4s' ],
1076
  'one ?touch 7024!' => [ 'Alcatel', 'One Touch Fierce' ],
1077
  'one touch fierce!' => [ 'Alcatel', 'One Touch Fierce' ],
@@ -1321,8 +1299,9 @@ DeviceModels::$ANDROID_MODELS = [
1321
  'KFGIWI' => [ 'Amazon', 'Fire HD 8 (2016)', DeviceType::TABLET, Flag::FIREOS ], // xth generation 8" HD (1280 x 800)
1322
  'KFDOWI' => [ 'Amazon', 'Fire HD 8 (2017)', DeviceType::TABLET, Flag::FIREOS ], // xth generation 8" HD (1280 x 800)
1323
  'KFSUWI' => [ 'Amazon', 'Fire HD 10 (2017)', DeviceType::TABLET, Flag::FIREOS ], // 5th generation 10" HD (1280 x 800)
1324
- 'KFMAWI' => [ 'Amazon', 'Fire HD 8 (2018)', DeviceType::TABLET, Flag::FIREOS ],
1325
- 'KFMUWI' => [ 'Amazon', 'Fire 7 (2019)', DeviceType::TABLET, Flag::FIREOS ],
 
1326
  'SD4930UR' => [ 'Amazon', 'Fire Phone', DeviceType::MOBILE, Flag::FIREOS ],
1327
  'AFTB' => [ 'Amazon', 'Fire TV', DeviceType::TELEVISION, Flag::FIREOS ],
1328
  'AFTS' => [ 'Amazon', 'Fire TV (2015)', DeviceType::TELEVISION, Flag::FIREOS ],
@@ -1498,7 +1477,6 @@ DeviceModels::$ANDROID_MODELS = [
1498
  'Archos!!' => [
1499
  'ARCHOS 80G9' => [ 'Archos', '80 G9', DeviceType::TABLET ],
1500
  'ARCHOS 101G9' => [ 'Archos', '101 G9', DeviceType::TABLET ],
1501
- 'Archos G9' => [ 'Archos', '101 G9', DeviceType::TABLET ],
1502
  'ARCHOS 97XSLG10' => [ 'Archos', '97 XS', DeviceType::TABLET ],
1503
  'ARCHOS 80XSK' => [ 'Archos', '80 XS', DeviceType::TABLET ],
1504
  'ARCHOS 101G10' => [ 'Archos', '101 XS', DeviceType::TABLET ],
@@ -1661,7 +1639,6 @@ DeviceModels::$ANDROID_MODELS = [
1661
  'ARCHOS 97 XENON' => [ 'Archos', '97 Xenon', DeviceType::TABLET ],
1662
  'Archos 101 Xenon' => [ 'Archos', '101 Xenon', DeviceType::TABLET ],
1663
  'Archos 101 Xenon v2' => [ 'Archos', '101 Xenon', DeviceType::TABLET ],
1664
- 'Archos 101b Xenon' => [ 'Archos', '101b Xenon', DeviceType::TABLET ],
1665
  'Archos 101b Xenon v2' => [ 'Archos', '101b Xenon', DeviceType::TABLET ],
1666
  'Archos 101c Xenon' => [ 'Archos', '101c Xenon', DeviceType::TABLET ],
1667
  'ARCHOS 101 Xenon Lite' => [ 'Archos', '101 Xenon Lite', DeviceType::TABLET ],
@@ -1680,13 +1657,10 @@ DeviceModels::$ANDROID_MODELS = [
1680
  'Archos Access 70 3G' => [ 'Archos', 'Access 70', DeviceType::TABLET ],
1681
  'Archos Access 101 3G' => [ 'Archos', 'Access 101', DeviceType::TABLET ],
1682
  'Archos Access 101 3G V2' => [ 'Archos', 'Access 101', DeviceType::TABLET ],
1683
- 'Archos Core 50 4G' => [ 'Archos', 'Core 50' ],
1684
  'Archos Core 55 4G' => [ 'Archos', 'Core 55' ],
1685
  'Archos Core 70 3G' => [ 'Archos', 'Core 70', DeviceType::TABLET ],
1686
- 'ARCHOS Core 101 Wifi' => [ 'Archos', 'Core 101', DeviceType::TABLET ],
1687
  'Archos Core 101 3G' => [ 'Archos', 'Core 101', DeviceType::TABLET ],
1688
  'Archos Sense 55 DC' => [ 'Archos', 'Sense 55' ],
1689
- 'Archos Sense 55 S' => [ 'Archos', 'Sense 55' ],
1690
  ],
1691
 
1692
  'Artes D708' => [ 'Artes', 'D708', DeviceType::TABLET ],
@@ -3849,10 +3823,6 @@ DeviceModels::$ANDROID_MODELS = [
3849
  'DM016SH' => [ 'Sharp', 'DM016SH', 'carrier' => 'Disney Mobile' ],
3850
  ],
3851
 
3852
- 'DM001c Frozen' => [ 'Disney Mobile', 'DM001C Frozen', 'carrier' => 'Disney Mobile' ],
3853
- 'DM001c Mickey' => [ 'Disney Mobile', 'DM001C Mickey', 'carrier' => 'Disney Mobile' ],
3854
- 'DM001c Princess' => [ 'Disney Mobile', 'DM001C Princess', 'carrier' => 'Disney Mobile' ],
3855
-
3856
  'DJC Touchtab3' => [ 'DJC', 'Touchtab3', DeviceType::TABLET ],
3857
  'DJC Touchtab4' => [ 'DJC', 'Touchtab4', DeviceType::TABLET ],
3858
  'AirBook TTJ702' => [ 'DNS', 'Airbook TTJ702', DeviceType::TABLET ],
@@ -4480,13 +4450,11 @@ DeviceModels::$ANDROID_MODELS = [
4480
  'F-01H' => [ 'Fujitsu', 'arrows Fit F-01H', 'carrier' => 'DoCoMo' ],
4481
  'F-01J' => [ 'Fujitsu', 'arrows NX F-01J', 'carrier' => 'DoCoMo' ],
4482
  'F-01K' => [ 'Fujitsu', 'arrows NX F-01K', 'carrier' => 'DoCoMo' ],
4483
- 'F-01L' => [ 'Fujitsu', 'らくらくスマートフォン me F-01L', 'carrier' => 'DoCoMo' ],
4484
  'F-02E' => [ 'Fujitsu', 'ARROWS X F-02E', 'carrier' => 'DoCoMo' ],
4485
  'F-02F' => [ 'Fujitsu', 'ARROWS Tab F-02F', DeviceType::TABLET, 'carrier' => 'DoCoMo' ],
4486
  'F-02G' => [ 'Fujitsu', 'ARROWS NX F-02G', 'carrier' => 'DoCoMo' ],
4487
  'F-02H' => [ 'Fujitsu', 'arrows NX F-02H', 'carrier' => 'DoCoMo' ],
4488
  'F-02K' => [ 'Fujitsu', 'ARROWS Tab F-02K', DeviceType::TABLET, 'carrier' => 'DoCoMo' ],
4489
- 'F-02L' => [ 'Fujitsu', 'arrows Be3 F-02L', 'carrier' => 'DoCoMo' ],
4490
  'F-03D' => [ 'Fujitsu', 'ARROWS Kiss F-03D', 'carrier' => 'DoCoMo' ],
4491
  'F-03E' => [ 'Fujitsu', 'ARROWS Kiss with JILL STUART F-03E', 'carrier' => 'DoCoMo' ],
4492
  'F-03F' => [ 'Fujitsu', 'F-03F', 'carrier' => 'Disney Mobile' ],
@@ -5886,7 +5854,6 @@ DeviceModels::$ANDROID_MODELS = [
5886
  'HTC 2Q4D200' => [ 'HTC', 'U11 Plus'],
5887
  'HTC 2Q3F2' => [ 'HTC', 'U11 Plus'],
5888
  'HTC 2Q3F3' => [ 'HTC', 'U11 Plus'],
5889
- 'HTC U12+' => [ 'HTC', 'U12+'],
5890
  'HTC Velocity!' => [ 'HTC', 'Velocity 4G'],
5891
  'HTCVelocity 4G' => [ 'HTC', 'Velocity 4G'],
5892
  'HTC Vivid' => [ 'HTC', 'Vivid'],
@@ -6195,15 +6162,10 @@ DeviceModels::$ANDROID_MODELS = [
6195
  'BTV-(DL09|W09)!' => [ 'Huawei', 'MediaPad M3', DeviceType::TABLET ],
6196
  'CPN-(W09|AL00|L09)!' => [ 'Huawei', 'MediaPad M3 Lite', DeviceType::TABLET ],
6197
  'BAH-(W09|AL00|L09)!' => [ 'Huawei', 'MediaPad M3 Lite', DeviceType::TABLET ],
6198
- 'CMR-(AL09|AL19|W09|W19)!' => [ 'Huawei', 'MediaPad M5', DeviceType::TABLET ],
6199
- 'BAH2-(AL10|L09|W09|W19)!' => [ 'Huawei', 'MediaPad M5 Lite', DeviceType::TABLET ],
6200
- 'SCM-(AL09|W09)!' => [ 'Huawei', 'MediaPad M6', DeviceType::TABLET ],
6201
 
6202
  'JDN-W09' => [ 'Huawei', 'Honor Pad 2', DeviceType::TABLET ],
6203
- 'JDN2-AL00HN' => [ 'Huawei', 'Honor Tab 5', DeviceType::TABLET ],
6204
- 'JDN2-W09HN' => [ 'Huawei', 'Honor Tab 5', DeviceType::TABLET ],
6205
 
6206
- '(HUAWEI )?(ALP|BLA|CRR|EVR|HMA|LIO|LON|LYA|MATE|MHA|MT1|MT2|MT7|M200|NXT|SNE|TAS|Z100)!!' => [
6207
  '(HW-|HUAWEI )?MT1-(T00|U06)!' => [ 'Huawei', 'Ascend Mate' ],
6208
  '(HW-|HUAWEI )?MATE-U06!' => [ 'Huawei', 'Ascend Mate' ],
6209
  '(HW-|HUAWEI )?MT2-?(C00|L01|L02|L03|L05)!' => [ 'Huawei', 'Ascend Mate 2' ],
@@ -6215,16 +6177,10 @@ DeviceModels::$ANDROID_MODELS = [
6215
  '(HW-|HUAWEI )?LON-(AL00|L29)!' => [ 'Huawei', 'Mate 9 Pro' ],
6216
  '(HW-|HUAWEI )?ALP-(AL00|L09|L29|TL00)!' => [ 'Huawei', 'Mate 10' ],
6217
  '(HW-|HUAWEI )?BLA-(A09|AL00|L09|L29|L30|TL00)!' => [ 'Huawei', 'Mate 10 Pro' ],
6218
- '(HW-|HUAWEI )?HMA-(AL00|L09|L29|TL00)!' => [ 'Huawei', 'Mate 20' ],
6219
- '(HW-|HUAWEI )?EVR-(AL00|AN00|L29|N29|TL00)!' => [ 'Huawei', 'Mate 20 X' ],
6220
- '(HW-|HUAWEI )?SNE-(AL00|LX1|LX2|LX3)!' => [ 'Huawei', 'Mate 20 Lite' ],
6221
- '(HW-|HUAWEI )?LYA-(AL00|AL00P|AL10|L09|L0C|L29|TL00)!' => [ 'Huawei', 'Mate 20 Pro' ],
6222
- '(HW-|HUAWEI )?TAS-(AL00)!' => [ 'Huawei', 'Mate 30' ],
6223
- '(HW-|HUAWEI )?LIO-(AL00|AN00|L29)!' => [ 'Huawei', 'Mate 30 Pro' ],
6224
  '(HW-|HUAWEI )?CRR-(L09|CL00|CL20|TL00|UL00|UL20)!' => [ 'Huawei', 'Mate S' ],
6225
  ],
6226
 
6227
- '(HW-|HUAWEI )?(ATU|DRA|FLA|JKM|TIT|TAG||MRD|NCE|POT|TRT|SLA)!!' => [
6228
  '(HW-|HUAWEI )?TIT-(AL00|CL00|CL10|L01|TL00|U02)!' => [ 'Huawei', 'Enjoy 5' ],
6229
  '(HW-|HUAWEI )?TAG-(AL00|CL00|L13|TL00)!' => [ 'Huawei', 'Enjoy 5S' ],
6230
  '(HW-|HUAWEI )?NCE-(AL00|AL10|TL10)!' => [ 'Huawei', 'Enjoy 6' ],
@@ -6232,13 +6188,9 @@ DeviceModels::$ANDROID_MODELS = [
6232
  '(HW-|HUAWEI )?TRT-(AL00|L21|L53|LX1|LX2|LX3|TL10)!' => [ 'Huawei', 'Enjoy 7 Plus' ],
6233
  '(HW-|HUAWEI )?FLA-(AL10|AL20|LX1|LX2|LX3|TL10)!' => [ 'Huawei', 'Enjoy 8 Plus' ],
6234
  '(HW-|HUAWEI )?DRA-(AL00|L01|L21|LX2)!' => [ 'Huawei', 'Enjoy 8e' ],
6235
- '(HW-|HUAWEI )?ATU-(AL10|L11|L21|L22|L31|LX3|TL10)!' => [ 'Huawei', 'Enjoy 8e' ],
6236
- '(HW-|HUAWEI )?POT-(AL00a|LX1|LX1AF|LX1T|LX2J|LX3)!' => [ 'Huawei', 'Enjoy 9S' ],
6237
- '(HW-|HUAWEI )?MRD-(AL00|LX1|LX1F|LX1N|LX2|LX3)!' => [ 'Huawei', 'Enjoy 9e' ],
6238
- '(HW-|HUAWEI )?JKM-(AL00|AL00a|AL00b|LX1|LX2|LX3|TL00)!' => [ 'Huawei', 'Enjoy 9 Plus' ],
6239
  ],
6240
 
6241
- '(HW-|HUAWEI |HONOR )?(ATH|BLN|BKL|BKK|BND|CHE|CHM|COL|DUA|DUK|DLI|EDI|FRD|HLK|HN3|H30|H60|HOL|JMM|JSN|LRA|KIW|LLD|NEM|NMO|OXF|PE|PCT|PLK|RNE|SCL|TNY|KNT|CAM|STF|HDN|YAL)!!' => [
6242
  'H30 U10' => [ 'Huawei', 'Honor 3C' ],
6243
  '(HW-|HUAWEI )?HN3-(U00|U01)!' => [ 'Huawei', 'Honor 3' ],
6244
  '(HW-|HUAWEI |HONOR )?H30[- ](C00|L01|L02|T00|T10|U10)!' => [ 'Huawei', 'Honor 3C' ],
@@ -6257,28 +6209,19 @@ DeviceModels::$ANDROID_MODELS = [
6257
  '(HW-|HUAWEI )?PE-(CL00|TL00|TL00M|TL10|TL20|UL00)!' => [ 'Huawei', 'Honor 6 Plus' ],
6258
  '(HW-|HUAWEI |HONOR )?PLK-(L01|AL10|CL00|UL00|TL00|TL01H)!' => [ 'Huawei', 'Honor 7' ],
6259
  '(HW-|HUAWEI )?ATH-(AL00|CL00|TL00|TL00H|UL00)!' => [ 'Huawei', 'Honor 7i' ],
6260
- '(HW-|HUAWEI )?DUA-(L22)!' => [ 'Huawei', 'Honor 7S' ],
6261
  '(HW-|HUAWEI )?BND-(AL00|AL10|L21|L24|L31|L34|TL10)!' => [ 'Huawei', 'Honor 7X' ],
6262
- '(HW-|HUAWEI )?DUA-(AL00|TL00)!' => [ 'Huawei', 'Honor 7 Play' ],
6263
  '(HW-|HUAWEI )?FRD-(AL00|AL10|DL00|L02|L04|L09|L14|L19)!' => [ 'Huawei', 'Honor 8' ],
6264
- '(HW-|HUAWEI )?BKK-(AL00|AL10|L21|LX2)!' => [ 'Huawei', 'Honor 8C' ],
6265
- '(HW-|HUAWEI )?JSN-(AL00|AL00a|L21|L22|L23|L42|TL00)!' => [ 'Huawei', 'Honor 8X' ],
6266
  '(HW-|HUAWEI )?ATH-(UL01|UL06)!' => [ 'Huawei', 'Honor ShotX' ],
6267
  '(HW-|HUAWEI )?KNT-(AL10|AL20|TL10|UL10)!' => [ 'Huawei', 'Honor V8' ],
6268
  '(HW-|HUAWEI )?EDI-(AL10)!' => [ 'Huawei', 'Honor Note 8' ],
6269
  '(HW-|HUAWEI )?STF-(AL00|AL10|L09|TL10)!' => [ 'Huawei', 'Honor 9' ],
6270
- '(HW-|HUAWEI )?LLD-(AL00|AL10|AL20|L21|L31)!' => [ 'Huawei', 'Honor 9 Lite' ],
6271
  '(HW-|HUAWEI )?RNE-(AL00|L01|L02|L03|L21|L22|L23|L31)!' => [ 'Huawei', 'Honor 9i' ],
6272
- '(HW-|HUAWEI )?HLK-(AL00|AL10)!' => [ 'Huawei', 'Honor 9X' ],
6273
  '(HW-|HUAWEI )?COL-(AL00|AL10|L29|TL00|TL10)!' => [ 'Huawei', 'Honor 10' ],
6274
- '(HW-|HUAWEI )?YAL-(AL00|AL10|L21|L41)!' => [ 'Huawei', 'Honor 20' ],
6275
- '(HW-|HUAWEI )?LRA-(AL00)!' => [ 'Huawei', 'Honor 20 Lite' ],
6276
  '(HW-|HUAWEI )?DUK-(AL20|L09|TL30)!' => [ 'Huawei', 'Honor V9' ],
6277
  '(HW-|HUAWEI )?JMM-(AL00|AL10|L22|L22HN|TL00)!' => [ 'Huawei', 'Honor V9 Play' ],
6278
  '(HW-|HUAWEI )?BKL-(AL00|AL20|L04|L09)!' => [ 'Huawei', 'Honor V10' ],
6279
- '(HW-|HUAWEI )?PCT-(AL10|L29|TL10)!' => [ 'Huawei', 'Honor V20' ],
6280
- '(HW-|HUAWEI )?OXF-(AN10)!' => [ 'Huawei', 'Honor V30 Pro' ],
6281
- '(HW-|HUAWEI )?TNY-(AL00)!' => [ 'Huawei', 'Honor Magic 2' ],
6282
  '(HW-|HUAWEI )?HDN-(L09|W09)!' => [ 'Huawei', 'Honor WaterPlay', DeviceType::TABLET ],
6283
  ],
6284
 
@@ -6289,7 +6232,7 @@ DeviceModels::$ANDROID_MODELS = [
6289
  '(HW-|HUAWEI )?BLL-(L21|L22|L23)!' => [ 'Huawei', 'GR5 (2017)' ],
6290
  ],
6291
 
6292
- '(HW-|HUAWEI )?(ALE|ANE|CLT|D2|DAV|ELE|EML|EVA|FIG|G6|G7|GRA|M100|P2|P6|P7|PRA|RIO|SC|Sophia|STK|VIE|VKY|VNS|VOG|VTR|WAS)!!' => [
6293
  'HUAWEI D2' => [ 'Huawei', 'Ascend D2' ],
6294
  '(HW-|HUAWEI )?D2-(0082|2010|5000|6070|6114)!' => [ 'Huawei', 'Ascend D2' ],
6295
  '(HW-|HUAWEI )?G6-(C00|L11|L22|L33|T00|U00|U10|U34|U251)!' => [ 'Huawei', 'Ascend G6' ],
@@ -6314,12 +6257,8 @@ DeviceModels::$ANDROID_MODELS = [
6314
  '(HW-|HUAWEI )?WAS-?(AL00|L03T|LX1|LX1A|LX2|LX2J|LX3|TL10)!' => [ 'Huawei', 'P10 Lite' ],
6315
  '(HW-|HUAWEI )?VKY-?(AL00|L09|L29|TL00)!' => [ 'Huawei', 'P10 Plus' ],
6316
  '(HW-|HUAWEI )?FIG-?(AL00|AL10|LA1|LX1|LX3|TL00)!' => [ 'Huawei', 'P Smart' ],
6317
- '(HW-|HUAWEI )?STK-?(L22|LX1|LX3)!' => [ 'Huawei', 'P Smart Z' ],
6318
  '(HW-|HUAWEI )?EML-?(AL00|L09|L29|TL00)!' => [ 'Huawei', 'P20' ],
6319
- '(HW-|HUAWEI )?ANE-?(AL00|L21|LX1|LX2|LX2J|LX3)!' => [ 'Huawei', 'P20 Lite' ],
6320
- '(HW-|HUAWEI )?CLT-?(AL00|AL01|L04|L09|L29|L39|TL00|TL01)!' => [ 'Huawei', 'P20 Pro' ],
6321
- '(HW-|HUAWEI )?ELE-?(AL00|L04|L09|L29|TL00)!' => [ 'Huawei', 'P30' ],
6322
- '(HW-|HUAWEI )?VOG-?(AL00|AL10|L04|L09|L29|TL00)!' => [ 'Huawei', 'P30 Pro' ],
6323
  ],
6324
 
6325
  'Rock-(AL00|CL00|L01|L03)!' => [ 'Huawei', 'Ascend G7' ],
@@ -6343,9 +6282,6 @@ DeviceModels::$ANDROID_MODELS = [
6343
  '(HW-|HUAWEI )?DIG-(AL00|L01|L03|L21|TL10)!' => [ 'Huawei', 'Nova Smart' ],
6344
  '(HW-|HUAWEI )?BAC-(AL00|L03|L21|L22|TL00)!' => [ 'Huawei', 'Nova 2 Plus' ],
6345
  '(HW-|HUAWEI )?HWI-(AL00|TL00)!' => [ 'Huawei', 'Nova 2S' ],
6346
- '(HW-|HUAWEI )?PAR-(AL00|LX1|LX1M|LX9|TL00)!' => [ 'Huawei', 'Nova 3' ],
6347
- '(HW-|HUAWEI )?INE-(AL00|LX1|LX1r|LX2||LX2r|TL00)!' => [ 'Huawei', 'Nova 3i' ],
6348
- '(HW-|HUAWEI )?MAR-(AL00|LX1A|LX1M|LX2|LX3A|TL00)!' => [ 'Huawei', 'Nova 4e' ],
6349
  '(HW-|HUAWEI )?MLA-(AL00|AL10)!' => [ 'Huawei', 'Maimang 5' ],
6350
  '(HW-|HUAWEI )?MLA-(TL00|TL10|UL00)!' => [ 'Huawei', 'G9 Plus' ],
6351
 
@@ -7923,7 +7859,6 @@ DeviceModels::$ANDROID_MODELS = [
7923
 
7924
  'KY[FLTYV][0-9]{2,2}!!' => [
7925
  'KYF31' => [ 'Kyocera', 'GRATINA KYF31', 'carrier' => 'au' ],
7926
- 'KYF33' => [ 'Kyocera', 'TORQUE X01 KYF31', 'carrier' => 'au' ],
7927
  'KYF37' => [ 'Kyocera', 'GRATINA KYF37', 'carrier' => 'au' ],
7928
  'KYL23' => [ 'Kyocera', 'miraie KYL23', 'carrier' => 'au' ],
7929
  'KYY21' => [ 'Kyocera', 'URBANO L01', 'carrier' => 'au' ],
@@ -7937,16 +7872,11 @@ DeviceModels::$ANDROID_MODELS = [
7937
  'KYV36' => [ 'Kyocera', 'DIGNO rafre KYV36', 'carrier' => 'au' ],
7938
  'KYV37' => [ 'Kyocera', 'Qua phone', 'carrier' => 'au' ],
7939
  'KYV38' => [ 'Kyocera', 'URBANO V03 KYV38', 'carrier' => 'au' ],
7940
- 'KYV39' => [ 'Kyocera', 'miraie f KYL39', 'carrier' => 'au' ],
7941
  'KYV40' => [ 'Kyocera', 'rafre KYV40', 'carrier' => 'au' ],
7942
  'KYV40U' => [ 'Kyocera', 'DIGNO W KYV40U', 'carrier' => 'UQ mobile' ],
7943
  'KYV41' => [ 'Kyocera', 'TORQUE G03 KYV41', 'carrier' => 'au' ],
7944
  'KYV42' => [ 'Kyocera', 'Qua phone QX', 'carrier' => 'au' ],
7945
- 'KYV42 u' => [ 'Kyocera', 'DIGNO V KYV42', 'carrier' => 'UQ mobile' ],
7946
- 'KYV44' => [ 'Kyocera', 'Qua phone QZ', 'carrier' => 'au' ],
7947
- 'KYV44 u' => [ 'Kyocera', 'DIGNO A KYV44', 'carrier' => 'UQ mobile' ],
7948
  'KYT31' => [ 'Kyocera', 'Qua tab', DeviceType::TABLET, 'carrier' => 'au' ],
7949
- 'KYT32' => [ 'Kyocera', 'Qua tab QZ8', DeviceType::TABLET, 'carrier' => 'au' ],
7950
  'KYT33' => [ 'Kyocera', 'Qua tab QZ10', DeviceType::TABLET, 'carrier' => 'au' ],
7951
  ],
7952
 
@@ -8863,9 +8793,7 @@ DeviceModels::$ANDROID_MODELS = [
8863
  'LGAS991' => [ 'LG', 'G4' ],
8864
  'LG-AS9(91)!' => [ 'LG', 'G4' ],
8865
  'LGAS992' => [ 'LG', 'G5' ],
8866
- 'LG-AS993' => [ 'LG', 'G6' ],
8867
  'LGAS995' => [ 'LG', 'G Flex 2' ],
8868
- 'LG-AS998' => [ 'LG', 'V30' ],
8869
  ],
8870
 
8871
  'LG-?C[0-9]{3,3}!!' => [
@@ -9004,7 +8932,6 @@ DeviceModels::$ANDROID_MODELS = [
9004
  'LG-F820!' => [ 'LG', 'U' ],
9005
  ],
9006
 
9007
- 'LG-FL40L!' => [ 'LG', '070 Touch' ],
9008
  'LG-GT540!' => [ 'LG', 'Optimus' ],
9009
  'LG-GW620!' => [ 'LG', 'GW620 Eve' ],
9010
 
@@ -9119,8 +9046,6 @@ DeviceModels::$ANDROID_MODELS = [
9119
  'LGL86C!' => [ 'LG', 'Optimus Showtime' ],
9120
  'LG-L95G!' => [ 'LG', 'L95G' ],
9121
  'LGL96G' => [ 'LG', 'Ultimate' ],
9122
- 'LGL157BL' => [ 'LG', 'Rebel 3' ],
9123
- 'LGL158VL' => [ 'LG', 'Rebel 3' ],
9124
  'LG-L160L' => [ 'LG', 'Optimus LTE2' ],
9125
  'LGL163BL' => [ 'LG', 'Fiesta 2' ],
9126
  'LGL164VL' => [ 'LG', 'Fiesta' ],
@@ -9208,7 +9133,6 @@ DeviceModels::$ANDROID_MODELS = [
9208
  'LG-M4(30)!' => [ 'LG', 'Stylo 3' ],
9209
  'LG-M4(70)!' => [ 'LG', 'Stylo 3 Plus' ],
9210
  'LG-M7(00|03)!' => [ 'LG', 'Q6' ],
9211
- 'LG-M7(10)!' => [ 'LG', 'X Venture' ],
9212
  ],
9213
 
9214
  'LG-?MS[0-9]{3,3}!!' => [
@@ -9222,7 +9146,6 @@ DeviceModels::$ANDROID_MODELS = [
9222
  'LGMS500' => [ 'LG', 'Optimus F6' ],
9223
  'LG-MS500' => [ 'LG', 'Optimus F6' ],
9224
  'LGMS550' => [ 'LG', 'G Stylo 2' ],
9225
- 'LG-MS550' => [ 'LG', 'G Stylo 2' ],
9226
  'LGMS631' => [ 'LG', 'G Stylo' ],
9227
  'LG-MS659' => [ 'LG', 'Optimus F3' ],
9228
  'LGMS659' => [ 'LG', 'Optimus F3' ],
@@ -9277,16 +9200,6 @@ DeviceModels::$ANDROID_MODELS = [
9277
  'LG-P815!' => [ 'LG', 'G Pad II 8.3', DeviceType::TABLET ],
9278
  ],
9279
 
9280
- 'LG-Q710!' => [ 'LG', 'Stylo 4' ],
9281
-
9282
- 'LG-RS988!' => [ 'LG', 'G5' ],
9283
- 'RS988' => [ 'LG', 'G5' ],
9284
-
9285
- 'LG-SP[0-9]{3,3}!!' => [
9286
- 'LG-SP200' => [ 'LG', 'Tribute Dynasty' ],
9287
- 'LG-SP320' => [ 'LG', 'X Charge' ],
9288
- ],
9289
-
9290
  'LG-SU[0-9]{3,3}!!' => [
9291
  'LG-SU370' => [ 'LG', 'Optimus One' ],
9292
  'LG-SU540' => [ 'LG', 'PRADA 3.0' ],
@@ -9303,6 +9216,8 @@ DeviceModels::$ANDROID_MODELS = [
9303
  'LG-TP260' => [ 'LG', 'K20 Plus' ],
9304
  'LG-TP450' => [ 'LG', 'Stylo 3 Plus' ],
9305
 
 
 
9306
  'LG-SU-760' => [ 'LG', 'Optimus 3D' ],
9307
  'LGUK410' => [ 'LG', 'G Pad 7.0', DeviceType::TABLET ],
9308
  'LG-UK495' => [ 'LG', 'G Pad F 8.0', DeviceType::TABLET ],
@@ -9315,11 +9230,9 @@ DeviceModels::$ANDROID_MODELS = [
9315
  'LGUS215' => [ 'LG', 'K8 2017' ],
9316
  'LGUS375' => [ 'LG', 'K8' ],
9317
  'LGUS550' => [ 'LG', 'Logos' ],
9318
- 'LG-US601' => [ 'LG', 'X Charge' ],
9319
  'LGUS610' => [ 'LG', 'X Power' ],
9320
  'LG-US670' => [ 'LG', 'Optimus U' ],
9321
- 'LG-US700' => [ 'LG', 'Q6' ],
9322
- 'LG-US701' => [ 'LG', 'X Venture' ],
9323
  'LG-US730' => [ 'LG', 'Splendor' ],
9324
  'LG-US780' => [ 'LG', 'Optimus F7' ],
9325
  'LGUS990!' => [ 'LG', 'G3' ],
@@ -9329,7 +9242,6 @@ DeviceModels::$ANDROID_MODELS = [
9329
  'LGUS995!' => [ 'LG', 'G Flex 2' ],
9330
  'LG-US996!' => [ 'LG', 'V20' ],
9331
  'LG-US997' => [ 'LG', 'G6' ],
9332
- 'LG-US998' => [ 'LG', 'V30' ],
9333
  ],
9334
 
9335
  'LG-V[0-9]{3,3}!!' => [
@@ -9416,7 +9328,6 @@ DeviceModels::$ANDROID_MODELS = [
9416
  'LGM-K120[KLS]!' => [ 'LG', 'X300' ],
9417
  'LGM-K121[KLS]!' => [ 'LG', 'X400' ],
9418
  'LGM-V300[KLS]!' => [ 'LG', 'V30' ],
9419
- 'LGM-X100[S]!' => [ 'LG', 'Smart Folder' ],
9420
  'LGM-X320[KLS]!' => [ 'LG', 'X500' ],
9421
  'LGM-X401[S]!' => [ 'LG', 'X401' ],
9422
  'LGM-X600[KLS]!' => [ 'LG', 'Q6' ],
@@ -9425,32 +9336,13 @@ DeviceModels::$ANDROID_MODELS = [
9425
 
9426
  'LM-G710!' => [ 'LG', 'G7 ThinQ' ],
9427
  'LM-G715!' => [ 'LG', 'G7 ThinQ' ],
9428
- 'LM-G810!' => [ 'LG', 'G8s ThinQ' ],
9429
- 'LM-G820!' => [ 'LG', 'G8 ThinQ' ],
9430
  'LM-Q610!' => [ 'LG', 'Q7' ],
9431
- 'LM-Q617!' => [ 'LG', 'Q7 BTS Edition' ],
9432
  'LM-Q710!' => [ 'LG', 'Q Stylus+' ],
9433
- 'LM-Q720!' => [ 'LG', 'Stylo 5' ],
9434
- 'LM-Q725!' => [ 'LG', 'Q7 Plus' ],
9435
- 'LM-Q815!' => [ 'LG', 'Q8 (2018)' ],
9436
- 'LM-Q850!' => [ 'LG', 'G7 Fit' ],
9437
- 'LM-Q910!' => [ 'LG', 'G7 One' ],
9438
- 'LM-Q925!' => [ 'LG', 'Q9' ],
9439
  'LM-V350!' => [ 'LG', 'V35 ThinQ' ],
9440
- 'LM-V40[59]!' => [ 'LG', 'V40 ThinQ' ],
9441
- 'LM-V450!' => [ 'LG', 'V50 ThinQ' ],
9442
- 'LM-V500!' => [ 'LG', 'V50 ThinQ' ],
9443
- 'LM-X120!' => [ 'LG', 'K20' ],
9444
  'LM-X210!' => [ 'LG', 'Aristo 2' ],
9445
- 'LM-X212!' => [ 'LG', 'K8' ],
9446
- 'LM-X220!' => [ 'LG', 'Aristo 3' ],
9447
- 'LM-X320!' => [ 'LG', 'K30' ],
9448
  'LM-X410!' => [ 'LG', 'X4' ],
9449
  'LM-X415!' => [ 'LG', 'X4+' ],
9450
- 'LM-X420!' => [ 'LG', 'X4 (2019)' ],
9451
  'LM-X510!' => [ 'LG', 'X5' ],
9452
- 'LM-X525!' => [ 'LG', 'K12 Prime' ],
9453
- 'LM-X625!' => [ 'LG', 'X6 (2019)' ],
9454
  'LM-Y110!' => [ 'LG', 'Folder' ],
9455
 
9456
  'LGMP450' => [ 'LG', 'Stylo 3 Plus' ],
@@ -9474,7 +9366,6 @@ DeviceModels::$ANDROID_MODELS = [
9474
  'LGL24' => [ 'LG', 'isai FL LGL24', 'carrier' => 'au' ],
9475
  'LGL25' => [ 'LG', 'Fx0 LGL25', 'carrier' => 'au' ],
9476
  'LGS01' => [ 'LG', 'Wine Smart LGS01', 'carrier' => 'J:COM' ],
9477
- 'LGS02' => [ 'LG', 'X screen LGS02', 'carrier' => 'J:COM' ],
9478
  'LGV31' => [ 'LG', 'isai VL LGV31', 'carrier' => 'au' ],
9479
  'LGV32' => [ 'LG', 'isai vivid LGV32', 'carrier' => 'au' ],
9480
  'LGV33' => [ 'LG', 'Qua phone PX LGV33', 'carrier' => 'au' ],
@@ -9941,7 +9832,6 @@ DeviceModels::$ANDROID_MODELS = [
9941
  'LIFETAB S1033X' => [ 'Medion', 'Lifetab S1033X', DeviceType::TABLET ],
9942
  'LIFETAB S1034X' => [ 'Medion', 'Lifetab S1034X', DeviceType::TABLET ],
9943
  'LIFETAB S1036X' => [ 'Medion', 'Lifetab S1036X', DeviceType::TABLET ],
9944
- 'X1030X' => [ 'Medion', 'Lifetab X1030X', DeviceType::TABLET ],
9945
  'MEDION LIFE P4012' => [ 'Medion', 'Life P4012' ],
9946
  'MEDION P4013' => [ 'Medion', 'Life P4013' ],
9947
  'MEDION-P4013' => [ 'Medion', 'Life P4013' ],
@@ -10684,13 +10574,6 @@ DeviceModels::$ANDROID_MODELS = [
10684
  'XT19(02)!' => [ 'Lenovo', 'K8 Note' ],
10685
  ],
10686
 
10687
- 'motorola one' => [ 'Motorola', 'One' ],
10688
- 'motorola one action' => [ 'Motorola', 'One Action' ],
10689
- 'motorola one macro' => [ 'Motorola', 'One Macro' ],
10690
- 'motorola one power' => [ 'Motorola', 'One Power' ],
10691
- 'motorola one vision' => [ 'Motorola', 'One Vision' ],
10692
- 'motorola one zoom' => [ 'Motorola', 'One Zoom' ],
10693
-
10694
  'Atrix 2' => [ 'Motorola', 'ATRIX 2' ],
10695
  'Atrix 2 WeifanZ' => [ 'Motorola', 'ATRIX 2' ],
10696
  'Atrix 4G' => [ 'Motorola', 'ATRIX 4G' ],
@@ -10745,44 +10628,21 @@ DeviceModels::$ANDROID_MODELS = [
10745
  '(Moto)?E2\(4G-LTE\)$!' => [ 'Motorola', 'Moto E (2015)' ],
10746
  'surnia' => [ 'Motorola', 'Moto E (2015)' ],
10747
  'Motorola MotoE2!' => [ 'Motorola', 'Moto E2' ],
10748
- 'Moto E4' => [ 'Motorola', 'Moto E4' ],
10749
  'Moto E (4)' => [ 'Motorola', 'Moto E4' ],
10750
  'Moto E (4) Plus' => [ 'Motorola', 'Moto E4 Plus' ],
10751
  'moto e5 cruise' => [ 'Motorola', 'Moto E5 Cruise' ],
10752
- 'moto e5 play' => [ 'Motorola', 'Moto E5 Play' ],
10753
  '(Moto)?G3$!' => [ 'Motorola', 'Moto G (2015)' ],
10754
  '(Moto)?G3-TE$!' => [ 'Motorola', 'Moto G (2015)' ],
10755
- 'Moto G 2015' => [ 'Motorola', 'Moto G (2015)' ],
10756
- 'Moto G (2015)' => [ 'Motorola', 'Moto G (2015)' ],
10757
- 'Moto G (2014' => [ 'Motorola', 'Moto G' ],
10758
  'MOTOROLA MOTOG' => [ 'Motorola', 'Moto G' ],
10759
  'Moto G Play' => [ 'Motorola', 'Moto G Play' ],
10760
- 'Moto G Turbo' => [ 'Motorola', 'Moto G Turbo' ],
10761
  'Moto G4' => [ 'Motorola', 'Moto G4' ],
10762
- 'Moto G (4' => [ 'Motorola', 'Moto G4' ],
10763
  'Moto G (4)' => [ 'Motorola', 'Moto G4' ],
10764
  'Moto G4 Plus' => [ 'Motorola', 'Moto G4 Plus' ],
10765
- 'Moto G 5' => [ 'Motorola', 'Moto G5' ],
10766
- 'Moto G (5' => [ 'Motorola', 'Moto G5' ],
10767
  'Moto G (5)' => [ 'Motorola', 'Moto G5' ],
10768
  'Moto G (5) Plus' => [ 'Motorola', 'Moto G5 Plus' ],
10769
- 'Moto G (5S' => [ 'Motorola', 'Moto G5S' ],
10770
- 'Moto G (5S)' => [ 'Motorola', 'Moto G5S' ],
10771
  'Moto G (5S) Plus' => [ 'Motorola', 'Moto G5S Plus' ],
10772
- 'moto g(6' => [ 'Motorola', 'Moto G6' ],
10773
  'moto g(6)' => [ 'Motorola', 'Moto G6' ],
10774
- 'moto g(6) (XT1925DL)' => [ 'Motorola', 'Moto G6' ],
10775
- 'moto g(6) forge' => [ 'Motorola', 'Moto G6 Forge' ],
10776
- 'moto g(6) play' => [ 'Motorola', 'Moto G6 Play' ],
10777
  'moto g(6) plus' => [ 'Motorola', 'Moto G6 Plus' ],
10778
- 'moto g(7' => [ 'Motorola', 'Moto G7' ],
10779
- 'moto g(7)' => [ 'Motorola', 'Moto G7' ],
10780
- 'moto g(7) optimo (XT1952DL)' => [ 'Motorola', 'Moto G7 Optimo' ],
10781
- 'moto g(7) play' => [ 'Motorola', 'Moto G7 Play' ],
10782
- 'moto g(7) plus' => [ 'Motorola', 'Moto G7 Plus' ],
10783
- 'moto g(7) power' => [ 'Motorola', 'Moto G7 Power' ],
10784
- 'moto g(7) supra' => [ 'Motorola', 'Moto G7 Supra' ],
10785
- 'moto g(8' => [ 'Motorola', 'Moto G8' ],
10786
  'Moto Z (2)' => [ 'Motorola', 'Moto Z2' ],
10787
  'Moto Z2 Play' => [ 'Motorola', 'Moto Z2 Play' ],
10788
  'Moto X Pro' => [ 'Motorola', 'Moto X Pro' ],
@@ -11189,30 +11049,10 @@ DeviceModels::$ANDROID_MODELS = [
11189
  'TA-10(00|03|21|25|33|39)!' => [ 'Nokia', '6' ],
11190
  'TA-10(43|50|54|68)!' => [ 'Nokia', '6.1' ],
11191
  'TA-10(41)!' => [ 'Nokia', '7' ],
11192
- 'TA-10(62)!' => [ 'Nokia', '7 Plus' ],
11193
  'TA-10(04|12|52)!' => [ 'Nokia', '8' ],
11194
  'TA-10(99)!' => [ 'Nokia', 'X6' ],
11195
  'TA-11(03|16)!' => [ 'Nokia', 'X6' ],
11196
- 'Nokia 1 Plus' => [ 'Nokia', '1 Plus' ],
11197
- 'Nokia 1' => [ 'Nokia', '1' ],
11198
- 'Nokia 2.1' => [ 'Nokia', '2.1' ],
11199
- 'Nokia 2' => [ 'Nokia', '2' ],
11200
- 'Nokia 3.1 Plus' => [ 'Nokia', '3.1 Plus' ],
11201
- 'Nokia 3.1' => [ 'Nokia', '3.1' ],
11202
- 'Nokia 4.2' => [ 'Nokia', '4.2' ],
11203
- 'Nokia 5.1 Plus' => [ 'Nokia', '5.1 Plus' ],
11204
- 'Nokia 5.1' => [ 'Nokia', '5.1' ],
11205
- 'Nokia 6.1 Plus' => [ 'Nokia', '6.1 Plus' ],
11206
- 'Nokia 6.1' => [ 'Nokia', '6.1' ],
11207
- 'Nokia 6.2' => [ 'Nokia', '6.2' ],
11208
- 'Nokia 6' => [ 'Nokia', '6' ],
11209
- 'Nokia 7.1' => [ 'Nokia', '7.1' ],
11210
- 'Nokia 7 Plus' => [ 'Nokia', '7 Plus' ],
11211
- 'Nokia 8.1' => [ 'Nokia', '8.1' ],
11212
- 'Nokia 8 Sirocco' => [ 'Nokia', '8 Sirocco' ],
11213
- 'Nokia 8' => [ 'Nokia', '8' ],
11214
- 'Nokia 9' => [ 'Nokia', '9' ],
11215
- 'Nokia 10.1' => [ 'Nokia', '10.1' ],
11216
  'Nokia N9' => [ 'Nokia', 'N9' ],
11217
  'Nokia N900' => [ 'Nokia', 'N900' ],
11218
  'Nokia X' => [ 'Nokia', 'X', DeviceType::MOBILE, Flag::NOKIAX ],
@@ -11344,13 +11184,6 @@ DeviceModels::$ANDROID_MODELS = [
11344
  'ONEPLUS A5000' => [ 'OnePlus', '5' ],
11345
  'ONEPLUS A5010' => [ 'OnePlus', '5T' ],
11346
  'ONEPLUS A6000' => [ 'OnePlus', '6' ],
11347
- 'ONEPLUS A6003' => [ 'OnePlus', '6' ],
11348
- 'ONEPLUS A6010' => [ 'OnePlus', '6T' ],
11349
- 'ONEPLUS A6013' => [ 'OnePlus', '6T' ],
11350
- 'HD190[01]!' => [ 'OnePlus', '7T' ],
11351
- 'HD191[03]!' => [ 'OnePlus', '7T Pro' ],
11352
- 'GM190[0135]!' => [ 'OnePlus', '7' ],
11353
- 'GM191[01357]!' => [ 'OnePlus', '7 Pro' ],
11354
  'ONE E1000' => [ 'OnePlus', 'X' ],
11355
  'ONE E1001' => [ 'OnePlus', 'X' ],
11356
  'ONE E1003' => [ 'OnePlus', 'X' ],
@@ -11395,19 +11228,6 @@ DeviceModels::$ANDROID_MODELS = [
11395
  'N2T' => [ 'ONN', 'N2T', DeviceType::TABLET ],
11396
  'Renesas!' => [ 'Opad', 'Renesas', DeviceType::TABLET ],
11397
  'A11w' => [ 'Oppo', 'Joy 3' ],
11398
- 'PADM00' => [ 'Oppo', 'A3' ],
11399
- 'PADT00' => [ 'Oppo', 'A3' ],
11400
- 'CPH1803' => [ 'Oppo', 'A3s' ],
11401
- 'CPH1809' => [ 'Oppo', 'A5' ],
11402
- 'PBAM00' => [ 'Oppo', 'A5' ],
11403
- 'OPPO PBAM00' => [ 'Oppo', 'A5' ],
11404
- 'PBAT00' => [ 'Oppo', 'A5' ],
11405
- 'CPH1901' => [ 'Oppo', 'A7' ],
11406
- 'PBFT00' => [ 'Oppo', 'A7' ],
11407
- 'OPPO PBFT00' => [ 'Oppo', 'A7' ],
11408
- 'PBBM00' => [ 'Oppo', 'A7x' ],
11409
- 'CPH1937' => [ 'Oppo', 'A9 2020' ],
11410
- 'CPH1941' => [ 'Oppo', 'A9 2020' ],
11411
  'OPPO A30' => [ 'Oppo', 'A30' ],
11412
  'A31' => [ 'Oppo', 'A31' ],
11413
  'OPPO A31' => [ 'Oppo', 'A31' ],
@@ -11415,7 +11235,6 @@ DeviceModels::$ANDROID_MODELS = [
11415
  'A31c' => [ 'Oppo', 'A31c' ],
11416
  'A31t' => [ 'Oppo', 'A31t' ],
11417
  'OPPO A31t' => [ 'Oppo', 'A31t' ],
11418
- 'A31u' => [ 'Oppo', 'A31u' ],
11419
  'OPPO A33' => [ 'Oppo', 'A33' ],
11420
  'A33f' => [ 'Oppo', 'A33f' ],
11421
  'OPPO A33m' => [ 'Oppo', 'A33m' ],
@@ -11424,11 +11243,9 @@ DeviceModels::$ANDROID_MODELS = [
11424
  'A37fw' => [ 'Oppo', 'A37fw' ],
11425
  'OPPO A37m' => [ 'Oppo', 'A37m' ],
11426
  'CPH1605' => [ 'Oppo', 'A39' ],
11427
- 'A51' => [ 'Oppo', 'A51' ],
11428
  'A51f' => [ 'Oppo', 'A51f' ],
11429
  'OPPO A53' => [ 'Oppo', 'A53' ],
11430
  'OPPO A53m' => [ 'Oppo', 'A53m' ],
11431
- 'OPPO A53t' => [ 'Oppo', 'A53t' ],
11432
  'CPH1701' => [ 'Oppo', 'A57' ],
11433
  'OPPO A57' => [ 'Oppo', 'A57' ],
11434
  'OPPO A57t' => [ 'Oppo', 'A57t' ],
@@ -11436,19 +11253,8 @@ DeviceModels::$ANDROID_MODELS = [
11436
  'OPPO A59s' => [ 'Oppo', 'A59s' ],
11437
  'OPPO A59st' => [ 'Oppo', 'A59st' ],
11438
  'CPH1717' => [ 'Oppo', 'A71' ],
11439
- 'CPH1801' => [ 'Oppo', 'A71 (2018)' ],
11440
- 'A73' => [ 'Oppo', 'A73' ],
11441
- 'OPPO A73' => [ 'Oppo', 'A73' ],
11442
- 'OPPO A73t' => [ 'Oppo', 'A73t' ],
11443
  'OPPO A77' => [ 'Oppo', 'A77' ],
11444
  'OPPO A77t' => [ 'Oppo', 'A77t' ],
11445
- 'OPPO A79' => [ 'Oppo', 'A79' ],
11446
- 'OPPO A79kt' => [ 'Oppo', 'A79kt' ],
11447
- 'OPPO A79t' => [ 'Oppo', 'A79t' ],
11448
- 'OPPO A83' => [ 'Oppo', 'A83' ],
11449
- 'CPH1729' => [ 'Oppo', 'A83' ],
11450
- 'CPH1827' => [ 'Oppo', 'A83' ],
11451
- 'OPPO A83t' => [ 'Oppo', 'A83t' ],
11452
  'OPPO A800' => [ 'Oppo', 'A800' ],
11453
  'A1603' => [ 'Oppo', 'C1' ],
11454
  'F1f' => [ 'Oppo', 'F1f' ],
@@ -11457,13 +11263,6 @@ DeviceModels::$ANDROID_MODELS = [
11457
  'CPH1609' => [ 'Oppo', 'F3' ],
11458
  'CPH1613' => [ 'Oppo', 'F3 Plus' ],
11459
  'CPH1723' => [ 'Oppo', 'F5' ],
11460
- 'CPH1727' => [ 'Oppo', 'F5' ],
11461
- 'CPH1819' => [ 'Oppo', 'F7' ],
11462
- 'CPH1821' => [ 'Oppo', 'F7' ],
11463
- 'CPH1859' => [ 'Oppo', 'F7 Youth' ],
11464
- 'CPH1881' => [ 'Oppo', 'F9' ],
11465
- 'CPH1823' => [ 'Oppo', 'F9 Pro' ],
11466
- 'CPH1969' => [ 'Oppo', 'F11 Pro' ],
11467
  'Find 5' => [ 'Oppo', 'Find 5' ],
11468
  'X903' => [ 'Oppo', 'Find Me X903' ],
11469
  'X903S' => [ 'Oppo', 'Find X903S' ],
@@ -11480,7 +11279,6 @@ DeviceModels::$ANDROID_MODELS = [
11480
  'X9000' => [ 'Oppo', 'Find 7a X9000' ],
11481
  'X9006' => [ 'Oppo', 'Find 7a X9006' ],
11482
  'X9007' => [ 'Oppo', 'Find 7a X9007' ],
11483
- 'OPPO X9007' => [ 'Oppo', 'Find 7a X9007' ],
11484
  'X9009' => [ 'Oppo', 'F1 Plus X9009' ],
11485
  'X9015' => [ 'Oppo', 'Find X9015' ],
11486
  'OPPOX9015' => [ 'Oppo', 'Find X9015' ],
@@ -11582,18 +11380,10 @@ DeviceModels::$ANDROID_MODELS = [
11582
  'OPPOU7015' => [ 'Oppo', 'Find Way U7015' ],
11583
  'U7015' => [ 'Oppo', 'Find Way U7015' ],
11584
  'A51w' => [ 'Oppo', 'Mirror 5' ],
11585
- 'PBCM30' => [ 'Oppo', 'K1' ],
11586
- 'OPPO PBCM30' => [ 'Oppo', 'K1' ],
11587
- 'OPPO PBCT10' => [ 'Oppo', 'K1' ],
11588
- 'PCGM00' => [ 'Oppo', 'K3' ],
11589
  'OPPO N1' => [ 'Oppo', 'N1' ],
11590
  'N51(10|11|16|17)!' => [ 'Oppo', 'N1 mini' ],
11591
  'N52(06|07|09)!' => [ 'Oppo', 'N3' ],
11592
- 'OB-OPPO R8205' => [ 'Oppo', 'R1c' ],
11593
- 'OB-OPPO R7005' => [ 'Oppo', 'R3' ],
11594
  'OPPO R7' => [ 'Oppo', 'R7' ],
11595
- 'OPPO R7Plus' => [ 'Oppo', 'R7 Plus' ],
11596
- 'OB-OPPO R7c' => [ 'Oppo', 'R7c' ],
11597
  'R7f' => [ 'Oppo', 'R7f' ],
11598
  'R7i' => [ 'Oppo', 'R7i' ],
11599
  'R7kf' => [ 'Oppo', 'R7kf' ],
@@ -11602,19 +11392,15 @@ DeviceModels::$ANDROID_MODELS = [
11602
  'OPPO R7sm' => [ 'Oppo', 'R7sm' ],
11603
  'OPPO R7st' => [ 'Oppo', 'R7st' ],
11604
  'OPPO R7t' => [ 'Oppo', 'R7t' ],
11605
- 'R7t' => [ 'Oppo', 'R7t' ],
11606
- 'OPPO R9k' => [ 'Oppo', 'R9k' ],
11607
  'OPPO R9m' => [ 'Oppo', 'R9m' ],
11608
  'OPPO R9tm' => [ 'Oppo', 'R9tm' ],
11609
  'OPPO R9km' => [ 'Oppo', 'R9km' ],
11610
  'OPPO R9s' => [ 'Oppo', 'R9s' ],
11611
  'OPPO R9sk' => [ 'Oppo', 'R9sk' ],
11612
  'OPPO R9st' => [ 'Oppo', 'R9st' ],
11613
- 'OPPO R9skt' => [ 'Oppo', 'R9skt' ],
11614
  'OPPO R9t' => [ 'Oppo', 'R9t' ],
11615
  'OPPO R9tm' => [ 'Oppo', 'R9tm' ],
11616
  'OPPO R11' => [ 'Oppo', 'R11' ],
11617
- 'CPH1721' => [ 'Oppo', 'R11s' ],
11618
  'OPPO R11t' => [ 'Oppo', 'R11t' ],
11619
  'OPPO R7 Plus' => [ 'Oppo', 'R7 Plus' ],
11620
  'R7Plus' => [ 'Oppo', 'R7 Plus' ],
@@ -11625,41 +11411,14 @@ DeviceModels::$ANDROID_MODELS = [
11625
  'OPPO R9 Plustm A' => [ 'Oppo', 'R9 Plus' ],
11626
  'CPH1611' => [ 'Oppo', 'R9s Plus' ],
11627
  'OPPO R9s Plus' => [ 'Oppo', 'R9s Plus' ],
11628
- 'OPPO R9s Plust' => [ 'Oppo', 'R9st Plus' ],
11629
  'OPPO R11 Plus' => [ 'Oppo', 'R11 Plus' ],
11630
- 'OPPO R11 Plusk' => [ 'Oppo', 'R11k Plus' ],
11631
- 'OPPO R11 Pluskt' => [ 'Oppo', 'R11kt Plus' ],
11632
- 'OPPO R11s' => [ 'Oppo', 'R11s' ],
11633
  'OPPO R11s Plus' => [ 'Oppo', 'R11s Plus' ],
11634
- 'OPPO R11st' => [ 'Oppo', 'R11st' ],
11635
- 'OPPO R11s Plust' => [ 'Oppo', 'R11st Plus' ],
11636
- 'PAAM00' => [ 'Oppo', 'R15' ],
11637
- 'OPPO PAAM00' => [ 'Oppo', 'R15' ],
11638
- 'PACM00' => [ 'Oppo', 'R15' ],
11639
- 'OPPO PACM00' => [ 'Oppo', 'R15' ],
11640
- 'PACT00' => [ 'Oppo', 'R15' ],
11641
- 'OPPO PACT00' => [ 'Oppo', 'R15' ],
11642
- 'PAAT00' => [ 'Oppo', 'R15 Dream Mirror' ],
11643
- 'CPH1879' => [ 'Oppo', 'R17' ],
11644
- 'PBEM00' => [ 'Oppo', 'R17' ],
11645
- 'PBET00' => [ 'Oppo', 'R17' ],
11646
- 'PBDM00' => [ 'Oppo', 'R17 Pro' ],
11647
- 'OPPO PBDM00' => [ 'Oppo', 'R17 Pro' ],
11648
- 'CPH1861' => [ 'Oppo', 'Realme 1' ],
11649
  'W8' => [ 'Oppo', 'W8' ],
11650
- 'OB-OPPO 1105' => [ 'Oppo', '1105' ],
11651
  '1105' => [ 'Oppo', '1105' ],
11652
  '1107' => [ 'Oppo', '1107' ],
11653
  'OB-OPPO 3005' => [ 'Oppo', '3005' ],
11654
- '3007' => [ 'Oppo', '3007' ],
11655
- '6607' => [ 'Oppo', 'U3' ],
11656
- 'PAFM00' => [ 'Oppo', 'Find X' ],
11657
- 'OPPO PAFM00' => [ 'Oppo', 'Find X' ],
11658
- 'PAHM00' => [ 'Oppo', 'Find X' ],
11659
- 'PCAM00' => [ 'Oppo', 'Reno' ],
11660
- 'PCAM10' => [ 'Oppo', 'Reno Lite' ],
11661
- 'PCCM00' => [ 'Oppo', 'Reno 10x Zoom' ],
11662
- 'CPH1979' => [ 'Oppo', 'Reno Z' ],
11663
 
11664
  'OPSSON!!' => [
11665
  'OPSSON D1' => [ 'Opsson', 'D1' ],
@@ -13255,44 +13014,27 @@ DeviceModels::$ANDROID_MODELS = [
13255
  'SMT-i9100' => [ 'Samsung', 'Galaxy Tab 7.0', DeviceType::TABLET ],
13256
 
13257
  'SM-A[0-9]{3,3}!!' => [
13258
- 'SM-A102!' => [ 'Samsung', 'Galaxy A10e' ],
13259
- 'SM-A105!' => [ 'Samsung', 'Galaxy A10' ],
13260
- 'SM-A107!' => [ 'Samsung', 'Galaxy A10s' ],
13261
- 'SM-A202!' => [ 'Samsung', 'Galaxy A20e' ],
13262
- 'SM-A205!' => [ 'Samsung', 'Galaxy A20' ],
13263
- 'SM-A260!' => [ 'Samsung', 'Galaxy A2 Core' ],
13264
  'SM-A300!' => [ 'Samsung', 'Galaxy A3' ],
13265
- 'SM-A305!' => [ 'Samsung', 'Galaxy A30' ],
13266
- 'SM-A307!' => [ 'Samsung', 'Galaxy A30s' ],
13267
  'SM-A310!' => [ 'Samsung', 'Galaxy A3 (2016)' ],
13268
  'SM-A320!' => [ 'Samsung', 'Galaxy A3 (2017)' ],
13269
- 'SM-A405!' => [ 'Samsung', 'Galaxy A40' ],
13270
  'SM-A430!' => [ 'Samsung', 'Galaxy A4' ],
13271
  'SM-A450!' => [ 'Samsung', 'Galaxy A4 (2017)' ],
13272
- 'SM-A460!' => [ 'Samsung', 'SM-A460' ],
13273
  'SM-A500!' => [ 'Samsung', 'Galaxy A5' ],
13274
- 'SM-A505!' => [ 'Samsung', 'Galaxy A50' ],
13275
- 'SM-A507!' => [ 'Samsung', 'Galaxy A50s' ],
13276
  'SM-A510!' => [ 'Samsung', 'Galaxy A5 (2016)' ],
13277
  'SM-A520!' => [ 'Samsung', 'Galaxy A5 (2017)' ],
13278
  'SM-A530!' => [ 'Samsung', 'Galaxy A8 (2018)' ],
13279
  'SM-A600!' => [ 'Samsung', 'Galaxy A6 (2018)' ],
13280
  'SM-A6050!' => [ 'Samsung', 'Galaxy A9 Star Lite' ],
13281
  'SM-A605!' => [ 'Samsung', 'Galaxy A6+ (2018)' ],
13282
- 'SM-A606!' => [ 'Samsung', 'Galaxy A60' ],
13283
  'SM-A700!' => [ 'Samsung', 'Galaxy A7' ],
13284
- 'SM-A705!' => [ 'Samsung', 'Galaxy A70' ],
13285
  'SM-A710!' => [ 'Samsung', 'Galaxy A7 (2016)' ],
13286
  'SM-A720!' => [ 'Samsung', 'Galaxy A7 (2017)' ],
13287
  'SM-A730!' => [ 'Samsung', 'Galaxy A8+ (2018)' ],
13288
- 'SM-A750!' => [ 'Samsung', 'Galaxy A7 (2018)' ],
13289
  'SM-A800!' => [ 'Samsung', 'Galaxy A8' ],
13290
- 'SM-A805!' => [ 'Samsung', 'Galaxy A80' ],
13291
  'SM-A810!' => [ 'Samsung', 'Galaxy A8 (2016)' ],
13292
  'SM-A850!' => [ 'Samsung', 'Galaxy Alpha' ],
13293
  'SM-A900!' => [ 'Samsung', 'Galaxy A9 (2016)' ],
13294
  'SM-A910!' => [ 'Samsung', 'Galaxy A9 Pro' ],
13295
- 'SM-A920!' => [ 'Samsung', 'Galaxy A9 (2018)' ],
13296
  ],
13297
 
13298
  'SM-C[0-9]{3,3}!!' => [
@@ -13311,11 +13053,6 @@ DeviceModels::$ANDROID_MODELS = [
13311
  'SM-E700!' => [ 'Samsung', 'Galaxy E7' ],
13312
  ],
13313
 
13314
- 'SM-F[0-9]{3,3}!!' => [
13315
- 'SM-F700!' => [ 'Samsung', 'Galaxy Z Flip' ],
13316
- 'SM-F900!' => [ 'Samsung', 'Galaxy Fold' ],
13317
- ],
13318
-
13319
  'SM-G[0-9]{3,3}!!' => [
13320
  'SM-G110!' => [ 'Samsung', 'Galaxy Pocket 2' ],
13321
  'SM-G130BT' => [ 'Samsung', 'Galaxy Young 2' ],
@@ -13381,11 +13118,9 @@ DeviceModels::$ANDROID_MODELS = [
13381
  'SM-G850!' => [ 'Samsung', 'Galaxy Alpha' ],
13382
  'SM-G860!' => [ 'Samsung', 'Galaxy S5 Sport' ],
13383
  'SM-G870!' => [ 'Samsung', 'Galaxy S5 Active' ],
13384
- 'SM-G875!' => [ 'Samsung', 'Galaxy S Lite Luxury' ],
13385
  'SM-G880!' => [ 'Samsung', 'Galaxy S7 mini' ],
13386
- 'SM-G885[FSY]!' => [ 'Samsung', 'Galaxy A8 Star' ],
13387
  'SM-G8850!' => [ 'Samsung', 'Galaxy A9 Star' ],
13388
- 'SM-G887!' => [ 'Samsung', 'Galaxy A9 Pro (2019)' ],
13389
  'SM-G890!' => [ 'Samsung', 'Galaxy S6 Active' ],
13390
  'SM-G891!' => [ 'Samsung', 'Galaxy S7 Active' ],
13391
  'SM-G892!' => [ 'Samsung', 'Galaxy S8 Active' ],
@@ -13406,15 +13141,6 @@ DeviceModels::$ANDROID_MODELS = [
13406
  'SM-G955!' => [ 'Samsung', 'Galaxy S8+' ],
13407
  'SM-G960!' => [ 'Samsung', 'Galaxy S9' ],
13408
  'SM-G965!' => [ 'Samsung', 'Galaxy S9+' ],
13409
- 'SM-G970!' => [ 'Samsung', 'Galaxy S10e' ],
13410
- 'SM-G973!' => [ 'Samsung', 'Galaxy S10' ],
13411
- 'SM-G975!' => [ 'Samsung', 'Galaxy S10 Plus' ],
13412
- 'SM-G977!' => [ 'Samsung', 'Galaxy S10 5G' ],
13413
- 'SM-G980!' => [ 'Samsung', 'Galaxy S20' ],
13414
- 'SM-G981!' => [ 'Samsung', 'Galaxy S20' ],
13415
- 'SM-G985!' => [ 'Samsung', 'Galaxy S20+' ],
13416
- 'SM-G986!' => [ 'Samsung', 'Galaxy S20+' ],
13417
- 'SM-G988!' => [ 'Samsung', 'Galaxy S20 Ultra' ],
13418
  ],
13419
 
13420
  'SM-I9500' => [ 'Samsung', 'Galaxy S4' ],
@@ -13428,7 +13154,6 @@ DeviceModels::$ANDROID_MODELS = [
13428
  'SM-J200!' => [ 'Samsung', 'Galaxy J2' ],
13429
  'SM-J210!' => [ 'Samsung', 'Galaxy J2 (2016)' ],
13430
  'SM-J250!' => [ 'Samsung', 'Galaxy J2 (2018)' ],
13431
- 'SM-J260!' => [ 'Samsung', 'Galaxy J2 Pure' ],
13432
  'SM-J3(10|20)!' => [ 'Samsung', 'Galaxy J3' ],
13433
  'SM-J311!' => [ 'Samsung', 'Galaxy J3 (2016)' ],
13434
  'SM-J321!' => [ 'Samsung', 'Galaxy Sol' ],
@@ -13436,18 +13161,12 @@ DeviceModels::$ANDROID_MODELS = [
13436
  'SM-J327!' => [ 'Samsung', 'Galaxy J3 Emerge' ],
13437
  'SM-J330!' => [ 'Samsung', 'Galaxy J3 (2017)' ],
13438
  'SM-J337!' => [ 'Samsung', 'Galaxy J3 (2018)' ],
13439
- 'SM-J400!' => [ 'Samsung', 'Galaxy J4' ],
13440
- 'SM-J410!' => [ 'Samsung', 'Galaxy J4 Core' ],
13441
- 'SM-J415!' => [ 'Samsung', 'Galaxy J4+' ],
13442
  'SM-J500!' => [ 'Samsung', 'Galaxy J5' ],
13443
  'SM-J510!' => [ 'Samsung', 'Galaxy J5 (2016)' ],
13444
  'SM-J530!' => [ 'Samsung', 'Galaxy J5 (2017)' ],
13445
- 'SM-J600!' => [ 'Samsung', 'Galaxy J6' ],
13446
- 'SM-J610!' => [ 'Samsung', 'Galaxy J6+' ],
13447
  'SM-J700!' => [ 'Samsung', 'Galaxy J7' ],
13448
  'SM-J701!' => [ 'Samsung', 'Galaxy J7 Core' ],
13449
  'SM-J710!' => [ 'Samsung', 'Galaxy J7 (2016)' ],
13450
- 'SM-J720!' => [ 'Samsung', 'Galaxy J7 Duo' ],
13451
  'SM-J727!' => [ 'Samsung', 'Galaxy J7 Perx' ],
13452
  'SM-J730!' => [ 'Samsung', 'Galaxy J7 (2017)' ],
13453
  'SM-J737!' => [ 'Samsung', 'Galaxy Wide 3' ],
@@ -13456,12 +13175,6 @@ DeviceModels::$ANDROID_MODELS = [
13456
  'SM-J900!' => [ 'Samsung', 'Galaxy J9' ],
13457
  ],
13458
 
13459
- 'SM-M[0-9]{3,4}!!' => [
13460
- 'SM-M105!' => [ 'Samsung', 'Galaxy M10' ],
13461
- 'SM-M205!' => [ 'Samsung', 'Galaxy M20' ],
13462
- 'SM-M305!' => [ 'Samsung', 'Galaxy M30' ],
13463
- ],
13464
-
13465
  'SM-N[0-9]{3,4}!!' => [
13466
  'SM-N750[025789][QV]?!' => [ 'Samsung', 'Galaxy Note 3 Neo' ],
13467
  'SM-N750[LS]?!' => [ 'Samsung', 'Galaxy Note 3 Neo' ],
@@ -13476,8 +13189,6 @@ DeviceModels::$ANDROID_MODELS = [
13476
  'SM-N935!' => [ 'Samsung', 'Galaxy Note FE' ],
13477
  'SM-N95[05]!' => [ 'Samsung', 'Galaxy Note 8' ],
13478
  'SM-N960!' => [ 'Samsung', 'Galaxy Note 9' ],
13479
- 'SM-N970!' => [ 'Samsung', 'Galaxy Note 10' ],
13480
- 'SM-N975!' => [ 'Samsung', 'Galaxy Note 10+' ],
13481
  ],
13482
 
13483
  'SM-P[0-9]{3,3}!!' => [
@@ -13493,14 +13204,11 @@ DeviceModels::$ANDROID_MODELS = [
13493
  'SM-S320VL' => [ 'Samsung', 'Galaxy Sky' ],
13494
  'SM-S327VL' => [ 'Samsung', 'Galaxy J3 Luna Pro' ],
13495
  'SM-S337TL' => [ 'Samsung', 'Galaxy J3 Luna Pro' ],
13496
- 'SM-S367VL' => [ 'Samsung', 'Galaxy J3 Orbit' ],
13497
  'SM-S550TL' => [ 'Samsung', 'Galaxy On5' ],
13498
  'SM-S727VL' => [ 'Samsung', 'Galaxy J7 Sky Pro' ],
13499
  'SM-S737TL' => [ 'Samsung', 'Galaxy J7 Sky Pro' ],
13500
- 'SM-S757BL' => [ 'Samsung', 'Galaxy J7 Top' ],
13501
  'SM-S765C' => [ 'Samsung', 'Galaxy Ace Style' ],
13502
  'SM-S766C' => [ 'Samsung', 'Galaxy Stardust' ],
13503
- 'SM-S767VL' => [ 'Samsung', 'Galaxy J7 Crown' ],
13504
  'SM-S777C' => [ 'Samsung', 'Galaxy J1' ],
13505
  'SM-S780L' => [ 'Samsung', 'Galaxy Mega 6.3' ],
13506
  'SM-S820L' => [ 'Samsung', 'Galaxy Core Prime' ],
@@ -13531,9 +13239,7 @@ DeviceModels::$ANDROID_MODELS = [
13531
  'SM-T36[05]!' => [ 'Samsung', 'Galaxy Tab Active 8.0', DeviceType::TABLET ],
13532
  'SM-T37[578]!' => [ 'Samsung', 'Galaxy Tab E 8.0', DeviceType::TABLET ],
13533
  'SM-T38[05]!' => [ 'Samsung', 'Galaxy Tab A 8.0 (2017)', DeviceType::TABLET ],
13534
- 'SM-T387!' => [ 'Samsung', 'Galaxy Tab A 8.0 (2018)', DeviceType::TABLET ],
13535
- 'SM-T39[05]!' => [ 'Samsung', 'Galaxy Tab Active2 8.0', DeviceType::TABLET ],
13536
- 'SM-T51[05]!' => [ 'Samsung', 'Galaxy Tab A 10.1 (2019)', DeviceType::TABLET ],
13537
  'SM-T520CC' => [ 'Samsung', 'Galaxy Tab Pro 10.1 Chef Collection', DeviceType::TABLET ],
13538
  'SM-T52[057]!' => [ 'Samsung', 'Galaxy Tab Pro 10.1', DeviceType::TABLET ],
13539
  'SM-T530NU' => [ 'Samsung', 'Galaxy Tab 4 Nook 10.1', DeviceType::TABLET ],
@@ -13542,21 +13248,17 @@ DeviceModels::$ANDROID_MODELS = [
13542
  'SM-T53[157]!' => [ 'Samsung', 'Galaxy Tab 4 10.0', DeviceType::TABLET ],
13543
  'SM-T55[015]!' => [ 'Samsung', 'Galaxy Tab A 9.7', DeviceType::TABLET ],
13544
  'SM-T58[057]!' => [ 'Samsung', 'Galaxy Tab A 10.1 (2016)', DeviceType::TABLET ],
13545
- 'SM-T583!' => [ 'Samsung', 'Galaxy Tab Advanced2', DeviceType::TABLET ],
13546
  'SM-T56[0127]!' => [ 'Samsung', 'Galaxy Tab E 9.6', DeviceType::TABLET ],
13547
- 'SM-T59[057]!' => [ 'Samsung', 'Galaxy Tab A 10.5', DeviceType::TABLET ],
13548
  'SM-T67[07]!' => [ 'Samsung', 'Galaxy View', DeviceType::TABLET ],
13549
  'SM-T70[057]!' => [ 'Samsung', 'Galaxy Tab S 8.4', DeviceType::TABLET ],
13550
  'SM-T71[05]!' => [ 'Samsung', 'Galaxy Tab S2 8.0', DeviceType::TABLET ],
13551
  'SM-T71[39]!' => [ 'Samsung', 'Galaxy Tab S2 8.0 (2016)', DeviceType::TABLET ],
13552
- 'SM-T72[05]!' => [ 'Samsung', 'Galaxy Tab S5e', DeviceType::TABLET ],
13553
  'SM-T80[0157]!' => [ 'Samsung', 'Galaxy Tab S 10.5', DeviceType::TABLET ],
13554
  'SM-T81[057]!' => [ 'Samsung', 'Galaxy Tab S2 9.7', DeviceType::TABLET ],
13555
  'SM-T81[39]!' => [ 'Samsung', 'Galaxy Tab S2 9.7 (2016)', DeviceType::TABLET ],
13556
  'SM-T81[8]!' => [ 'Samsung', 'Galaxy Tab S2 Plus 9.7', DeviceType::TABLET ],
13557
  'SM-T82[057]!' => [ 'Samsung', 'Galaxy Tab S3 9.7', DeviceType::TABLET ],
13558
  'SM-T83[057]!' => [ 'Samsung', 'Galaxy Tab S4 10.5', DeviceType::TABLET ],
13559
- 'SM-T86[057]!' => [ 'Samsung', 'Galaxy Tab S6 10.5', DeviceType::TABLET ],
13560
  'SM-T90[05]!' => [ 'Samsung', 'Galaxy Tab Pro 12.2', DeviceType::TABLET ],
13561
  ],
13562
 
@@ -13699,8 +13401,6 @@ DeviceModels::$ANDROID_MODELS = [
13699
  'SC-01G' => [ 'Samsung', 'GALAXY Note Edge SC-01G', 'carrier' => 'DoCoMo' ],
13700
  'SC-01H' => [ 'Samsung', 'GALAXY Active neo SC-01H', 'carrier' => 'DoCoMo' ],
13701
  'SC-01K' => [ 'Samsung', 'GALAXY Note 8 SC-01K', 'carrier' => 'DoCoMo' ],
13702
- 'SC-01L' => [ 'Samsung', 'GALAXY Note9 SC-01L', 'carrier' => 'DoCoMo' ],
13703
- 'SC-01M' => [ 'Samsung', 'GALAXY Note10+ SC-01M', 'carrier' => 'DoCoMo' ],
13704
  'SC-02B' => [ 'Samsung', 'GALAXY S SC-02B', 'carrier' => 'DoCoMo' ],
13705
  'SC-02C' => [ 'Samsung', 'GALAXY S II SC-02C', 'carrier' => 'DoCoMo' ],
13706
  'SC-02D' => [ 'Samsung', 'GALAXY Tab 7.0 Plus SC-02D', DeviceType::TABLET, 'carrier' => 'DoCoMo' ],
@@ -13710,20 +13410,17 @@ DeviceModels::$ANDROID_MODELS = [
13710
  'SC-02H' => [ 'Samsung', 'Galaxy S7 Edge SC-02H', 'carrier' => 'DoCoMo' ],
13711
  'SC-02J' => [ 'Samsung', 'Galaxy S8 SC-02J', 'carrier' => 'DoCoMo' ],
13712
  'SC-02K' => [ 'Samsung', 'Galaxy S9 SC-02K', 'carrier' => 'DoCoMo' ],
13713
- 'SC-02L' => [ 'Samsung', 'Galaxy Feel2 SC-02L', 'carrier' => 'DoCoMo' ],
13714
  'SC-03D' => [ 'Samsung', 'GALAXY S II LTE SC-03D', 'carrier' => 'DoCoMo' ],
13715
  'SC-03E' => [ 'Samsung', 'GALAXY S III α SC-03E', 'carrier' => 'DoCoMo' ],
13716
  'SC03E' => [ 'Samsung', 'GALAXY S III α SC-03E', 'carrier' => 'DoCoMo' ],
13717
  'SC-03G' => [ 'Samsung', 'GALAXY Tab S 8.4 SC-03G', DeviceType::TABLET, 'carrier' => 'DoCoMo' ],
13718
  'SC-03J' => [ 'Samsung', 'GALAXY S8+ SC-03J', 'carrier' => 'DoCoMo' ],
13719
  'SC-03K' => [ 'Samsung', 'GALAXY S9+ SC-03K', 'carrier' => 'DoCoMo' ],
13720
- 'SC-03L' => [ 'Samsung', 'Galaxy S10 SC-03L', 'carrier' => 'DoCoMo' ],
13721
  'SC-04D' => [ 'Samsung', 'GALAXY NEXUS SC-04D', 'carrier' => 'DoCoMo' ],
13722
  'SC-04E' => [ 'Samsung', 'GALAXY S4 SC-04E', 'carrier' => 'DoCoMo' ],
13723
  'SC-04F' => [ 'Samsung', 'GALAXY S5 SC-04F', 'carrier' => 'DoCoMo' ],
13724
  'SC-04G' => [ 'Samsung', 'GALAXY S6 Edge SC-04G', 'carrier' => 'DoCoMo' ],
13725
  'SC-04J' => [ 'Samsung', 'GALAXY Feel SC-04J', 'carrier' => 'DoCoMo' ],
13726
- 'SC-04L' => [ 'Samsung', 'Galaxy S10+ SC-04L', 'carrier' => 'DoCoMo' ],
13727
  'SC-05D' => [ 'Samsung', 'GALAXY Note SC-05D', 'carrier' => 'DoCoMo' ],
13728
  'SC-05G' => [ 'Samsung', 'GALAXY S6 SC-05G', 'carrier' => 'DoCoMo' ],
13729
  'SC-06D' => [ 'Samsung', 'GALAXY S III SC-06D', 'carrier' => 'DoCoMo' ],
@@ -13738,14 +13435,9 @@ DeviceModels::$ANDROID_MODELS = [
13738
  'SCV31' => [ 'Samsung', 'GALAXY S6 Edge SCV31', 'carrier' => 'au' ],
13739
  'SCV32' => [ 'Samsung', 'GALAXY A8 SCV32', 'carrier' => 'au' ],
13740
  'SCV33' => [ 'Samsung', 'GALAXY S7 edge Injustice Edition SCV33', 'carrier' => 'au' ],
13741
- 'SCV34' => [ 'Samsung', 'GALAXY Note7 SCV34', 'carrier' => 'au' ],
13742
  'SCV35' => [ 'Samsung', 'GALAXY S8+ SCV35', 'carrier' => 'au' ],
13743
  'SCV36' => [ 'Samsung', 'GALAXY S8 SCV36', 'carrier' => 'au' ],
13744
  'SCV37' => [ 'Samsung', 'GALAXY Note8 SCV37', 'carrier' => 'au' ],
13745
- 'SCV38' => [ 'Samsung', 'Galaxy S9 SCV38', 'carrier' => 'au' ],
13746
- 'SCV39' => [ 'Samsung', 'Galaxy S9+ SCV39', 'carrier' => 'au' ],
13747
- 'SCV40' => [ 'Samsung', 'Galaxy Note9 SCV40', 'carrier' => 'au' ],
13748
- 'SCV41' => [ 'Samsung', 'Galaxy S10 SCV41', 'carrier' => 'au' ],
13749
  ],
13750
 
13751
  'ISW11SC' => [ 'Samsung', 'GALAXY S II WiMAX ISW11SC', 'carrier' => 'au' ],
@@ -13914,7 +13606,6 @@ DeviceModels::$ANDROID_MODELS = [
13914
  'SH-01H' => [ 'Sharp', 'AQUOS PHONE ZETA SH-01H', 'carrier' => 'DoCoMo' ],
13915
  'SH-01J' => [ 'Sharp', 'AQUOS ケータイ SH-01J', 'carrier' => 'DoCoMo' ],
13916
  'SH-01K' => [ 'Sharp', 'AQUOS sense SH-01K', 'carrier' => 'DoCoMo' ],
13917
- 'SH-01L' => [ 'Sharp', 'AQUOS sense2 SH-01L', 'carrier' => 'DoCoMo' ],
13918
  'SH-02D' => [ 'Sharp', 'AQUOS PHONE slider SH-02D', 'carrier' => 'DoCoMo' ],
13919
  'SH-02E' => [ 'Sharp', 'AQUOS PHONE ZETA SH-02E', 'carrier' => 'DoCoMo' ],
13920
  'SH-02F' => [ 'Sharp', 'AQUOS PHONE EX SH-02F', 'carrier' => 'DoCoMo' ],
@@ -14003,11 +13694,9 @@ DeviceModels::$ANDROID_MODELS = [
14003
  'SHV35' => [ 'Sharp', 'AQUOS U SHV35', 'carrier' => 'au' ],
14004
  'SHV36' => [ 'Sharp', 'BASIO2 SHV36', 'carrier' => 'au' ],
14005
  'SHV37' => [ 'Sharp', 'AQUOS U SHV37', 'carrier' => 'au' ],
14006
- 'SHV37 u' => [ 'Sharp', 'AQUOS L SHV37', 'carrier' => 'UQ mobile' ],
14007
  'SHV38' => [ 'Sharp', 'AQUOS SERIE mini SHV38', 'carrier' => 'au' ],
14008
  'SHV39' => [ 'Sharp', 'AQUOS R SHV39', 'carrier' => 'au' ],
14009
  'SHV40' => [ 'Sharp', 'AQUOS sense SHV40', 'carrier' => 'au' ],
14010
- 'SHV40 u' => [ 'Sharp', 'AQUOS sense SHV40', 'carrier' => 'UQ mobile' ],
14011
  'SHV41' => [ 'Sharp', 'AQUOS R compact SHV41', 'carrier' => 'au' ],
14012
  'SHV42' => [ 'Sharp', 'AQUOS R2 SHV42', 'carrier' => 'au' ],
14013
  ],
@@ -14249,7 +13938,7 @@ DeviceModels::$ANDROID_MODELS = [
14249
  ],
14250
 
14251
  'G[0-9]{4,4}!!' => [
14252
- 'G31(12|13|16|21|23|25)!' => [ 'Sony', 'Xperia XA1' ],
14253
  'G32(12|21|23|26)!' => [ 'Sony', 'Xperia XA1 Ultra' ],
14254
  'G33(11|12|13)!' => [ 'Sony', 'Xperia L1' ],
14255
  'G34(12|16|21|23|26)!' => [ 'Sony', 'Xperia XA1 Plus' ],
@@ -14260,25 +13949,7 @@ DeviceModels::$ANDROID_MODELS = [
14260
  ],
14261
 
14262
  'H[0-9]{4,4}!!' => [
14263
- 'H31(13|23)!' => [ 'Sony', 'Xperia XA2 Ultra' ],
14264
- 'H32(13|23)!' => [ 'Sony', 'Xperia XA2 Ultra' ],
14265
- 'H33(11|21)!' => [ 'Sony', 'Xperia L2' ],
14266
- 'H41(13|33)!' => [ 'Sony', 'Xperia XA2' ],
14267
- 'H42(13|33)!' => [ 'Sony', 'Xperia XA2 Ultra' ],
14268
- 'H43(11|31)!' => [ 'Sony', 'Xperia L2' ],
14269
- 'H44(13|93)!' => [ 'Sony', 'Xperia XA2 Plus' ],
14270
- 'H81(16|66)!' => [ 'Sony', 'Xperia XZ2 Premium' ],
14271
- 'H82(16|66|76|96)!' => [ 'Sony', 'Xperia XZ2' ],
14272
- 'H83(14|24)!' => [ 'Sony', 'Xperia XZ2 Compact' ],
14273
- 'H84(16)!' => [ 'Sony', 'Xperia XZ3' ],
14274
- 'H84(41)!' => [ 'Sony', 'Xperia XZ1 Compact' ],
14275
- ],
14276
-
14277
- 'I[0-9]{4,4}!!' => [
14278
- 'I31(13|23)!' => [ 'Sony', 'Xperia 10' ],
14279
- 'I32(13|23)!' => [ 'Sony', 'Xperia 10 Plus' ],
14280
- 'I41(13|93)!' => [ 'Sony', 'Xperia 10' ],
14281
- 'I42(13|93)!' => [ 'Sony', 'Xperia 10 Plus' ],
14282
  ],
14283
 
14284
  'E[0-9]{2,2}[a-z]!!' => [
@@ -14385,7 +14056,6 @@ DeviceModels::$ANDROID_MODELS = [
14385
  'SO-01H' => [ 'Sony', 'Xperia Z5 SO-01H', 'carrier' => 'DoCoMo' ], // ...
14386
  'SO-01J' => [ 'Sony', 'Xperia XZ SO-01J', 'carrier' => 'DoCoMo' ], // ...
14387
  'SO-01K' => [ 'Sony', 'Xperia XZ1 SO-01K', 'carrier' => 'DoCoMo' ], // ...
14388
- 'SO-01L' => [ 'Sony', 'Xperia XZ3 SO-01L', 'carrier' => 'DoCoMo' ], // ...
14389
  'SO-02C' => [ 'Sony Ericsson', 'Xperia acro SO-02C', 'carrier' => 'DoCoMo' ], // Azusa
14390
  'SO-02D' => [ 'Sony Ericsson', 'Xperia NX SO-02D', 'carrier' => 'DoCoMo' ], // Nozomi
14391
  'SO-02E' => [ 'Sony', 'Xperia Z SO-02E', 'carrier' => 'DoCoMo' ], // Yuga
@@ -14402,7 +14072,6 @@ DeviceModels::$ANDROID_MODELS = [
14402
  'SO-03H' => [ 'Sony', 'Xperia Z5 Premium SO-03H', 'carrier' => 'DoCoMo' ],
14403
  'SO-03J' => [ 'Sony', 'Xperia XZs SO-03J', 'carrier' => 'DoCoMo' ],
14404
  'SO-03K' => [ 'Sony', 'Xperia XZ2 SO-03K', 'carrier' => 'DoCoMo' ],
14405
- 'SO-03L' => [ 'Sony', 'Xperia 1 SO-03L', 'carrier' => 'DoCoMo' ],
14406
  'SO-04D' => [ 'Sony', 'Xperia GX SO-04D', 'carrier' => 'DoCoMo' ], // Hayabusa
14407
  'SO-04E' => [ 'Sony', 'Xperia A SO-04E', 'carrier' => 'DoCoMo' ], // Dogo
14408
  'SO-04EM' => [ 'Sony', 'Xperia feat. HATSUNE MIKU SO-04E', 'carrier' => 'DoCoMo' ],
@@ -14410,7 +14079,6 @@ DeviceModels::$ANDROID_MODELS = [
14410
  'SO-04G' => [ 'Sony', 'Xperia A4 SO-04G', 'carrier' => 'DoCoMo' ],
14411
  'SO-04H' => [ 'Sony', 'Xperia X Performance SO-04H', 'carrier' => 'DoCoMo' ],
14412
  'SO-04J' => [ 'Sony', 'Xperia XZ Premium SO-04J', 'carrier' => 'DoCoMo' ],
14413
- 'SO-04K' => [ 'Sony', 'Xperia XZ2 Premium SO-04K', 'carrier' => 'DoCoMo' ],
14414
  'SO-05D' => [ 'Sony', 'Xperia SX SO-05D', 'carrier' => 'DoCoMo' ], // Komachi
14415
  'SO-05F' => [ 'Sony', 'Xperia Tablet Z2 SO-05F', DeviceType::TABLET, 'carrier' => 'DoCoMo' ], // Castor
14416
  'SO-05G' => [ 'Sony', 'Xperia Tablet Z4 SO-05G', DeviceType::TABLET, 'carrier' => 'DoCoMo' ], // ...
@@ -14433,10 +14101,7 @@ DeviceModels::$ANDROID_MODELS = [
14433
  'SOV34' => [ 'Sony', 'Xperia XZ SOV34', 'carrier' => 'au' ], // ...
14434
  'SOV35' => [ 'Sony', 'Xperia XZs SOV35', 'carrier' => 'au' ], // ...
14435
  'SOV36' => [ 'Sony', 'Xperia XZ1 SOV36', 'carrier' => 'au' ], // ...
14436
- 'SOV37' => [ 'Sony', 'Xperia XZ2 SOV37', 'carrier' => 'au' ], // ...
14437
- 'SOV38' => [ 'Sony', 'Xperia XZ2 Premium SOV38', 'carrier' => 'au' ], // ...
14438
- 'SOV39' => [ 'Sony', 'Xperia XZ3 SOV39', 'carrier' => 'au' ], // ...
14439
- 'SOV40' => [ 'Sony', 'Xperia 1 SOV40', 'carrier' => 'au' ], // ...
14440
  ],
14441
 
14442
  '40[0-9]SO!!' => [
@@ -16827,22 +16492,9 @@ DeviceModels::$ANDROID_MODELS = [
16827
  '(Xiaomi )?(Xiaomi|Xiaomi M|MI)[ \-]?5s Plus$!' => [ 'Xiaomi', 'Mi 5s Plus' ],
16828
  '(Xiaomi )?(Xiaomi|Xiaomi M|MI)[ \-]?5x$!' => [ 'Xiaomi', 'Mi 5x' ],
16829
  '(Xiaomi )?(Xiaomi|Xiaomi M|MI)[ \-]?6$!' => [ 'Xiaomi', 'Mi 6' ],
16830
- '(Xiaomi )?(Xiaomi|Xiaomi M|MI)[ \-]?6X$!' => [ 'Xiaomi', 'Mi 6X' ],
16831
- '(Xiaomi )?(Xiaomi|Xiaomi M|MI)[ \-]?7S$!' => [ 'Xiaomi', 'Mi 7S' ],
16832
  '(Xiaomi )?(Xiaomi|Xiaomi M|MI)[ \-]?A1$!' => [ 'Xiaomi', 'Mi A1' ],
16833
- '(Xiaomi )?(Xiaomi|Xiaomi M|MI)[ \-]?A2$!' => [ 'Xiaomi', 'Mi A2' ],
16834
- '(Xiaomi )?(Xiaomi|Xiaomi M|MI)[ \-]?A2 Lite!' => [ 'Xiaomi', 'Mi A2 Lite' ],
16835
- '(Xiaomi )?(Xiaomi|Xiaomi M|MI)[ \-]?A3$!' => [ 'Xiaomi', 'Mi A3' ],
16836
- ],
16837
-
16838
- 'MI 8' => [ 'Xiaomi', 'Mi 8' ],
16839
- 'MI 8 SE' => [ 'Xiaomi', 'Mi 8 SE' ],
16840
- 'MI 8 UD' => [ 'Xiaomi', 'Mi 8 UD' ],
16841
- 'MI 8 Lite' => [ 'Xiaomi', 'Mi 8 Lite' ],
16842
- 'MI 9' => [ 'Xiaomi', 'Mi 9' ],
16843
- 'Mi 9T Pro' => [ 'Xiaomi', 'Mi 9T Pro' ],
16844
- 'Mi9 Pro 5G' => [ 'Xiaomi', 'Mi 9 Pro' ],
16845
-
16846
  '(Xiaomi|Xiaomi Mi|MI) Note!!' => [
16847
  '(Xiaomi|Xiaomi Mi|MI) Note (LTE|4G)$!' => [ 'Xiaomi', 'Mi Note' ],
16848
  '(Xiaomi|Xiaomi Mi|MI) Note ?2!' => [ 'Xiaomi', 'Mi Note 2' ],
@@ -16853,7 +16505,6 @@ DeviceModels::$ANDROID_MODELS = [
16853
 
16854
  '(Xiaomi )?(MI )?MAX$!' => [ 'Xiaomi', 'Mi Max' ],
16855
  '(Xiaomi )?(MI )?MAX 2$!' => [ 'Xiaomi', 'Mi Max 2' ],
16856
- '(Xiaomi )?(MI )?MAX 3$!' => [ 'Xiaomi', 'Mi Max 3' ],
16857
  '(Xiaomi )?(MI )?MIX$!' => [ 'Xiaomi', 'Mi MIX' ],
16858
  '(Xiaomi )?(MI )?MIX 2$!' => [ 'Xiaomi', 'Mi MIX 2' ],
16859
  '(Xiaomi )?(MI )?MIX 2S$!' => [ 'Xiaomi', 'Mi MIX 2S' ],
@@ -16885,16 +16536,9 @@ DeviceModels::$ANDROID_MODELS = [
16885
  '(Xiaomi )?(Redmi|HM) ?5$!' => [ 'Xiaomi', 'Redmi 5' ],
16886
  '(Xiaomi )?(Redmi|HM) ?5 Plus!' => [ 'Xiaomi', 'Redmi 5 Plus' ],
16887
  '(Xiaomi )?(Redmi|HM) ?5A!' => [ 'Xiaomi', 'Redmi 5A' ],
16888
- '(Xiaomi )?(Redmi|HM) ?6A!' => [ 'Xiaomi', 'Redmi 6A' ],
16889
- '(Xiaomi )?(Redmi|HM) ?6 Pro!' => [ 'Xiaomi', 'Redmi 6 Pro' ],
16890
- '(Xiaomi )?(Redmi|HM) ?7$!' => [ 'Xiaomi', 'Redmi 7' ],
16891
- '(Xiaomi )?(Redmi|HM) ?7A!' => [ 'Xiaomi', 'Redmi 7A' ],
16892
- '(Xiaomi )?(Redmi|HM) ?8$!' => [ 'Xiaomi', 'Redmi 8' ],
16893
- '(Xiaomi )?Redmi[ \-]K20 Pro!' => [ 'Xiaomi', 'Redmi K20 Pro' ],
16894
  '(Xiaomi )?Redmi[ \-]S2$!' => [ 'Xiaomi', 'Redmi S2' ],
16895
  '(Xiaomi )?Redmi[ \-]Y1$!' => [ 'Xiaomi', 'Redmi Y1' ],
16896
  '(Xiaomi )?Redmi[ \-]Y1 Lite!' => [ 'Xiaomi', 'Redmi Y1 Lite' ],
16897
- '(Xiaomi )?Redmi[ \-]Go$!' => [ 'Xiaomi', 'Redmi Go' ],
16898
  ],
16899
 
16900
  '(Xiaomi )?(Redmi|HM)[ \-]?Note!!' => [
@@ -16907,9 +16551,6 @@ DeviceModels::$ANDROID_MODELS = [
16907
  '(Xiaomi )?Redmi[ \-]Note ?5$!' => [ 'Xiaomi', 'Redmi Note 5' ],
16908
  '(Xiaomi )?Redmi[ \-]Note ?5A!' => [ 'Xiaomi', 'Redmi Note 5A' ],
16909
  '(Xiaomi )?Redmi[ \-]Note 5 Pro!' => [ 'Xiaomi', 'Redmi Note 5 Pro' ],
16910
- '(Xiaomi )?Redmi[ \-]Note 7$!' => [ 'Xiaomi', 'Redmi Note 7' ],
16911
- '(Xiaomi )?Redmi[ \-]Note 7 Pro!' => [ 'Xiaomi', 'Redmi Note 7 Pro' ],
16912
- '(Xiaomi )?Redmi[ \-]Note 8$!' => [ 'Xiaomi', 'Redmi Note 8' ],
16913
  ],
16914
 
16915
  '(Xiaomi |HM)?20!!' => [
@@ -16932,8 +16573,6 @@ DeviceModels::$ANDROID_MODELS = [
16932
  '(Xiaomi |HM)?20160(51)!' => [ 'Xiaomi', 'Redmi Note 4' ],
16933
  ],
16934
 
16935
- 'POCOPHONE F1' => [ 'Xiaomi', 'Pocophone F1' ],
16936
-
16937
  'Xiaomi MDT2!' => [ 'Xiaomi', 'Mi 5x' ],
16938
  'Xiaomi MCT1!' => [ 'Xiaomi', 'Mi 6' ],
16939
  'Xiaomi MAT136!' => [ 'Xiaomi', 'Redmi 4X' ],
@@ -18444,7 +18083,6 @@ DeviceModels::$ANDROID_MODELS = [
18444
  'GM 5 Plus d' => [ 'General Mobile', 'GM5 Plus' ],
18445
  'GM 6' => [ 'General Mobile', 'GM6' ],
18446
  'GM 6 d' => [ 'General Mobile', 'GM6' ],
18447
- 'GM 8 d' => [ 'General Mobile', 'GM8' ],
18448
  'GM Discovery tab 8' => [ 'General Mobile', 'tab 8', DeviceType::TABLET ],
18449
  'etab5' => [ 'General Mobile', 'Etab 5', DeviceType::TABLET ],
18450
 
261
  'Pixel' => [ 'Google', 'Pixel' ],
262
  'Google Pixel' => [ 'Google', 'Pixel' ],
263
  'Pixel XL' => [ 'Google', 'Pixel XL' ],
264
+ 'Google Pixel XL' => [ 'Google', 'Pixel XL' ],
265
  'Pixel 2' => [ 'Google', 'Pixel 2' ],
266
  'Google Pixel 2' => [ 'Google', 'Pixel 2' ],
267
  'Pixel 2XL' => [ 'Google', 'Pixel 2 XL' ],
268
  'Pixel 2 XL' => [ 'Google', 'Pixel 2 XL' ],
269
  'Google Pixel 2XL' => [ 'Google', 'Pixel 2 XL' ],
 
 
 
 
 
 
270
 
271
  /* Google Edition */
272
  'HTC One' => [ 'HTC', 'One (Google Edition)' ],
959
  'one ?touch 4032!' => [ 'Alcatel', 'One Touch Pop C2' ],
960
  '4032[ADEX]!' => [ 'Alcatel', 'One Touch Pop C2' ],
961
  'one ?touch 4033!' => [ 'Alcatel', 'One Touch Pop C3' ],
962
+ '4033[AL]!' => [ 'Alcatel', 'One Touch Pop C3' ],
963
  'ONETOUCH POPC3' => [ 'Alcatel', 'One Touch Pop C3' ],
964
  '4034[ADEFGX]!' => [ 'Alcatel', 'One Touch Pixi 4 (4)' ],
965
  'one ?touch 40(35|36|37)!' => [ 'Alcatel', 'One Touch Pop D3' ],
970
  '4037[V]!' => [ 'Alcatel', 'One Touch Elevate' ],
971
  'one ?touch 5045!' => [ 'Alcatel', 'One Touch Pop 2 (4)' ],
972
  '4045[ADEFLOYX]!' => [ 'Alcatel', 'One Touch Pop 2 (4)' ],
 
 
973
  '4055[JU]!' => [ 'Alcatel', 'One Touch Pixi 5 (4)' ],
974
  '4060[A]!' => [ 'Alcatel', 'IDEAL' ],
975
+ '4060[W]!' => [ 'Alcatel', 'One Touch Pixi 4 (5)' ],
976
  '5010[DEGSUX]!' => [ 'Alcatel', 'One Touch Pixi 4 (5)' ],
 
977
  '5012[G]!' => [ 'Alcatel', 'One Touch Pixi 4 (5.5)' ],
978
  '5015[ADEX]!' => [ 'Alcatel', 'One Touch Pixi 3 (5)' ],
979
  '5016[AJ]!' => [ 'Alcatel', 'One Touch Pixi 3 (5)' ],
988
  'one ?touch 5021!' => [ 'Alcatel', 'One Touch Soleil' ],
989
  '5022[DEX]!' => [ 'Alcatel', 'One Touch Pop Star' ],
990
  '5023[F]!' => [ 'Alcatel', 'One Touch Pixi 4 Plus Power' ],
 
991
  '5025[DEGX]!' => [ 'Alcatel', 'One Touch Pop 3' ],
992
  '5027[B]!' => [ 'Alcatel', 'One Touch Dawn' ],
 
 
993
  'one ?touch 5035!' => [ 'Alcatel', 'One Touch X\'Pop' ],
994
  '5036[D]!' => [ 'Alcatel', 'One Touch Pop C5' ],
995
  'one ?touch 50(36|37)!' => [ 'Alcatel', 'One Touch Pop C5' ],
996
  'ONETOUCH POPC5' => [ 'Alcatel', 'One Touch Pop C5' ],
997
  'one ?touch 50(38)!' => [ 'Alcatel', 'One Touch Pop D5' ],
998
  '5038[ADEX]!' => [ 'Alcatel', 'One Touch Pop D5' ],
 
 
999
  'one ?touch 5042!' => [ 'Alcatel', 'One Touch Pop 2 (4.5)' ],
1000
  '5042[ADEFGTWXY]!' => [ 'Alcatel', 'One Touch Pop 2 (4.5)' ],
1001
+ '5044[ADOY]!' => [ 'Alcatel', 'U5' ],
1002
+ '5045[ADGJTX]!' => [ 'Alcatel', 'One Touch Pixi 4 (5.0)' ],
1003
+ '5046[DGJY]!' => [ 'Alcatel', 'A3' ],
1004
+ '5047[DUY]!' => [ 'Alcatel', 'U5 HD' ],
1005
  '5049[EGSWZ]!' => [ 'Alcatel', 'A30 Fierce' ],
1006
  'one ?touch 5050!' => [ 'Alcatel', 'One Touch Pop S3' ],
1007
  '5050[ASYX]!' => [ 'Alcatel', 'One Touch Pop S3' ],
1008
  '5051[ADJMX]!' => [ 'Alcatel', 'One Touch Pop 4 (5.0)' ],
1009
+ '5052[D]!' => [ 'Alcatel', '3' ],
 
1010
  '5054[ADOSTX]!' => [ 'Alcatel', 'One Touch Pixi 3 (5.5)' ],
1011
  '5054[NW]!' => [ 'Alcatel', 'One Touch Fierce XL' ],
1012
+ '5056[ADENUWX]!' => [ 'Alcatel', 'One Touch Pop 4+' ],
1013
  '5056[O]!' => [ 'Alcatel', 'One Touch Allura' ],
1014
  '5057[M]!' => [ 'Alcatel', 'One Touch Pop Mirage' ],
 
 
 
1015
  '5065[ADJNWX]!' => [ 'Alcatel', 'One Touch Pixi 3 (5)' ],
1016
  '5070[DJX]!' => [ 'Alcatel', 'One Touch Pop Star' ],
 
1017
  '5080[DFQX]!' => [ 'Alcatel', 'One Touch Pixi 4 (6)' ],
1018
+ '5085[CDJNY]!' => [ 'Alcatel', 'A5 LED' ],
 
1019
  '5090[Y]!' => [ 'Alcatel', 'A7' ],
1020
  '5095[BIKY]!' => [ 'Alcatel', 'One Touch Pop 4S' ],
1021
  '5096[AI]!' => [ 'Alcatel', 'One Touch Net' ],
1050
  'one ?touch 6050!' => [ 'Alcatel', 'One Touch Idol 2S' ],
1051
  '6050[AFWY]!' => [ 'Alcatel', 'One Touch Idol 2S' ],
1052
  '6055[ABDHIKPUY]!' => [ 'Alcatel', 'One Touch Idol 4' ],
 
 
 
1053
  '6070[KOY]!' => [ 'Alcatel', 'One Touch Idol 4s' ],
1054
  'one ?touch 7024!' => [ 'Alcatel', 'One Touch Fierce' ],
1055
  'one touch fierce!' => [ 'Alcatel', 'One Touch Fierce' ],
1299
  'KFGIWI' => [ 'Amazon', 'Fire HD 8 (2016)', DeviceType::TABLET, Flag::FIREOS ], // xth generation 8" HD (1280 x 800)
1300
  'KFDOWI' => [ 'Amazon', 'Fire HD 8 (2017)', DeviceType::TABLET, Flag::FIREOS ], // xth generation 8" HD (1280 x 800)
1301
  'KFSUWI' => [ 'Amazon', 'Fire HD 10 (2017)', DeviceType::TABLET, Flag::FIREOS ], // 5th generation 10" HD (1280 x 800)
1302
+ // 'KFSLWI'
1303
+ // 'KFBJWI'
1304
+ // 'KFHDX'
1305
  'SD4930UR' => [ 'Amazon', 'Fire Phone', DeviceType::MOBILE, Flag::FIREOS ],
1306
  'AFTB' => [ 'Amazon', 'Fire TV', DeviceType::TELEVISION, Flag::FIREOS ],
1307
  'AFTS' => [ 'Amazon', 'Fire TV (2015)', DeviceType::TELEVISION, Flag::FIREOS ],
1477
  'Archos!!' => [
1478
  'ARCHOS 80G9' => [ 'Archos', '80 G9', DeviceType::TABLET ],
1479
  'ARCHOS 101G9' => [ 'Archos', '101 G9', DeviceType::TABLET ],
 
1480
  'ARCHOS 97XSLG10' => [ 'Archos', '97 XS', DeviceType::TABLET ],
1481
  'ARCHOS 80XSK' => [ 'Archos', '80 XS', DeviceType::TABLET ],
1482
  'ARCHOS 101G10' => [ 'Archos', '101 XS', DeviceType::TABLET ],
1639
  'ARCHOS 97 XENON' => [ 'Archos', '97 Xenon', DeviceType::TABLET ],
1640
  'Archos 101 Xenon' => [ 'Archos', '101 Xenon', DeviceType::TABLET ],
1641
  'Archos 101 Xenon v2' => [ 'Archos', '101 Xenon', DeviceType::TABLET ],
 
1642
  'Archos 101b Xenon v2' => [ 'Archos', '101b Xenon', DeviceType::TABLET ],
1643
  'Archos 101c Xenon' => [ 'Archos', '101c Xenon', DeviceType::TABLET ],
1644
  'ARCHOS 101 Xenon Lite' => [ 'Archos', '101 Xenon Lite', DeviceType::TABLET ],
1657
  'Archos Access 70 3G' => [ 'Archos', 'Access 70', DeviceType::TABLET ],
1658
  'Archos Access 101 3G' => [ 'Archos', 'Access 101', DeviceType::TABLET ],
1659
  'Archos Access 101 3G V2' => [ 'Archos', 'Access 101', DeviceType::TABLET ],
 
1660
  'Archos Core 55 4G' => [ 'Archos', 'Core 55' ],
1661
  'Archos Core 70 3G' => [ 'Archos', 'Core 70', DeviceType::TABLET ],
 
1662
  'Archos Core 101 3G' => [ 'Archos', 'Core 101', DeviceType::TABLET ],
1663
  'Archos Sense 55 DC' => [ 'Archos', 'Sense 55' ],
 
1664
  ],
1665
 
1666
  'Artes D708' => [ 'Artes', 'D708', DeviceType::TABLET ],
3823
  'DM016SH' => [ 'Sharp', 'DM016SH', 'carrier' => 'Disney Mobile' ],
3824
  ],
3825
 
 
 
 
 
3826
  'DJC Touchtab3' => [ 'DJC', 'Touchtab3', DeviceType::TABLET ],
3827
  'DJC Touchtab4' => [ 'DJC', 'Touchtab4', DeviceType::TABLET ],
3828
  'AirBook TTJ702' => [ 'DNS', 'Airbook TTJ702', DeviceType::TABLET ],
4450
  'F-01H' => [ 'Fujitsu', 'arrows Fit F-01H', 'carrier' => 'DoCoMo' ],
4451
  'F-01J' => [ 'Fujitsu', 'arrows NX F-01J', 'carrier' => 'DoCoMo' ],
4452
  'F-01K' => [ 'Fujitsu', 'arrows NX F-01K', 'carrier' => 'DoCoMo' ],
 
4453
  'F-02E' => [ 'Fujitsu', 'ARROWS X F-02E', 'carrier' => 'DoCoMo' ],
4454
  'F-02F' => [ 'Fujitsu', 'ARROWS Tab F-02F', DeviceType::TABLET, 'carrier' => 'DoCoMo' ],
4455
  'F-02G' => [ 'Fujitsu', 'ARROWS NX F-02G', 'carrier' => 'DoCoMo' ],
4456
  'F-02H' => [ 'Fujitsu', 'arrows NX F-02H', 'carrier' => 'DoCoMo' ],
4457
  'F-02K' => [ 'Fujitsu', 'ARROWS Tab F-02K', DeviceType::TABLET, 'carrier' => 'DoCoMo' ],
 
4458
  'F-03D' => [ 'Fujitsu', 'ARROWS Kiss F-03D', 'carrier' => 'DoCoMo' ],
4459
  'F-03E' => [ 'Fujitsu', 'ARROWS Kiss with JILL STUART F-03E', 'carrier' => 'DoCoMo' ],
4460
  'F-03F' => [ 'Fujitsu', 'F-03F', 'carrier' => 'Disney Mobile' ],
5854
  'HTC 2Q4D200' => [ 'HTC', 'U11 Plus'],
5855
  'HTC 2Q3F2' => [ 'HTC', 'U11 Plus'],
5856
  'HTC 2Q3F3' => [ 'HTC', 'U11 Plus'],
 
5857
  'HTC Velocity!' => [ 'HTC', 'Velocity 4G'],
5858
  'HTCVelocity 4G' => [ 'HTC', 'Velocity 4G'],
5859
  'HTC Vivid' => [ 'HTC', 'Vivid'],
6162
  'BTV-(DL09|W09)!' => [ 'Huawei', 'MediaPad M3', DeviceType::TABLET ],
6163
  'CPN-(W09|AL00|L09)!' => [ 'Huawei', 'MediaPad M3 Lite', DeviceType::TABLET ],
6164
  'BAH-(W09|AL00|L09)!' => [ 'Huawei', 'MediaPad M3 Lite', DeviceType::TABLET ],
 
 
 
6165
 
6166
  'JDN-W09' => [ 'Huawei', 'Honor Pad 2', DeviceType::TABLET ],
 
 
6167
 
6168
+ '(HUAWEI )?(ALP|BLA|CRR|LON|MATE|MHA|MT1|MT2|MT7|M200|NXT|Z100)!!' => [
6169
  '(HW-|HUAWEI )?MT1-(T00|U06)!' => [ 'Huawei', 'Ascend Mate' ],
6170
  '(HW-|HUAWEI )?MATE-U06!' => [ 'Huawei', 'Ascend Mate' ],
6171
  '(HW-|HUAWEI )?MT2-?(C00|L01|L02|L03|L05)!' => [ 'Huawei', 'Ascend Mate 2' ],
6177
  '(HW-|HUAWEI )?LON-(AL00|L29)!' => [ 'Huawei', 'Mate 9 Pro' ],
6178
  '(HW-|HUAWEI )?ALP-(AL00|L09|L29|TL00)!' => [ 'Huawei', 'Mate 10' ],
6179
  '(HW-|HUAWEI )?BLA-(A09|AL00|L09|L29|L30|TL00)!' => [ 'Huawei', 'Mate 10 Pro' ],
 
 
 
 
 
 
6180
  '(HW-|HUAWEI )?CRR-(L09|CL00|CL20|TL00|UL00|UL20)!' => [ 'Huawei', 'Mate S' ],
6181
  ],
6182
 
6183
+ '(HW-|HUAWEI )?(DRA|FLA|TIT|TAG|NCE|TRT|SLA)!!' => [
6184
  '(HW-|HUAWEI )?TIT-(AL00|CL00|CL10|L01|TL00|U02)!' => [ 'Huawei', 'Enjoy 5' ],
6185
  '(HW-|HUAWEI )?TAG-(AL00|CL00|L13|TL00)!' => [ 'Huawei', 'Enjoy 5S' ],
6186
  '(HW-|HUAWEI )?NCE-(AL00|AL10|TL10)!' => [ 'Huawei', 'Enjoy 6' ],
6188
  '(HW-|HUAWEI )?TRT-(AL00|L21|L53|LX1|LX2|LX3|TL10)!' => [ 'Huawei', 'Enjoy 7 Plus' ],
6189
  '(HW-|HUAWEI )?FLA-(AL10|AL20|LX1|LX2|LX3|TL10)!' => [ 'Huawei', 'Enjoy 8 Plus' ],
6190
  '(HW-|HUAWEI )?DRA-(AL00|L01|L21|LX2)!' => [ 'Huawei', 'Enjoy 8e' ],
 
 
 
 
6191
  ],
6192
 
6193
+ '(HW-|HUAWEI |HONOR )?(ATH|BLN|BKL|BND|CHE|CHM|COL|DUA|DUK|DLI|EDI|FRD|HN3|H30|H60|HOL|JMM|KIW|LLD|NEM|NMO|PE|PLK|RNE|SCL|KNT|CAM|STF|HDN)!!' => [
6194
  'H30 U10' => [ 'Huawei', 'Honor 3C' ],
6195
  '(HW-|HUAWEI )?HN3-(U00|U01)!' => [ 'Huawei', 'Honor 3' ],
6196
  '(HW-|HUAWEI |HONOR )?H30[- ](C00|L01|L02|T00|T10|U10)!' => [ 'Huawei', 'Honor 3C' ],
6209
  '(HW-|HUAWEI )?PE-(CL00|TL00|TL00M|TL10|TL20|UL00)!' => [ 'Huawei', 'Honor 6 Plus' ],
6210
  '(HW-|HUAWEI |HONOR )?PLK-(L01|AL10|CL00|UL00|TL00|TL01H)!' => [ 'Huawei', 'Honor 7' ],
6211
  '(HW-|HUAWEI )?ATH-(AL00|CL00|TL00|TL00H|UL00)!' => [ 'Huawei', 'Honor 7i' ],
 
6212
  '(HW-|HUAWEI )?BND-(AL00|AL10|L21|L24|L31|L34|TL10)!' => [ 'Huawei', 'Honor 7X' ],
6213
+ '(HW-|HUAWEI )?DUA-(AL00)!' => [ 'Huawei', 'Honor 7 Play' ],
6214
  '(HW-|HUAWEI )?FRD-(AL00|AL10|DL00|L02|L04|L09|L14|L19)!' => [ 'Huawei', 'Honor 8' ],
 
 
6215
  '(HW-|HUAWEI )?ATH-(UL01|UL06)!' => [ 'Huawei', 'Honor ShotX' ],
6216
  '(HW-|HUAWEI )?KNT-(AL10|AL20|TL10|UL10)!' => [ 'Huawei', 'Honor V8' ],
6217
  '(HW-|HUAWEI )?EDI-(AL10)!' => [ 'Huawei', 'Honor Note 8' ],
6218
  '(HW-|HUAWEI )?STF-(AL00|AL10|L09|TL10)!' => [ 'Huawei', 'Honor 9' ],
6219
+ '(HW-|HUAWEI )?LLD-(AL00|AL10|AL20|L21|L31)!' => [ 'Huawei', 'Honor 9 Lite' ],
6220
  '(HW-|HUAWEI )?RNE-(AL00|L01|L02|L03|L21|L22|L23|L31)!' => [ 'Huawei', 'Honor 9i' ],
 
6221
  '(HW-|HUAWEI )?COL-(AL00|AL10|L29|TL00|TL10)!' => [ 'Huawei', 'Honor 10' ],
 
 
6222
  '(HW-|HUAWEI )?DUK-(AL20|L09|TL30)!' => [ 'Huawei', 'Honor V9' ],
6223
  '(HW-|HUAWEI )?JMM-(AL00|AL10|L22|L22HN|TL00)!' => [ 'Huawei', 'Honor V9 Play' ],
6224
  '(HW-|HUAWEI )?BKL-(AL00|AL20|L04|L09)!' => [ 'Huawei', 'Honor V10' ],
 
 
 
6225
  '(HW-|HUAWEI )?HDN-(L09|W09)!' => [ 'Huawei', 'Honor WaterPlay', DeviceType::TABLET ],
6226
  ],
6227
 
6232
  '(HW-|HUAWEI )?BLL-(L21|L22|L23)!' => [ 'Huawei', 'GR5 (2017)' ],
6233
  ],
6234
 
6235
+ '(HW-|HUAWEI )?(ALE|ANE|D2|DAV|EML|EVA|FIG|G6|G7|GRA|M100|P2|P6|P7|PRA|RIO|SC|Sophia|VIE|VKY|VNS|VTR|WAS)!!' => [
6236
  'HUAWEI D2' => [ 'Huawei', 'Ascend D2' ],
6237
  '(HW-|HUAWEI )?D2-(0082|2010|5000|6070|6114)!' => [ 'Huawei', 'Ascend D2' ],
6238
  '(HW-|HUAWEI )?G6-(C00|L11|L22|L33|T00|U00|U10|U34|U251)!' => [ 'Huawei', 'Ascend G6' ],
6257
  '(HW-|HUAWEI )?WAS-?(AL00|L03T|LX1|LX1A|LX2|LX2J|LX3|TL10)!' => [ 'Huawei', 'P10 Lite' ],
6258
  '(HW-|HUAWEI )?VKY-?(AL00|L09|L29|TL00)!' => [ 'Huawei', 'P10 Plus' ],
6259
  '(HW-|HUAWEI )?FIG-?(AL00|AL10|LA1|LX1|LX3|TL00)!' => [ 'Huawei', 'P Smart' ],
 
6260
  '(HW-|HUAWEI )?EML-?(AL00|L09|L29|TL00)!' => [ 'Huawei', 'P20' ],
6261
+ '(HW-|HUAWEI )?ANE-?(AL00|L21|LX1|LX2|LX2J|LX3)!' => [ 'Huawei', 'P20 lite' ],
 
 
 
6262
  ],
6263
 
6264
  'Rock-(AL00|CL00|L01|L03)!' => [ 'Huawei', 'Ascend G7' ],
6282
  '(HW-|HUAWEI )?DIG-(AL00|L01|L03|L21|TL10)!' => [ 'Huawei', 'Nova Smart' ],
6283
  '(HW-|HUAWEI )?BAC-(AL00|L03|L21|L22|TL00)!' => [ 'Huawei', 'Nova 2 Plus' ],
6284
  '(HW-|HUAWEI )?HWI-(AL00|TL00)!' => [ 'Huawei', 'Nova 2S' ],
 
 
 
6285
  '(HW-|HUAWEI )?MLA-(AL00|AL10)!' => [ 'Huawei', 'Maimang 5' ],
6286
  '(HW-|HUAWEI )?MLA-(TL00|TL10|UL00)!' => [ 'Huawei', 'G9 Plus' ],
6287
 
7859
 
7860
  'KY[FLTYV][0-9]{2,2}!!' => [
7861
  'KYF31' => [ 'Kyocera', 'GRATINA KYF31', 'carrier' => 'au' ],
 
7862
  'KYF37' => [ 'Kyocera', 'GRATINA KYF37', 'carrier' => 'au' ],
7863
  'KYL23' => [ 'Kyocera', 'miraie KYL23', 'carrier' => 'au' ],
7864
  'KYY21' => [ 'Kyocera', 'URBANO L01', 'carrier' => 'au' ],
7872
  'KYV36' => [ 'Kyocera', 'DIGNO rafre KYV36', 'carrier' => 'au' ],
7873
  'KYV37' => [ 'Kyocera', 'Qua phone', 'carrier' => 'au' ],
7874
  'KYV38' => [ 'Kyocera', 'URBANO V03 KYV38', 'carrier' => 'au' ],
 
7875
  'KYV40' => [ 'Kyocera', 'rafre KYV40', 'carrier' => 'au' ],
7876
  'KYV40U' => [ 'Kyocera', 'DIGNO W KYV40U', 'carrier' => 'UQ mobile' ],
7877
  'KYV41' => [ 'Kyocera', 'TORQUE G03 KYV41', 'carrier' => 'au' ],
7878
  'KYV42' => [ 'Kyocera', 'Qua phone QX', 'carrier' => 'au' ],
 
 
 
7879
  'KYT31' => [ 'Kyocera', 'Qua tab', DeviceType::TABLET, 'carrier' => 'au' ],
 
7880
  'KYT33' => [ 'Kyocera', 'Qua tab QZ10', DeviceType::TABLET, 'carrier' => 'au' ],
7881
  ],
7882
 
8793
  'LGAS991' => [ 'LG', 'G4' ],
8794
  'LG-AS9(91)!' => [ 'LG', 'G4' ],
8795
  'LGAS992' => [ 'LG', 'G5' ],
 
8796
  'LGAS995' => [ 'LG', 'G Flex 2' ],
 
8797
  ],
8798
 
8799
  'LG-?C[0-9]{3,3}!!' => [
8932
  'LG-F820!' => [ 'LG', 'U' ],
8933
  ],
8934
 
 
8935
  'LG-GT540!' => [ 'LG', 'Optimus' ],
8936
  'LG-GW620!' => [ 'LG', 'GW620 Eve' ],
8937
 
9046
  'LGL86C!' => [ 'LG', 'Optimus Showtime' ],
9047
  'LG-L95G!' => [ 'LG', 'L95G' ],
9048
  'LGL96G' => [ 'LG', 'Ultimate' ],
 
 
9049
  'LG-L160L' => [ 'LG', 'Optimus LTE2' ],
9050
  'LGL163BL' => [ 'LG', 'Fiesta 2' ],
9051
  'LGL164VL' => [ 'LG', 'Fiesta' ],
9133
  'LG-M4(30)!' => [ 'LG', 'Stylo 3' ],
9134
  'LG-M4(70)!' => [ 'LG', 'Stylo 3 Plus' ],
9135
  'LG-M7(00|03)!' => [ 'LG', 'Q6' ],
 
9136
  ],
9137
 
9138
  'LG-?MS[0-9]{3,3}!!' => [
9146
  'LGMS500' => [ 'LG', 'Optimus F6' ],
9147
  'LG-MS500' => [ 'LG', 'Optimus F6' ],
9148
  'LGMS550' => [ 'LG', 'G Stylo 2' ],
 
9149
  'LGMS631' => [ 'LG', 'G Stylo' ],
9150
  'LG-MS659' => [ 'LG', 'Optimus F3' ],
9151
  'LGMS659' => [ 'LG', 'Optimus F3' ],
9200
  'LG-P815!' => [ 'LG', 'G Pad II 8.3', DeviceType::TABLET ],
9201
  ],
9202
 
 
 
 
 
 
 
 
 
 
 
9203
  'LG-SU[0-9]{3,3}!!' => [
9204
  'LG-SU370' => [ 'LG', 'Optimus One' ],
9205
  'LG-SU540' => [ 'LG', 'PRADA 3.0' ],
9216
  'LG-TP260' => [ 'LG', 'K20 Plus' ],
9217
  'LG-TP450' => [ 'LG', 'Stylo 3 Plus' ],
9218
 
9219
+ 'RS988' => [ 'LG', 'G5' ],
9220
+
9221
  'LG-SU-760' => [ 'LG', 'Optimus 3D' ],
9222
  'LGUK410' => [ 'LG', 'G Pad 7.0', DeviceType::TABLET ],
9223
  'LG-UK495' => [ 'LG', 'G Pad F 8.0', DeviceType::TABLET ],
9230
  'LGUS215' => [ 'LG', 'K8 2017' ],
9231
  'LGUS375' => [ 'LG', 'K8' ],
9232
  'LGUS550' => [ 'LG', 'Logos' ],
 
9233
  'LGUS610' => [ 'LG', 'X Power' ],
9234
  'LG-US670' => [ 'LG', 'Optimus U' ],
9235
+ 'LG-US701' => [ 'LG', 'X venture' ],
 
9236
  'LG-US730' => [ 'LG', 'Splendor' ],
9237
  'LG-US780' => [ 'LG', 'Optimus F7' ],
9238
  'LGUS990!' => [ 'LG', 'G3' ],
9242
  'LGUS995!' => [ 'LG', 'G Flex 2' ],
9243
  'LG-US996!' => [ 'LG', 'V20' ],
9244
  'LG-US997' => [ 'LG', 'G6' ],
 
9245
  ],
9246
 
9247
  'LG-V[0-9]{3,3}!!' => [
9328
  'LGM-K120[KLS]!' => [ 'LG', 'X300' ],
9329
  'LGM-K121[KLS]!' => [ 'LG', 'X400' ],
9330
  'LGM-V300[KLS]!' => [ 'LG', 'V30' ],
 
9331
  'LGM-X320[KLS]!' => [ 'LG', 'X500' ],
9332
  'LGM-X401[S]!' => [ 'LG', 'X401' ],
9333
  'LGM-X600[KLS]!' => [ 'LG', 'Q6' ],
9336
 
9337
  'LM-G710!' => [ 'LG', 'G7 ThinQ' ],
9338
  'LM-G715!' => [ 'LG', 'G7 ThinQ' ],
 
 
9339
  'LM-Q610!' => [ 'LG', 'Q7' ],
 
9340
  'LM-Q710!' => [ 'LG', 'Q Stylus+' ],
 
 
 
 
 
 
9341
  'LM-V350!' => [ 'LG', 'V35 ThinQ' ],
 
 
 
 
9342
  'LM-X210!' => [ 'LG', 'Aristo 2' ],
 
 
 
9343
  'LM-X410!' => [ 'LG', 'X4' ],
9344
  'LM-X415!' => [ 'LG', 'X4+' ],
 
9345
  'LM-X510!' => [ 'LG', 'X5' ],
 
 
9346
  'LM-Y110!' => [ 'LG', 'Folder' ],
9347
 
9348
  'LGMP450' => [ 'LG', 'Stylo 3 Plus' ],
9366
  'LGL24' => [ 'LG', 'isai FL LGL24', 'carrier' => 'au' ],
9367
  'LGL25' => [ 'LG', 'Fx0 LGL25', 'carrier' => 'au' ],
9368
  'LGS01' => [ 'LG', 'Wine Smart LGS01', 'carrier' => 'J:COM' ],
 
9369
  'LGV31' => [ 'LG', 'isai VL LGV31', 'carrier' => 'au' ],
9370
  'LGV32' => [ 'LG', 'isai vivid LGV32', 'carrier' => 'au' ],
9371
  'LGV33' => [ 'LG', 'Qua phone PX LGV33', 'carrier' => 'au' ],
9832
  'LIFETAB S1033X' => [ 'Medion', 'Lifetab S1033X', DeviceType::TABLET ],
9833
  'LIFETAB S1034X' => [ 'Medion', 'Lifetab S1034X', DeviceType::TABLET ],
9834
  'LIFETAB S1036X' => [ 'Medion', 'Lifetab S1036X', DeviceType::TABLET ],
 
9835
  'MEDION LIFE P4012' => [ 'Medion', 'Life P4012' ],
9836
  'MEDION P4013' => [ 'Medion', 'Life P4013' ],
9837
  'MEDION-P4013' => [ 'Medion', 'Life P4013' ],
10574
  'XT19(02)!' => [ 'Lenovo', 'K8 Note' ],
10575
  ],
10576
 
 
 
 
 
 
 
 
10577
  'Atrix 2' => [ 'Motorola', 'ATRIX 2' ],
10578
  'Atrix 2 WeifanZ' => [ 'Motorola', 'ATRIX 2' ],
10579
  'Atrix 4G' => [ 'Motorola', 'ATRIX 4G' ],
10628
  '(Moto)?E2\(4G-LTE\)$!' => [ 'Motorola', 'Moto E (2015)' ],
10629
  'surnia' => [ 'Motorola', 'Moto E (2015)' ],
10630
  'Motorola MotoE2!' => [ 'Motorola', 'Moto E2' ],
 
10631
  'Moto E (4)' => [ 'Motorola', 'Moto E4' ],
10632
  'Moto E (4) Plus' => [ 'Motorola', 'Moto E4 Plus' ],
10633
  'moto e5 cruise' => [ 'Motorola', 'Moto E5 Cruise' ],
 
10634
  '(Moto)?G3$!' => [ 'Motorola', 'Moto G (2015)' ],
10635
  '(Moto)?G3-TE$!' => [ 'Motorola', 'Moto G (2015)' ],
 
 
 
10636
  'MOTOROLA MOTOG' => [ 'Motorola', 'Moto G' ],
10637
  'Moto G Play' => [ 'Motorola', 'Moto G Play' ],
 
10638
  'Moto G4' => [ 'Motorola', 'Moto G4' ],
 
10639
  'Moto G (4)' => [ 'Motorola', 'Moto G4' ],
10640
  'Moto G4 Plus' => [ 'Motorola', 'Moto G4 Plus' ],
 
 
10641
  'Moto G (5)' => [ 'Motorola', 'Moto G5' ],
10642
  'Moto G (5) Plus' => [ 'Motorola', 'Moto G5 Plus' ],
 
 
10643
  'Moto G (5S) Plus' => [ 'Motorola', 'Moto G5S Plus' ],
 
10644
  'moto g(6)' => [ 'Motorola', 'Moto G6' ],
 
 
 
10645
  'moto g(6) plus' => [ 'Motorola', 'Moto G6 Plus' ],
 
 
 
 
 
 
 
 
10646
  'Moto Z (2)' => [ 'Motorola', 'Moto Z2' ],
10647
  'Moto Z2 Play' => [ 'Motorola', 'Moto Z2 Play' ],
10648
  'Moto X Pro' => [ 'Motorola', 'Moto X Pro' ],
11049
  'TA-10(00|03|21|25|33|39)!' => [ 'Nokia', '6' ],
11050
  'TA-10(43|50|54|68)!' => [ 'Nokia', '6.1' ],
11051
  'TA-10(41)!' => [ 'Nokia', '7' ],
11052
+ 'TA-10(62)!' => [ 'Nokia', '7 plus' ],
11053
  'TA-10(04|12|52)!' => [ 'Nokia', '8' ],
11054
  'TA-10(99)!' => [ 'Nokia', 'X6' ],
11055
  'TA-11(03|16)!' => [ 'Nokia', 'X6' ],
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11056
  'Nokia N9' => [ 'Nokia', 'N9' ],
11057
  'Nokia N900' => [ 'Nokia', 'N900' ],
11058
  'Nokia X' => [ 'Nokia', 'X', DeviceType::MOBILE, Flag::NOKIAX ],
11184
  'ONEPLUS A5000' => [ 'OnePlus', '5' ],
11185
  'ONEPLUS A5010' => [ 'OnePlus', '5T' ],
11186
  'ONEPLUS A6000' => [ 'OnePlus', '6' ],
 
 
 
 
 
 
 
11187
  'ONE E1000' => [ 'OnePlus', 'X' ],
11188
  'ONE E1001' => [ 'OnePlus', 'X' ],
11189
  'ONE E1003' => [ 'OnePlus', 'X' ],
11228
  'N2T' => [ 'ONN', 'N2T', DeviceType::TABLET ],
11229
  'Renesas!' => [ 'Opad', 'Renesas', DeviceType::TABLET ],
11230
  'A11w' => [ 'Oppo', 'Joy 3' ],
 
 
 
 
 
 
 
 
 
 
 
 
 
11231
  'OPPO A30' => [ 'Oppo', 'A30' ],
11232
  'A31' => [ 'Oppo', 'A31' ],
11233
  'OPPO A31' => [ 'Oppo', 'A31' ],
11235
  'A31c' => [ 'Oppo', 'A31c' ],
11236
  'A31t' => [ 'Oppo', 'A31t' ],
11237
  'OPPO A31t' => [ 'Oppo', 'A31t' ],
 
11238
  'OPPO A33' => [ 'Oppo', 'A33' ],
11239
  'A33f' => [ 'Oppo', 'A33f' ],
11240
  'OPPO A33m' => [ 'Oppo', 'A33m' ],
11243
  'A37fw' => [ 'Oppo', 'A37fw' ],
11244
  'OPPO A37m' => [ 'Oppo', 'A37m' ],
11245
  'CPH1605' => [ 'Oppo', 'A39' ],
 
11246
  'A51f' => [ 'Oppo', 'A51f' ],
11247
  'OPPO A53' => [ 'Oppo', 'A53' ],
11248
  'OPPO A53m' => [ 'Oppo', 'A53m' ],
 
11249
  'CPH1701' => [ 'Oppo', 'A57' ],
11250
  'OPPO A57' => [ 'Oppo', 'A57' ],
11251
  'OPPO A57t' => [ 'Oppo', 'A57t' ],
11253
  'OPPO A59s' => [ 'Oppo', 'A59s' ],
11254
  'OPPO A59st' => [ 'Oppo', 'A59st' ],
11255
  'CPH1717' => [ 'Oppo', 'A71' ],
 
 
 
 
11256
  'OPPO A77' => [ 'Oppo', 'A77' ],
11257
  'OPPO A77t' => [ 'Oppo', 'A77t' ],
 
 
 
 
 
 
 
11258
  'OPPO A800' => [ 'Oppo', 'A800' ],
11259
  'A1603' => [ 'Oppo', 'C1' ],
11260
  'F1f' => [ 'Oppo', 'F1f' ],
11263
  'CPH1609' => [ 'Oppo', 'F3' ],
11264
  'CPH1613' => [ 'Oppo', 'F3 Plus' ],
11265
  'CPH1723' => [ 'Oppo', 'F5' ],
 
 
 
 
 
 
 
11266
  'Find 5' => [ 'Oppo', 'Find 5' ],
11267
  'X903' => [ 'Oppo', 'Find Me X903' ],
11268
  'X903S' => [ 'Oppo', 'Find X903S' ],
11279
  'X9000' => [ 'Oppo', 'Find 7a X9000' ],
11280
  'X9006' => [ 'Oppo', 'Find 7a X9006' ],
11281
  'X9007' => [ 'Oppo', 'Find 7a X9007' ],
 
11282
  'X9009' => [ 'Oppo', 'F1 Plus X9009' ],
11283
  'X9015' => [ 'Oppo', 'Find X9015' ],
11284
  'OPPOX9015' => [ 'Oppo', 'Find X9015' ],
11380
  'OPPOU7015' => [ 'Oppo', 'Find Way U7015' ],
11381
  'U7015' => [ 'Oppo', 'Find Way U7015' ],
11382
  'A51w' => [ 'Oppo', 'Mirror 5' ],
 
 
 
 
11383
  'OPPO N1' => [ 'Oppo', 'N1' ],
11384
  'N51(10|11|16|17)!' => [ 'Oppo', 'N1 mini' ],
11385
  'N52(06|07|09)!' => [ 'Oppo', 'N3' ],
 
 
11386
  'OPPO R7' => [ 'Oppo', 'R7' ],
 
 
11387
  'R7f' => [ 'Oppo', 'R7f' ],
11388
  'R7i' => [ 'Oppo', 'R7i' ],
11389
  'R7kf' => [ 'Oppo', 'R7kf' ],
11392
  'OPPO R7sm' => [ 'Oppo', 'R7sm' ],
11393
  'OPPO R7st' => [ 'Oppo', 'R7st' ],
11394
  'OPPO R7t' => [ 'Oppo', 'R7t' ],
 
 
11395
  'OPPO R9m' => [ 'Oppo', 'R9m' ],
11396
  'OPPO R9tm' => [ 'Oppo', 'R9tm' ],
11397
  'OPPO R9km' => [ 'Oppo', 'R9km' ],
11398
  'OPPO R9s' => [ 'Oppo', 'R9s' ],
11399
  'OPPO R9sk' => [ 'Oppo', 'R9sk' ],
11400
  'OPPO R9st' => [ 'Oppo', 'R9st' ],
 
11401
  'OPPO R9t' => [ 'Oppo', 'R9t' ],
11402
  'OPPO R9tm' => [ 'Oppo', 'R9tm' ],
11403
  'OPPO R11' => [ 'Oppo', 'R11' ],
 
11404
  'OPPO R11t' => [ 'Oppo', 'R11t' ],
11405
  'OPPO R7 Plus' => [ 'Oppo', 'R7 Plus' ],
11406
  'R7Plus' => [ 'Oppo', 'R7 Plus' ],
11411
  'OPPO R9 Plustm A' => [ 'Oppo', 'R9 Plus' ],
11412
  'CPH1611' => [ 'Oppo', 'R9s Plus' ],
11413
  'OPPO R9s Plus' => [ 'Oppo', 'R9s Plus' ],
 
11414
  'OPPO R11 Plus' => [ 'Oppo', 'R11 Plus' ],
11415
+ 'OPPO R11 Plusk' => [ 'Oppo', 'R11 Plus' ],
11416
+ 'OPPO R11 Pluskt' => [ 'Oppo', 'R11 Plus' ],
 
11417
  'OPPO R11s Plus' => [ 'Oppo', 'R11s Plus' ],
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11418
  'W8' => [ 'Oppo', 'W8' ],
 
11419
  '1105' => [ 'Oppo', '1105' ],
11420
  '1107' => [ 'Oppo', '1107' ],
11421
  'OB-OPPO 3005' => [ 'Oppo', '3005' ],
 
 
 
 
 
 
 
 
 
11422
 
11423
  'OPSSON!!' => [
11424
  'OPSSON D1' => [ 'Opsson', 'D1' ],
13014
  'SMT-i9100' => [ 'Samsung', 'Galaxy Tab 7.0', DeviceType::TABLET ],
13015
 
13016
  'SM-A[0-9]{3,3}!!' => [
 
 
 
 
 
 
13017
  'SM-A300!' => [ 'Samsung', 'Galaxy A3' ],
 
 
13018
  'SM-A310!' => [ 'Samsung', 'Galaxy A3 (2016)' ],
13019
  'SM-A320!' => [ 'Samsung', 'Galaxy A3 (2017)' ],
 
13020
  'SM-A430!' => [ 'Samsung', 'Galaxy A4' ],
13021
  'SM-A450!' => [ 'Samsung', 'Galaxy A4 (2017)' ],
 
13022
  'SM-A500!' => [ 'Samsung', 'Galaxy A5' ],
 
 
13023
  'SM-A510!' => [ 'Samsung', 'Galaxy A5 (2016)' ],
13024
  'SM-A520!' => [ 'Samsung', 'Galaxy A5 (2017)' ],
13025
  'SM-A530!' => [ 'Samsung', 'Galaxy A8 (2018)' ],
13026
  'SM-A600!' => [ 'Samsung', 'Galaxy A6 (2018)' ],
13027
  'SM-A6050!' => [ 'Samsung', 'Galaxy A9 Star Lite' ],
13028
  'SM-A605!' => [ 'Samsung', 'Galaxy A6+ (2018)' ],
 
13029
  'SM-A700!' => [ 'Samsung', 'Galaxy A7' ],
 
13030
  'SM-A710!' => [ 'Samsung', 'Galaxy A7 (2016)' ],
13031
  'SM-A720!' => [ 'Samsung', 'Galaxy A7 (2017)' ],
13032
  'SM-A730!' => [ 'Samsung', 'Galaxy A8+ (2018)' ],
 
13033
  'SM-A800!' => [ 'Samsung', 'Galaxy A8' ],
 
13034
  'SM-A810!' => [ 'Samsung', 'Galaxy A8 (2016)' ],
13035
  'SM-A850!' => [ 'Samsung', 'Galaxy Alpha' ],
13036
  'SM-A900!' => [ 'Samsung', 'Galaxy A9 (2016)' ],
13037
  'SM-A910!' => [ 'Samsung', 'Galaxy A9 Pro' ],
 
13038
  ],
13039
 
13040
  'SM-C[0-9]{3,3}!!' => [
13053
  'SM-E700!' => [ 'Samsung', 'Galaxy E7' ],
13054
  ],
13055
 
 
 
 
 
 
13056
  'SM-G[0-9]{3,3}!!' => [
13057
  'SM-G110!' => [ 'Samsung', 'Galaxy Pocket 2' ],
13058
  'SM-G130BT' => [ 'Samsung', 'Galaxy Young 2' ],
13118
  'SM-G850!' => [ 'Samsung', 'Galaxy Alpha' ],
13119
  'SM-G860!' => [ 'Samsung', 'Galaxy S5 Sport' ],
13120
  'SM-G870!' => [ 'Samsung', 'Galaxy S5 Active' ],
 
13121
  'SM-G880!' => [ 'Samsung', 'Galaxy S7 mini' ],
13122
+ 'SM-G885Y!' => [ 'Samsung', 'Galaxy A8 Star' ],
13123
  'SM-G8850!' => [ 'Samsung', 'Galaxy A9 Star' ],
 
13124
  'SM-G890!' => [ 'Samsung', 'Galaxy S6 Active' ],
13125
  'SM-G891!' => [ 'Samsung', 'Galaxy S7 Active' ],
13126
  'SM-G892!' => [ 'Samsung', 'Galaxy S8 Active' ],
13141
  'SM-G955!' => [ 'Samsung', 'Galaxy S8+' ],
13142
  'SM-G960!' => [ 'Samsung', 'Galaxy S9' ],
13143
  'SM-G965!' => [ 'Samsung', 'Galaxy S9+' ],
 
 
 
 
 
 
 
 
 
13144
  ],
13145
 
13146
  'SM-I9500' => [ 'Samsung', 'Galaxy S4' ],
13154
  'SM-J200!' => [ 'Samsung', 'Galaxy J2' ],
13155
  'SM-J210!' => [ 'Samsung', 'Galaxy J2 (2016)' ],
13156
  'SM-J250!' => [ 'Samsung', 'Galaxy J2 (2018)' ],
 
13157
  'SM-J3(10|20)!' => [ 'Samsung', 'Galaxy J3' ],
13158
  'SM-J311!' => [ 'Samsung', 'Galaxy J3 (2016)' ],
13159
  'SM-J321!' => [ 'Samsung', 'Galaxy Sol' ],
13161
  'SM-J327!' => [ 'Samsung', 'Galaxy J3 Emerge' ],
13162
  'SM-J330!' => [ 'Samsung', 'Galaxy J3 (2017)' ],
13163
  'SM-J337!' => [ 'Samsung', 'Galaxy J3 (2018)' ],
 
 
 
13164
  'SM-J500!' => [ 'Samsung', 'Galaxy J5' ],
13165
  'SM-J510!' => [ 'Samsung', 'Galaxy J5 (2016)' ],
13166
  'SM-J530!' => [ 'Samsung', 'Galaxy J5 (2017)' ],
 
 
13167
  'SM-J700!' => [ 'Samsung', 'Galaxy J7' ],
13168
  'SM-J701!' => [ 'Samsung', 'Galaxy J7 Core' ],
13169
  'SM-J710!' => [ 'Samsung', 'Galaxy J7 (2016)' ],
 
13170
  'SM-J727!' => [ 'Samsung', 'Galaxy J7 Perx' ],
13171
  'SM-J730!' => [ 'Samsung', 'Galaxy J7 (2017)' ],
13172
  'SM-J737!' => [ 'Samsung', 'Galaxy Wide 3' ],
13175
  'SM-J900!' => [ 'Samsung', 'Galaxy J9' ],
13176
  ],
13177
 
 
 
 
 
 
 
13178
  'SM-N[0-9]{3,4}!!' => [
13179
  'SM-N750[025789][QV]?!' => [ 'Samsung', 'Galaxy Note 3 Neo' ],
13180
  'SM-N750[LS]?!' => [ 'Samsung', 'Galaxy Note 3 Neo' ],
13189
  'SM-N935!' => [ 'Samsung', 'Galaxy Note FE' ],
13190
  'SM-N95[05]!' => [ 'Samsung', 'Galaxy Note 8' ],
13191
  'SM-N960!' => [ 'Samsung', 'Galaxy Note 9' ],
 
 
13192
  ],
13193
 
13194
  'SM-P[0-9]{3,3}!!' => [
13204
  'SM-S320VL' => [ 'Samsung', 'Galaxy Sky' ],
13205
  'SM-S327VL' => [ 'Samsung', 'Galaxy J3 Luna Pro' ],
13206
  'SM-S337TL' => [ 'Samsung', 'Galaxy J3 Luna Pro' ],
 
13207
  'SM-S550TL' => [ 'Samsung', 'Galaxy On5' ],
13208
  'SM-S727VL' => [ 'Samsung', 'Galaxy J7 Sky Pro' ],
13209
  'SM-S737TL' => [ 'Samsung', 'Galaxy J7 Sky Pro' ],
 
13210
  'SM-S765C' => [ 'Samsung', 'Galaxy Ace Style' ],
13211
  'SM-S766C' => [ 'Samsung', 'Galaxy Stardust' ],
 
13212
  'SM-S777C' => [ 'Samsung', 'Galaxy J1' ],
13213
  'SM-S780L' => [ 'Samsung', 'Galaxy Mega 6.3' ],
13214
  'SM-S820L' => [ 'Samsung', 'Galaxy Core Prime' ],
13239
  'SM-T36[05]!' => [ 'Samsung', 'Galaxy Tab Active 8.0', DeviceType::TABLET ],
13240
  'SM-T37[578]!' => [ 'Samsung', 'Galaxy Tab E 8.0', DeviceType::TABLET ],
13241
  'SM-T38[05]!' => [ 'Samsung', 'Galaxy Tab A 8.0 (2017)', DeviceType::TABLET ],
13242
+ 'SM-T39[5]!' => [ 'Samsung', 'Galaxy Tab Active2 8.0', DeviceType::TABLET ],
 
 
13243
  'SM-T520CC' => [ 'Samsung', 'Galaxy Tab Pro 10.1 Chef Collection', DeviceType::TABLET ],
13244
  'SM-T52[057]!' => [ 'Samsung', 'Galaxy Tab Pro 10.1', DeviceType::TABLET ],
13245
  'SM-T530NU' => [ 'Samsung', 'Galaxy Tab 4 Nook 10.1', DeviceType::TABLET ],
13248
  'SM-T53[157]!' => [ 'Samsung', 'Galaxy Tab 4 10.0', DeviceType::TABLET ],
13249
  'SM-T55[015]!' => [ 'Samsung', 'Galaxy Tab A 9.7', DeviceType::TABLET ],
13250
  'SM-T58[057]!' => [ 'Samsung', 'Galaxy Tab A 10.1 (2016)', DeviceType::TABLET ],
 
13251
  'SM-T56[0127]!' => [ 'Samsung', 'Galaxy Tab E 9.6', DeviceType::TABLET ],
 
13252
  'SM-T67[07]!' => [ 'Samsung', 'Galaxy View', DeviceType::TABLET ],
13253
  'SM-T70[057]!' => [ 'Samsung', 'Galaxy Tab S 8.4', DeviceType::TABLET ],
13254
  'SM-T71[05]!' => [ 'Samsung', 'Galaxy Tab S2 8.0', DeviceType::TABLET ],
13255
  'SM-T71[39]!' => [ 'Samsung', 'Galaxy Tab S2 8.0 (2016)', DeviceType::TABLET ],
 
13256
  'SM-T80[0157]!' => [ 'Samsung', 'Galaxy Tab S 10.5', DeviceType::TABLET ],
13257
  'SM-T81[057]!' => [ 'Samsung', 'Galaxy Tab S2 9.7', DeviceType::TABLET ],
13258
  'SM-T81[39]!' => [ 'Samsung', 'Galaxy Tab S2 9.7 (2016)', DeviceType::TABLET ],
13259
  'SM-T81[8]!' => [ 'Samsung', 'Galaxy Tab S2 Plus 9.7', DeviceType::TABLET ],
13260
  'SM-T82[057]!' => [ 'Samsung', 'Galaxy Tab S3 9.7', DeviceType::TABLET ],
13261
  'SM-T83[057]!' => [ 'Samsung', 'Galaxy Tab S4 10.5', DeviceType::TABLET ],
 
13262
  'SM-T90[05]!' => [ 'Samsung', 'Galaxy Tab Pro 12.2', DeviceType::TABLET ],
13263
  ],
13264
 
13401
  'SC-01G' => [ 'Samsung', 'GALAXY Note Edge SC-01G', 'carrier' => 'DoCoMo' ],
13402
  'SC-01H' => [ 'Samsung', 'GALAXY Active neo SC-01H', 'carrier' => 'DoCoMo' ],
13403
  'SC-01K' => [ 'Samsung', 'GALAXY Note 8 SC-01K', 'carrier' => 'DoCoMo' ],
 
 
13404
  'SC-02B' => [ 'Samsung', 'GALAXY S SC-02B', 'carrier' => 'DoCoMo' ],
13405
  'SC-02C' => [ 'Samsung', 'GALAXY S II SC-02C', 'carrier' => 'DoCoMo' ],
13406
  'SC-02D' => [ 'Samsung', 'GALAXY Tab 7.0 Plus SC-02D', DeviceType::TABLET, 'carrier' => 'DoCoMo' ],
13410
  'SC-02H' => [ 'Samsung', 'Galaxy S7 Edge SC-02H', 'carrier' => 'DoCoMo' ],
13411
  'SC-02J' => [ 'Samsung', 'Galaxy S8 SC-02J', 'carrier' => 'DoCoMo' ],
13412
  'SC-02K' => [ 'Samsung', 'Galaxy S9 SC-02K', 'carrier' => 'DoCoMo' ],
 
13413
  'SC-03D' => [ 'Samsung', 'GALAXY S II LTE SC-03D', 'carrier' => 'DoCoMo' ],
13414
  'SC-03E' => [ 'Samsung', 'GALAXY S III α SC-03E', 'carrier' => 'DoCoMo' ],
13415
  'SC03E' => [ 'Samsung', 'GALAXY S III α SC-03E', 'carrier' => 'DoCoMo' ],
13416
  'SC-03G' => [ 'Samsung', 'GALAXY Tab S 8.4 SC-03G', DeviceType::TABLET, 'carrier' => 'DoCoMo' ],
13417
  'SC-03J' => [ 'Samsung', 'GALAXY S8+ SC-03J', 'carrier' => 'DoCoMo' ],
13418
  'SC-03K' => [ 'Samsung', 'GALAXY S9+ SC-03K', 'carrier' => 'DoCoMo' ],
 
13419
  'SC-04D' => [ 'Samsung', 'GALAXY NEXUS SC-04D', 'carrier' => 'DoCoMo' ],
13420
  'SC-04E' => [ 'Samsung', 'GALAXY S4 SC-04E', 'carrier' => 'DoCoMo' ],
13421
  'SC-04F' => [ 'Samsung', 'GALAXY S5 SC-04F', 'carrier' => 'DoCoMo' ],
13422
  'SC-04G' => [ 'Samsung', 'GALAXY S6 Edge SC-04G', 'carrier' => 'DoCoMo' ],
13423
  'SC-04J' => [ 'Samsung', 'GALAXY Feel SC-04J', 'carrier' => 'DoCoMo' ],
 
13424
  'SC-05D' => [ 'Samsung', 'GALAXY Note SC-05D', 'carrier' => 'DoCoMo' ],
13425
  'SC-05G' => [ 'Samsung', 'GALAXY S6 SC-05G', 'carrier' => 'DoCoMo' ],
13426
  'SC-06D' => [ 'Samsung', 'GALAXY S III SC-06D', 'carrier' => 'DoCoMo' ],
13435
  'SCV31' => [ 'Samsung', 'GALAXY S6 Edge SCV31', 'carrier' => 'au' ],
13436
  'SCV32' => [ 'Samsung', 'GALAXY A8 SCV32', 'carrier' => 'au' ],
13437
  'SCV33' => [ 'Samsung', 'GALAXY S7 edge Injustice Edition SCV33', 'carrier' => 'au' ],
 
13438
  'SCV35' => [ 'Samsung', 'GALAXY S8+ SCV35', 'carrier' => 'au' ],
13439
  'SCV36' => [ 'Samsung', 'GALAXY S8 SCV36', 'carrier' => 'au' ],
13440
  'SCV37' => [ 'Samsung', 'GALAXY Note8 SCV37', 'carrier' => 'au' ],
 
 
 
 
13441
  ],
13442
 
13443
  'ISW11SC' => [ 'Samsung', 'GALAXY S II WiMAX ISW11SC', 'carrier' => 'au' ],
13606
  'SH-01H' => [ 'Sharp', 'AQUOS PHONE ZETA SH-01H', 'carrier' => 'DoCoMo' ],
13607
  'SH-01J' => [ 'Sharp', 'AQUOS ケータイ SH-01J', 'carrier' => 'DoCoMo' ],
13608
  'SH-01K' => [ 'Sharp', 'AQUOS sense SH-01K', 'carrier' => 'DoCoMo' ],
 
13609
  'SH-02D' => [ 'Sharp', 'AQUOS PHONE slider SH-02D', 'carrier' => 'DoCoMo' ],
13610
  'SH-02E' => [ 'Sharp', 'AQUOS PHONE ZETA SH-02E', 'carrier' => 'DoCoMo' ],
13611
  'SH-02F' => [ 'Sharp', 'AQUOS PHONE EX SH-02F', 'carrier' => 'DoCoMo' ],
13694
  'SHV35' => [ 'Sharp', 'AQUOS U SHV35', 'carrier' => 'au' ],
13695
  'SHV36' => [ 'Sharp', 'BASIO2 SHV36', 'carrier' => 'au' ],
13696
  'SHV37' => [ 'Sharp', 'AQUOS U SHV37', 'carrier' => 'au' ],
 
13697
  'SHV38' => [ 'Sharp', 'AQUOS SERIE mini SHV38', 'carrier' => 'au' ],
13698
  'SHV39' => [ 'Sharp', 'AQUOS R SHV39', 'carrier' => 'au' ],
13699
  'SHV40' => [ 'Sharp', 'AQUOS sense SHV40', 'carrier' => 'au' ],
 
13700
  'SHV41' => [ 'Sharp', 'AQUOS R compact SHV41', 'carrier' => 'au' ],
13701
  'SHV42' => [ 'Sharp', 'AQUOS R2 SHV42', 'carrier' => 'au' ],
13702
  ],
13938
  ],
13939
 
13940
  'G[0-9]{4,4}!!' => [
13941
+ 'G31(12|16|21|23|25)!' => [ 'Sony', 'Xperia XA1' ],
13942
  'G32(12|21|23|26)!' => [ 'Sony', 'Xperia XA1 Ultra' ],
13943
  'G33(11|12|13)!' => [ 'Sony', 'Xperia L1' ],
13944
  'G34(12|16|21|23|26)!' => [ 'Sony', 'Xperia XA1 Plus' ],
13949
  ],
13950
 
13951
  'H[0-9]{4,4}!!' => [
13952
+ 'H42(33)!' => [ 'Sony', 'Xperia XA2 Ultra' ],
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13953
  ],
13954
 
13955
  'E[0-9]{2,2}[a-z]!!' => [
14056
  'SO-01H' => [ 'Sony', 'Xperia Z5 SO-01H', 'carrier' => 'DoCoMo' ], // ...
14057
  'SO-01J' => [ 'Sony', 'Xperia XZ SO-01J', 'carrier' => 'DoCoMo' ], // ...
14058
  'SO-01K' => [ 'Sony', 'Xperia XZ1 SO-01K', 'carrier' => 'DoCoMo' ], // ...
 
14059
  'SO-02C' => [ 'Sony Ericsson', 'Xperia acro SO-02C', 'carrier' => 'DoCoMo' ], // Azusa
14060
  'SO-02D' => [ 'Sony Ericsson', 'Xperia NX SO-02D', 'carrier' => 'DoCoMo' ], // Nozomi
14061
  'SO-02E' => [ 'Sony', 'Xperia Z SO-02E', 'carrier' => 'DoCoMo' ], // Yuga
14072
  'SO-03H' => [ 'Sony', 'Xperia Z5 Premium SO-03H', 'carrier' => 'DoCoMo' ],
14073
  'SO-03J' => [ 'Sony', 'Xperia XZs SO-03J', 'carrier' => 'DoCoMo' ],
14074
  'SO-03K' => [ 'Sony', 'Xperia XZ2 SO-03K', 'carrier' => 'DoCoMo' ],
 
14075
  'SO-04D' => [ 'Sony', 'Xperia GX SO-04D', 'carrier' => 'DoCoMo' ], // Hayabusa
14076
  'SO-04E' => [ 'Sony', 'Xperia A SO-04E', 'carrier' => 'DoCoMo' ], // Dogo
14077
  'SO-04EM' => [ 'Sony', 'Xperia feat. HATSUNE MIKU SO-04E', 'carrier' => 'DoCoMo' ],
14079
  'SO-04G' => [ 'Sony', 'Xperia A4 SO-04G', 'carrier' => 'DoCoMo' ],
14080
  'SO-04H' => [ 'Sony', 'Xperia X Performance SO-04H', 'carrier' => 'DoCoMo' ],
14081
  'SO-04J' => [ 'Sony', 'Xperia XZ Premium SO-04J', 'carrier' => 'DoCoMo' ],
 
14082
  'SO-05D' => [ 'Sony', 'Xperia SX SO-05D', 'carrier' => 'DoCoMo' ], // Komachi
14083
  'SO-05F' => [ 'Sony', 'Xperia Tablet Z2 SO-05F', DeviceType::TABLET, 'carrier' => 'DoCoMo' ], // Castor
14084
  'SO-05G' => [ 'Sony', 'Xperia Tablet Z4 SO-05G', DeviceType::TABLET, 'carrier' => 'DoCoMo' ], // ...
14101
  'SOV34' => [ 'Sony', 'Xperia XZ SOV34', 'carrier' => 'au' ], // ...
14102
  'SOV35' => [ 'Sony', 'Xperia XZs SOV35', 'carrier' => 'au' ], // ...
14103
  'SOV36' => [ 'Sony', 'Xperia XZ1 SOV36', 'carrier' => 'au' ], // ...
14104
+ 'SOV37' => [ 'Sony', 'Xperia XZ2 SOV37', 'carrier' => 'au' ], // ...
 
 
 
14105
  ],
14106
 
14107
  '40[0-9]SO!!' => [
16492
  '(Xiaomi )?(Xiaomi|Xiaomi M|MI)[ \-]?5s Plus$!' => [ 'Xiaomi', 'Mi 5s Plus' ],
16493
  '(Xiaomi )?(Xiaomi|Xiaomi M|MI)[ \-]?5x$!' => [ 'Xiaomi', 'Mi 5x' ],
16494
  '(Xiaomi )?(Xiaomi|Xiaomi M|MI)[ \-]?6$!' => [ 'Xiaomi', 'Mi 6' ],
 
 
16495
  '(Xiaomi )?(Xiaomi|Xiaomi M|MI)[ \-]?A1$!' => [ 'Xiaomi', 'Mi A1' ],
16496
+ ],
16497
+
 
 
 
 
 
 
 
 
 
 
 
16498
  '(Xiaomi|Xiaomi Mi|MI) Note!!' => [
16499
  '(Xiaomi|Xiaomi Mi|MI) Note (LTE|4G)$!' => [ 'Xiaomi', 'Mi Note' ],
16500
  '(Xiaomi|Xiaomi Mi|MI) Note ?2!' => [ 'Xiaomi', 'Mi Note 2' ],
16505
 
16506
  '(Xiaomi )?(MI )?MAX$!' => [ 'Xiaomi', 'Mi Max' ],
16507
  '(Xiaomi )?(MI )?MAX 2$!' => [ 'Xiaomi', 'Mi Max 2' ],
 
16508
  '(Xiaomi )?(MI )?MIX$!' => [ 'Xiaomi', 'Mi MIX' ],
16509
  '(Xiaomi )?(MI )?MIX 2$!' => [ 'Xiaomi', 'Mi MIX 2' ],
16510
  '(Xiaomi )?(MI )?MIX 2S$!' => [ 'Xiaomi', 'Mi MIX 2S' ],
16536
  '(Xiaomi )?(Redmi|HM) ?5$!' => [ 'Xiaomi', 'Redmi 5' ],
16537
  '(Xiaomi )?(Redmi|HM) ?5 Plus!' => [ 'Xiaomi', 'Redmi 5 Plus' ],
16538
  '(Xiaomi )?(Redmi|HM) ?5A!' => [ 'Xiaomi', 'Redmi 5A' ],
 
 
 
 
 
 
16539
  '(Xiaomi )?Redmi[ \-]S2$!' => [ 'Xiaomi', 'Redmi S2' ],
16540
  '(Xiaomi )?Redmi[ \-]Y1$!' => [ 'Xiaomi', 'Redmi Y1' ],
16541
  '(Xiaomi )?Redmi[ \-]Y1 Lite!' => [ 'Xiaomi', 'Redmi Y1 Lite' ],
 
16542
  ],
16543
 
16544
  '(Xiaomi )?(Redmi|HM)[ \-]?Note!!' => [
16551
  '(Xiaomi )?Redmi[ \-]Note ?5$!' => [ 'Xiaomi', 'Redmi Note 5' ],
16552
  '(Xiaomi )?Redmi[ \-]Note ?5A!' => [ 'Xiaomi', 'Redmi Note 5A' ],
16553
  '(Xiaomi )?Redmi[ \-]Note 5 Pro!' => [ 'Xiaomi', 'Redmi Note 5 Pro' ],
 
 
 
16554
  ],
16555
 
16556
  '(Xiaomi |HM)?20!!' => [
16573
  '(Xiaomi |HM)?20160(51)!' => [ 'Xiaomi', 'Redmi Note 4' ],
16574
  ],
16575
 
 
 
16576
  'Xiaomi MDT2!' => [ 'Xiaomi', 'Mi 5x' ],
16577
  'Xiaomi MCT1!' => [ 'Xiaomi', 'Mi 6' ],
16578
  'Xiaomi MAT136!' => [ 'Xiaomi', 'Redmi 4X' ],
18083
  'GM 5 Plus d' => [ 'General Mobile', 'GM5 Plus' ],
18084
  'GM 6' => [ 'General Mobile', 'GM6' ],
18085
  'GM 6 d' => [ 'General Mobile', 'GM6' ],
 
18086
  'GM Discovery tab 8' => [ 'General Mobile', 'tab 8', DeviceType::TABLET ],
18087
  'etab5' => [ 'General Mobile', 'Etab 5', DeviceType::TABLET ],
18088
 
includes/vendor/whichbrowser/parser/data/models-ios.php CHANGED
@@ -54,16 +54,12 @@ DeviceModels::$IOS_MODELS = [
54
  'iPhone11,4' => [ 'Apple', 'iPhone XS Max', DeviceType::MOBILE ],
55
  'iPhone11,6' => [ 'Apple', 'iPhone XS Max', DeviceType::MOBILE ],
56
  'iPhone11,8' => [ 'Apple', 'iPhone XR', DeviceType::MOBILE ],
57
- 'iPhone12,1' => [ 'Apple', 'iPhone 11', DeviceType::MOBILE ],
58
- 'iPhone12,3' => [ 'Apple', 'iPhone 11 Pro', DeviceType::MOBILE ],
59
- 'iPhone12,5' => [ 'Apple', 'iPhone 11 Pro Max', DeviceType::MOBILE ],
60
  'iPod1,1' => [ 'Apple', 'iPod touch', DeviceType::MEDIA ],
61
  'iPod2,1' => [ 'Apple', 'iPod touch (2nd gen)', DeviceType::MEDIA ],
62
  'iPod3,1' => [ 'Apple', 'iPod touch (3rd gen)', DeviceType::MEDIA ],
63
  'iPod4,1' => [ 'Apple', 'iPod touch (4th gen)', DeviceType::MEDIA ],
64
  'iPod5,1' => [ 'Apple', 'iPod touch (5th gen)', DeviceType::MEDIA ],
65
  'iPod7,1' => [ 'Apple', 'iPod touch (6th gen)', DeviceType::MEDIA ],
66
- 'iPod9,1' => [ 'Apple', 'iPod touch (7th gen)', DeviceType::MEDIA ],
67
  'iPad1,1' => [ 'Apple', 'iPad', DeviceType::TABLET ],
68
  'iPad1,2' => [ 'Apple', 'iPad 2', DeviceType::TABLET ],
69
  'iPad2,1' => [ 'Apple', 'iPad 2', DeviceType::TABLET ],
@@ -104,18 +100,4 @@ DeviceModels::$IOS_MODELS = [
104
  'iPad7,4' => [ 'Apple', 'iPad Pro (10.5″)', DeviceType::TABLET ],
105
  'iPad7,5' => [ 'Apple', 'iPad (9.7″, 6th gen)', DeviceType::TABLET ],
106
  'iPad7,6' => [ 'Apple', 'iPad (9.7″, 6th gen)', DeviceType::TABLET ],
107
- 'iPad7,11' => [ 'Apple', 'iPad (10.2″, 7th gen)', DeviceType::TABLET ],
108
- 'iPad7,12' => [ 'Apple', 'iPad (10.2″, 7th gen)', DeviceType::TABLET ],
109
- 'iPad8,1' => [ 'Apple', 'iPad Pro (11.0″)', DeviceType::TABLET ],
110
- 'iPad8,2' => [ 'Apple', 'iPad Pro (11.0″)', DeviceType::TABLET ],
111
- 'iPad8,3' => [ 'Apple', 'iPad Pro (11.0″)', DeviceType::TABLET ],
112
- 'iPad8,4' => [ 'Apple', 'iPad Pro (11.0″)', DeviceType::TABLET ],
113
- 'iPad8,5' => [ 'Apple', 'iPad Pro (12.9″, 3rd gen)', DeviceType::TABLET ],
114
- 'iPad8,6' => [ 'Apple', 'iPad Pro (12.9″, 3rd gen)', DeviceType::TABLET ],
115
- 'iPad8,7' => [ 'Apple', 'iPad Pro (12.9″, 3rd gen)', DeviceType::TABLET ],
116
- 'iPad8,8' => [ 'Apple', 'iPad Pro (12.9″, 3rd gen)', DeviceType::TABLET ],
117
- 'iPad11,1' => [ 'Apple', 'iPad mini (5th gen)', DeviceType::TABLET ],
118
- 'iPad11,2' => [ 'Apple', 'iPad mini (5th gen)', DeviceType::TABLET ],
119
- 'iPad11,3' => [ 'Apple', 'iPad Air (3rd gen)', DeviceType::TABLET ],
120
- 'iPad11,4' => [ 'Apple', 'iPad Air (3rd gen)', DeviceType::TABLET ],
121
  ];
54
  'iPhone11,4' => [ 'Apple', 'iPhone XS Max', DeviceType::MOBILE ],
55
  'iPhone11,6' => [ 'Apple', 'iPhone XS Max', DeviceType::MOBILE ],
56
  'iPhone11,8' => [ 'Apple', 'iPhone XR', DeviceType::MOBILE ],
 
 
 
57
  'iPod1,1' => [ 'Apple', 'iPod touch', DeviceType::MEDIA ],
58
  'iPod2,1' => [ 'Apple', 'iPod touch (2nd gen)', DeviceType::MEDIA ],
59
  'iPod3,1' => [ 'Apple', 'iPod touch (3rd gen)', DeviceType::MEDIA ],
60
  'iPod4,1' => [ 'Apple', 'iPod touch (4th gen)', DeviceType::MEDIA ],
61
  'iPod5,1' => [ 'Apple', 'iPod touch (5th gen)', DeviceType::MEDIA ],
62
  'iPod7,1' => [ 'Apple', 'iPod touch (6th gen)', DeviceType::MEDIA ],
 
63
  'iPad1,1' => [ 'Apple', 'iPad', DeviceType::TABLET ],
64
  'iPad1,2' => [ 'Apple', 'iPad 2', DeviceType::TABLET ],
65
  'iPad2,1' => [ 'Apple', 'iPad 2', DeviceType::TABLET ],
100
  'iPad7,4' => [ 'Apple', 'iPad Pro (10.5″)', DeviceType::TABLET ],
101
  'iPad7,5' => [ 'Apple', 'iPad (9.7″, 6th gen)', DeviceType::TABLET ],
102
  'iPad7,6' => [ 'Apple', 'iPad (9.7″, 6th gen)', DeviceType::TABLET ],
 
 
 
 
 
 
 
 
 
 
 
 
 
 
103
  ];
includes/vendor/whichbrowser/parser/data/regexes/applications-bots.php CHANGED
@@ -2,4 +2,4 @@
2
 
3
  namespace WhichBrowser\Data;
4
 
5
- Applications::$BOTS_REGEX = '/(008|360|a6|abound|muncher|adaxas|addthis|admantx|ahrefsbot|archiver|altavista|curious|cloudfront|amorank|archive|jeeves|astra|backlink|baidu|bazqux|bingbot|msnbot|msmobot|bing|blogbridge|bloglines|bloglovin|blogpulse|blogram|blogtrot|blogshares|boardreader|browsershots|bubing|butterfly|heritrix|cliqz|cloudflare|comodo|commafeed|cbot|watchdog|datasearch|daumoa|digg|domain|exabot|exactseek|ezooms|facebook|fast|flamingo|fastladder|feed|wrangler|validator|fever|friendica|robot|genieo|fetchor|google|gomez|ichiro|gooblog|goorss|grammarly|grub|hatena|capture|heureka|htdig|httpmon|hubpages|spider|crawler|kouio|larbin|linkedin|linkdex|livedoor|ltx71|magpie|mapion|socialstreams|mixi|mnogo|monitor|yeti|netcraft|netvibes|newsblur|newsgator|orange|pages|psbot|pingdom|pinterest|postrank|python|comment|rssbar|hunter|quora|safesearch|scrapy|seznam|shopwiki|reader|simplepie|site24|sogou|sophora|soso|spdycheck|spinn|detector|summify|telegram|twisted|twitter|tiny|tlsprober|typhoeus|vagabondo|voila|vocus|mcrawler|w3bot|jigsaw|w3c|wayback|webindexer|wordpress|mechanize|xerka|sitemap|yacy|yandex|yahoo|y\!j|slurp|httpclient|nutch|synapse|indy|wget|curl|package|java|simple|libwww|lwp|urllib|php|pear|zend|ruby)/i';
2
 
3
  namespace WhichBrowser\Data;
4
 
5
+ Applications::$BOTS_REGEX = '/(008|360|a6|abound|muncher|adaxas|addthis|admantx|ahrefsbot|archiver|altavista|curious|cloudfront|amorank|archive|jeeves|astra|backlink|baidu|bazqux|bingbot|msnbot|msmobot|bing|blogbridge|bloglines|bloglovin|blogpulse|blogram|blogtrot|blogshares|boardreader|browsershots|bubing|butterfly|heritrix|cliqz|cloudflare|comodo|commafeed|cbot|watchdog|datasearch|daumoa|digg|domain|exabot|exactseek|ezooms|facebook|fast|flamingo|fastladder|feed|wrangler|validator|fever|friendica|robot|genieo|fetchor|google|gomez|ichiro|gooblog|goorss|grammarly|grub|hatena|capture|heureka|htdig|httpmon|hubpages|spider|crawler|kouio|larbin|linkedin|linkdex|livedoor|ltx71|magpie|mapion|socialstreams|mixi|mnogo|monitor|yeti|netcraft|netvibes|newsblur|newsgator|orange|pages|psbot|pingdom|pinterest|postrank|comment|rssbar|hunter|quora|safesearch|scrapy|seznam|shopwiki|reader|simplepie|site24|sogou|sophora|soso|spdycheck|spinn|detector|summify|telegram|twisted|twitter|tiny|tlsprober|typhoeus|vagabondo|voila|vocus|mcrawler|w3bot|jigsaw|w3c|wayback|webindexer|wordpress|mechanize|xerka|sitemap|yacy|yandex|yahoo|y\!j|slurp|httpclient|nutch|synapse|indy|wget|curl|package|java|simple|libwww|lwp|urllib|php|pear|zend|ruby)/i';
includes/vendor/whichbrowser/parser/data/regexes/applications-browsers.php CHANGED
@@ -2,4 +2,4 @@
2
 
3
  namespace WhichBrowser\Data;
4
 
5
- Applications::$BROWSERS_REGEX = '/(115|126|2345|qihu|7star|abrowse|acorn|acoo|aol|america|arachne|arora|aweb|avant|asw|aviator|flyflow|bdbrowser|bdspark|beamrise|blackwren|brave|byffox|camino|canure|charon|chromeplus|cometbird|comodo|dragon|conkeror|coolnovo|cunaguaro|cyberfox|daedalus|dillo|rhodonit|eudoraweb|flock|galeon|epiphany|ibrowse|icab|iceape|icecat|iceweasel|iridium|iron|kazehakase|kchrome|meleon|lbbrowser|lobo|lunascape|naenara|mxbrowser|mixshark|mlbrowser|netpositive|origyn|owb|orca|oregano|otter|palemoon|qtweb|qupzilla|rekonq|ryouko|saayaa|sleipnir|metasr|stainless|sunchrome|superbird|swing|tencent|tenfourfox|theworld|tungsten|vivaldi|voyager|waterfox|yabrowser|1password|3g explorer|4g explorer|atomiclite|au|awakening|baidu|bdmobile|bidu|baiduboxapp|browser|blazer|acheetahi|cornowser|coolmarket|cute|digia|doris|doroty|www browser|eui|go\.web|helium|huohoubrowser|surfboard|isurf|jig browser|jumanji|kiosk|lebrowser|liebao|macross|mammoth|mcent|mib|cmcs|motorola|netfrontlife|onebrowser|plink|polaris|openwave|up|km|oppo|quark|semc|stnc|sogou|symphony|ucpro|vivo|weblite|alti|aplix|awox|browserserver|isis|spyglass|oregan|viera|zetakey|bunjalloo|nwf|nuanti|wib|prince|demobrowser|dooble|dwb|evm|fireweb|hive|intermec|phantom|qt|roccat|raven|rockmelt|scope|slim|smbrowser|snowshoe|sputnik|surf|tao|taz|uzbl|villanova|vimb|wada|wavelink|webrender|webster|wyzo|yelang|yrcweb|linemode|lynx|links|w3m|nimbus|Webwasher|sankore|adapi|brightsign|coship)/i';
2
 
3
  namespace WhichBrowser\Data;
4
 
5
+ Applications::$BROWSERS_REGEX = '/(115|126|2345|qihu|7star|abrowse|acorn|acoo|aol|america|arachne|arora|aweb|avant|asw|aviator|flyflow|bdbrowser|bdspark|beamrise|blackwren|brave|byffox|camino|canure|charon|chromeplus|cometbird|comodo|dragon|conkeror|coolnovo|cunaguaro|cyberfox|daedalus|dillo|rhodonit|eudoraweb|flock|galeon|epiphany|ibrowse|icab|iceape|icecat|iceweasel|iridium|iron|kazehakase|kchrome|meleon|lbbrowser|lobo|lunascape|naenara|mxbrowser|mixshark|mlbrowser|netpositive|origyn|owb|orca|oregano|otter|palemoon|qtweb|qupzilla|rekonq|ryouko|saayaa|sleipnir|metasr|stainless|sunchrome|superbird|swing|tencent|tenfourfox|theworld|tungsten|vivaldi|voyager|waterfox|yabrowser|1password|3g explorer|4g explorer|atomiclite|au|awakening|baidu|bdmobile|bidu|baiduboxapp|browser|blazer|acheetahi|cornowser|coolmarket|cute|digia|doris|doroty|www browser|eui|go\.web|helium|huohoubrowser|surfboard|isurf|jig browser|jumanji|kiosk|lebrowser|liebao|macross|mammoth|mcent|mib|cmcs|motorola|netfrontlife|onebrowser|plink|polaris|openwave|up|km|quark|semc|stnc|sogou|symphony|ucpro|weblite|alti|aplix|awox|browserserver|isis|spyglass|oregan|viera|zetakey|bunjalloo|nwf|nuanti|wib|prince|demobrowser|dooble|dwb|evm|fireweb|hive|intermec|phantom|qt|roccat|raven|rockmelt|scope|slim|smbrowser|snowshoe|sputnik|surf|tao|taz|uzbl|villanova|vimb|wada|wavelink|webrender|webster|wyzo|yelang|yrcweb|linemode|lynx|links|w3m|nimbus|Webwasher|sankore|adapi|brightsign|coship)/i';
includes/vendor/whichbrowser/parser/phpunit.xml ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <phpunit
2
+ bootstrap="./vendor/autoload.php"
3
+ colors="false"
4
+ convertErrorsToExceptions="true"
5
+ convertNoticesToExceptions="true"
6
+ convertWarningsToExceptions="true"
7
+ verbose="true"
8
+ stopOnFailure="false"
9
+ processIsolation="false"
10
+ backupGlobals="false"
11
+ syntaxCheck="true"
12
+ >
13
+ <testsuites>
14
+ <testsuite name="WhichBrowser tests">
15
+ <directory suffix="Test.php">tests/unit</directory>
16
+ </testsuite>
17
+ </testsuites>
18
+
19
+ <filter>
20
+ <whitelist addUncoveredFilesFromWhitelist="true">
21
+ <directory suffix=".php">src/Model</directory>
22
+ <file>src/Parser.php</file>
23
+ <file>src/Analyser.php</file>
24
+ <file>src/Cache.php</file>
25
+ </whitelist>
26
+ </filter>
27
+
28
+ <logging>
29
+ <log type="coverage-html" target="./build" charset="UTF-8" highlight="false" lowUpperBound="35" highLowerBound="70"/>
30
+ </logging>
31
+
32
+ </phpunit>
includes/vendor/whichbrowser/parser/src/Analyser/Derive.php CHANGED
@@ -480,10 +480,6 @@ trait Derive
480
  if ($this->data->os->version->is('10.14')) {
481
  $this->data->os->version->nickname = 'Mojave';
482
  }
483
-
484
- if ($this->data->os->version->is('10.15')) {
485
- $this->data->os->version->nickname = 'Catalina';
486
- }
487
  }
488
  }
489
  }
480
  if ($this->data->os->version->is('10.14')) {
481
  $this->data->os->version->nickname = 'Mojave';
482
  }
 
 
 
 
483
  }
484
  }
485
  }
includes/vendor/whichbrowser/parser/src/Analyser/Header/Useragent/Browser.php CHANGED
@@ -15,8 +15,8 @@ trait Browser
15
  /* Detect major browsers */
16
  $this->detectSafari($ua);
17
  $this->detectExplorer($ua);
18
- $this->detectChrome($ua);
19
  $this->detectFirefox($ua);
 
20
  $this->detectEdge($ua);
21
  $this->detectOpera($ua);
22
 
@@ -491,13 +491,6 @@ trait Browser
491
  $this->data->browser->version = new Version([ 'value' => $match[2], 'details' => 1, 'hidden' => true ]);
492
  $this->data->browser->type = Constants\BrowserType::BROWSER;
493
  }
494
-
495
- if (preg_match('/Edg\/([0-9.]*)/u', $ua, $match)) {
496
- $this->data->browser->name = 'Edge';
497
- $this->data->browser->channel = '';
498
- $this->data->browser->version = new Version([ 'value' => $match[1], 'details' => 1 ]);
499
- $this->data->browser->type = Constants\BrowserType::BROWSER;
500
- }
501
  }
502
 
503
 
@@ -505,7 +498,7 @@ trait Browser
505
 
506
  private function detectOpera($ua)
507
  {
508
- if (!preg_match('/(OPR|OMI|Opera|OPiOS|OPT|Coast|Oupeng)/ui', $ua)) {
509
  return;
510
  }
511
 
@@ -643,16 +636,6 @@ trait Browser
643
  $this->data->browser->type = Constants\BrowserType::BROWSER;
644
  }
645
 
646
- if (preg_match('/OPT\/([0-9]\.[0-9.]+)?/u', $ua, $match)) {
647
- $this->data->browser->stock = false;
648
- $this->data->browser->name = 'Opera Touch';
649
- $this->data->browser->type = Constants\BrowserType::BROWSER;
650
-
651
- if (isset($match[1])) {
652
- $this->data->browser->version = new Version([ 'value' => $match[1], 'details' => 2 ]);
653
- }
654
- }
655
-
656
  if (preg_match('/Coast\/([0-9.]*)/u', $ua, $match)) {
657
  $this->data->browser->stock = false;
658
  $this->data->browser->name = 'Coast by Opera';
@@ -673,7 +656,7 @@ trait Browser
673
 
674
  private function detectFirefox($ua)
675
  {
676
- if (!preg_match('/(Firefox|GranParadiso|Namoroka|Shiretoko|Minefield|BonEcho|Fennec|Phoenix|Firebird|Minimo|FxiOS|Focus)/ui', $ua)) {
677
  return;
678
  }
679
 
@@ -777,12 +760,6 @@ trait Browser
777
  $this->data->browser->type = Constants\BrowserType::BROWSER;
778
  }
779
 
780
- if (preg_match('/Focus\/([0-9.]*)/u', $ua, $match)) {
781
- $this->data->browser->name = 'Firefox Focus';
782
- $this->data->browser->version = new Version([ 'value' => $match[1] ]);
783
- $this->data->browser->type = Constants\BrowserType::BROWSER;
784
- }
785
-
786
  if (preg_match('/Servo\/1.0 Firefox\//u', $ua)) {
787
  $this->data->browser->name = 'Servo Nightly Build';
788
  $this->data->browser->version = null;
@@ -1434,7 +1411,7 @@ trait Browser
1434
  }
1435
  }
1436
 
1437
- if (preg_match('/[^A-Z](Q)0?([0-9][A-Z])/u', $ua, $match)) {
1438
  $this->data->browser->name = 'Obigo ' . $match[1];
1439
  $this->data->browser->version = new Version($processObigoVersion($match[2]));
1440
  $this->data->browser->type = Constants\BrowserType::BROWSER;
15
  /* Detect major browsers */
16
  $this->detectSafari($ua);
17
  $this->detectExplorer($ua);
 
18
  $this->detectFirefox($ua);
19
+ $this->detectChrome($ua);
20
  $this->detectEdge($ua);
21
  $this->detectOpera($ua);
22
 
491
  $this->data->browser->version = new Version([ 'value' => $match[2], 'details' => 1, 'hidden' => true ]);
492
  $this->data->browser->type = Constants\BrowserType::BROWSER;
493
  }
 
 
 
 
 
 
 
494
  }
495
 
496
 
498
 
499
  private function detectOpera($ua)
500
  {
501
+ if (!preg_match('/(OPR|OMI|Opera|OPiOS|Coast|Oupeng)/ui', $ua)) {
502
  return;
503
  }
504
 
636
  $this->data->browser->type = Constants\BrowserType::BROWSER;
637
  }
638
 
 
 
 
 
 
 
 
 
 
 
639
  if (preg_match('/Coast\/([0-9.]*)/u', $ua, $match)) {
640
  $this->data->browser->stock = false;
641
  $this->data->browser->name = 'Coast by Opera';
656
 
657
  private function detectFirefox($ua)
658
  {
659
+ if (!preg_match('/(Firefox|GranParadiso|Namoroka|Shiretoko|Minefield|BonEcho|Fennec|Phoenix|Firebird|Minimo|FxiOS)/ui', $ua)) {
660
  return;
661
  }
662
 
760
  $this->data->browser->type = Constants\BrowserType::BROWSER;
761
  }
762
 
 
 
 
 
 
 
763
  if (preg_match('/Servo\/1.0 Firefox\//u', $ua)) {
764
  $this->data->browser->name = 'Servo Nightly Build';
765
  $this->data->browser->version = null;
1411
  }
1412
  }
1413
 
1414
+ if (preg_match('/(Q)0?([0-9][A-Z])/u', $ua, $match)) {
1415
  $this->data->browser->name = 'Obigo ' . $match[1];
1416
  $this->data->browser->version = new Version($processObigoVersion($match[2]));
1417
  $this->data->browser->type = Constants\BrowserType::BROWSER;
includes/vendor/whichbrowser/parser/src/Model/Primitive/Base.php CHANGED
@@ -76,6 +76,6 @@ class Base
76
  }
77
  }
78
 
79
- return implode(", ", $lines);
80
  }
81
  }
76
  }
77
  }
78
 
79
+ return implode($lines, ", ");
80
  }
81
  }
includes/vendor/whichbrowser/parser/src/Model/Primitive/NameVersion.php CHANGED
@@ -12,19 +12,14 @@ class NameVersion extends Base
12
  {
13
  /**
14
  * @var string $name The name
15
- */
16
- public $name;
17
-
18
- /**
19
  * @var string $alias An alternative name that is used for readable strings
20
- */
21
- public $alias;
22
-
23
- /**
24
  * @var \WhichBrowser\Model\Version $version Version information
25
  */
 
 
26
  public $version;
27
 
 
28
  /**
29
  * Set the properties to the default values
30
  *
12
  {
13
  /**
14
  * @var string $name The name
 
 
 
 
15
  * @var string $alias An alternative name that is used for readable strings
 
 
 
 
16
  * @var \WhichBrowser\Model\Version $version Version information
17
  */
18
+ public $name;
19
+ public $alias;
20
  public $version;
21
 
22
+
23
  /**
24
  * Set the properties to the default values
25
  *
includes/vendor/whichbrowser/parser/src/Model/Version.php CHANGED
@@ -251,7 +251,7 @@ class Version extends Base
251
  }
252
  }
253
 
254
- $version .= implode('.', $v);
255
 
256
  if (array_key_exists(5, $match) && strlen($match[5])) {
257
  $version .= $match[5] . (!empty($match[6]) ? $match[6] : '');
251
  }
252
  }
253
 
254
+ $version .= implode($v, '.');
255
 
256
  if (array_key_exists(5, $match) && strlen($match[5])) {
257
  $version .= $match[5] . (!empty($match[6]) ? $match[6] : '');
includes/vendor/whichbrowser/parser/tests/data/appliance/amstrad.yaml ADDED
@@ -0,0 +1,4 @@
 
 
 
 
1
+ -
2
+ headers: 'User-Agent: MobileExplorer/3.00 (Mozilla/1.22; compatible; MMEF300; Amstrad; Gamma)'
3
+ readable: 'Microsoft Mobile Explorer 3.0 on an Amstrad E-m@iler Plus'
4
+ result: { browser: { name: 'Microsoft Mobile Explorer', version: '3.0', type: browser }, device: { type: desktop, manufacturer: Amstrad, model: 'E-m@iler Plus' } }
includes/vendor/whichbrowser/parser/tests/data/appliance/familyhub.yaml ADDED
@@ -0,0 +1,4 @@
 
 
 
 
1
+ -
2
+ headers: 'User-Agent: Mozilla/5.0 (Linux; Tizen 2.3; FamilyHub) AppleWebKit/537.3 (KHTML, like Gecko) Version/2.3 Mobile Safari/537.3'
3
+ readable: 'Samsung Browser on a Samsung Family Hub running Tizen 2.3'
4
+ result: { browser: { name: 'Samsung Browser' }, engine: { name: Webkit, version: '537.3' }, os: { name: Tizen, version: '2.3' }, device: { type: appliance, manufacturer: Samsung, model: 'Family Hub' } }
includes/vendor/whichbrowser/parser/tests/data/appliance/i-opener.yaml ADDED
@@ -0,0 +1,4 @@
 
 
 
 
1
+ -
2
+ headers: 'User-Agent: Mozilla/3.x (I-Opener 1.1; Netpliance)'
3
+ readable: 'a Netpliance i-Opener'
4
+ result: { device: { type: desktop, manufacturer: Netpliance, model: i-Opener } }
includes/vendor/whichbrowser/parser/tests/data/appliance/weblight.yaml ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ -
2
+ headers: 'User-Agent: Mozilla/3.0 KOMATSU (AveFront/2.6 WebLight) WL/3.0 V2.45ohi M=11E2A2499945'
3
+ readable: 'NetFront 2.6 on a KOMATSU WebLight'
4
+ result: { browser: { name: NetFront, version: '2.6', type: browser }, engine: { name: NetFront }, device: { type: desktop, manufacturer: KOMATSU, model: WebLight } }
5
+ -
6
+ headers: 'User-Agent: Mozilla/3.0 KOMATSU WL/3.0'
7
+ readable: 'Netscape Navigator 3.0 on a KOMATSU WebLight'
8
+ result: { browser: { name: 'Netscape Navigator', version: '3.0', type: browser }, device: { type: desktop, manufacturer: KOMATSU, model: WebLight } }
includes/vendor/whichbrowser/parser/tests/data/bots/disabled.yaml ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ -
2
+ detectBots: false
3
+ headers: 'User-Agent: (Windows NT 10.0; Googlebot Googlebot-Image/1.0 msnbot-media/1.1 facebookexternalhit/1.1 Trident/7.0) Maxthon/4.4.5.3000 Firefox/38'
4
+ result: { browser: { name: "Maxthon", family: { name: "Firefox", version: "38" }, version: "4.4.5", type: "browser" }, engine: { name: "Trident", version: "7.0" }, os: { name: "Windows", version: { value: "10.0", alias: "10" } }, device: { type: "desktop" } }
5
+ readable: 'Maxthon 4.4.5 on Windows 10'
6
+ -
7
+ detectBots: false
8
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534+ (KHTML, like Gecko) MsnBot-Media /1.0b'
9
+ result: { engine: { name: "Webkit", version: "534" }, os: { name: "Windows", version: { value: "6.1", alias: "7" } }, device: { type: "desktop" } }
10
+ readable: 'an unknown browser based on Webkit 534 running on Windows 7'
11
+ -
12
+ detectBots: false
13
+ headers: 'User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A5376e Safari/8536.25 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)'
14
+ result: { browser: { name: "Safari", version: "6.0", type: "browser" }, engine: { name: "Webkit", version: "536.26" }, os: { name: "iOS", version: "6.0" }, device: { type: "mobile", subtype: "smart", manufacturer: "Apple", model: "iPhone" }}
15
+ readable: 'Safari on an Apple iPhone running iOS 6.0'
16
+ -
17
+ detectBots: false
18
+ headers: 'User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 7_0 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11A465 Safari/9537.53 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)'
19
+ result: { browser: { name: "Safari", version: "7.0", type: "browser" }, engine: { name: "Webkit", version: "537.51.1" }, os: { name: "iOS", version: "7.0" }, device: { type: "mobile", subtype: "smart", manufacturer: "Apple", model: "iPhone" }}
20
+ readable: 'Safari on an Apple iPhone running iOS 7.0'
21
+ -
22
+ detectBots: false
23
+ headers: 'User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko; Google Page Speed Insights) Chrome/27.0.1453 Safari/537.36'
24
+ result: { browser: { name: "Chrome", version: "27", type: "browser" }, engine: { name: "Blink" }, os: { name: "Linux" }, device: { type: "desktop" }, camouflage: true }
25
+ readable: 'an unknown browser that imitates Chrome 27 on Linux'
includes/vendor/whichbrowser/parser/tests/data/bots/false-positive.yaml ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ -
2
+ headers: 'User-Agent: Mozilla/5.0 (Linux; U; Android 4.2.2; tr-tr; S308 Build/CUBOT) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30 [FB_IAB/FB4A;FBAV/71.0.0.17.73;]'
3
+ readable: 'Facebook on a Cubot S308 running Android 4.2.2'
4
+ result: { browser: { name: Facebook, type: 'app:social' }, engine: { name: Webkit, version: '534.30' }, os: { name: Android, version: 4.2.2 }, device: { type: mobile, subtype: smart, manufacturer: Cubot, model: S308 } }
5
+ -
6
+ headers: 'User-Agent: Mozilla/5.0 (Linux; U; Android 4.2.2; de-de; CUBOT S108 Build/CUBOT) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30 [FB_IAB/FB4A;FBAV/55.0.0.18.66;]'
7
+ readable: 'Facebook on a Cubot S108 running Android 4.2.2'
8
+ result: { browser: { name: Facebook, type: 'app:social' }, engine: { name: Webkit, version: '534.30' }, os: { name: Android, version: 4.2.2 }, device: { type: mobile, subtype: smart, manufacturer: Cubot, model: S108 } }
includes/vendor/whichbrowser/parser/tests/data/bots/generic.yaml ADDED
@@ -0,0 +1,508 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ -
2
+ headers: 'User-Agent: (Windows NT 10.0; Googlebot Googlebot-Image/1.0 msnbot-media/1.1 facebookexternalhit/1.1 Trident/7.0) Maxthon/4.0'
3
+ result: { browser: { name: Bing, version: '1.1' }, device: { type: bot } }
4
+ readable: 'Bing 1.1'
5
+ -
6
+ headers: 'User-Agent: (Windows NT 10.0; Googlebot Googlebot-Image/1.0 msnbot-media/1.1 facebookexternalhit/1.1 Trident/7.0) Maxthon/4.4.5.3000 Firefox/38'
7
+ result: { browser: { name: Bing, version: '1.1' }, device: { type: bot } }
8
+ readable: 'Bing 1.1'
9
+ -
10
+ headers: 'User-Agent: 360spider-image'
11
+ result: { browser: { name: 360spider }, device: { type: bot } }
12
+ readable: 360spider
13
+ -
14
+ headers: 'User-Agent: 5acd734a-1ed3-4a17-ad9d-0b09ae7bc2d2/Nutch-1.7'
15
+ result: { browser: { name: 'Apache Nutch', version: '1.7' }, device: { type: bot } }
16
+ readable: 'Apache Nutch 1.7'
17
+ -
18
+ headers: 'User-Agent: ADmantX Platform Semantic Analyzer - ADmantX Inc. - www.admantx.com - support@admantx.com'
19
+ result: { browser: { name: ADmantX }, device: { type: bot } }
20
+ readable: ADmantX
21
+ -
22
+ headers: 'User-Agent: Aboundex/0.3 (http://www.aboundex.com/crawler/)'
23
+ result: { browser: { name: Aboundex, version: '0.3' }, device: { type: bot } }
24
+ readable: 'Aboundex 0.3'
25
+ -
26
+ headers: 'User-Agent: Ad Muncher v4.93.33707/4957'
27
+ result: { browser: { name: 'Ad Muncher', version: 4.93.33707 }, device: { type: bot } }
28
+ readable: 'Ad Muncher 4.93.33707'
29
+ -
30
+ headers: 'User-Agent: AddThis.com robot tech.support@clearspring.com'
31
+ result: { browser: { name: AddThis.com }, device: { type: bot } }
32
+ readable: AddThis.com
33
+ -
34
+ headers: 'User-Agent: AdsBot-Google ( http://www.google.com/adsbot.html)'
35
+ result: { browser: { name: 'Google Ads Bot' }, device: { type: bot } }
36
+ readable: 'Google Ads Bot'
37
+ -
38
+ headers: 'User-Agent: AdsBot-Google (+http://www.google.com/adsbot.html)'
39
+ result: { browser: { name: 'Google Ads Bot' }, device: { type: bot } }
40
+ readable: 'Google Ads Bot'
41
+ -
42
+ headers: 'User-Agent: AdsBot-Google-Mobile (+http://www.google.com/mobile/adsbot.html) Mozilla (iPhone; U; CPU iPhone OS 3 0 like Mac OS X) AppleWebKit (KHTML, like Gecko) Mobile Safari'
43
+ result: { browser: { name: 'Google Ads Bot' }, device: { type: bot } }
44
+ readable: 'Google Ads Bot'
45
+ -
46
+ headers: 'User-Agent: AdsBot-Google-Mobile (+http://www.google.com/mobile/adsbot.html) Mozilla (iPhone; U; CPU iPhone OS 3 0 like Mac OS X) AppleWebKit/537.36 (KHTML, like Gecko) Mobile Safari/537.36'
47
+ result: { browser: { name: 'Google Ads Bot' }, device: { type: bot } }
48
+ readable: 'Google Ads Bot'
49
+ -
50
+ headers: 'User-Agent: AhrefsBot.Feeds v0.1; http://ahrefs.com/'
51
+ result: { browser: { name: AhrefsBot, version: '0.1' }, device: { type: bot } }
52
+ readable: 'AhrefsBot 0.1'
53
+ -
54
+ headers: 'User-Agent: AmorankSpider/0.1; +http://amorank.com/webcrawler.html'
55
+ result: { browser: { name: 'Amorank Spider', version: '0.1' }, device: { type: bot } }
56
+ readable: 'Amorank Spider 0.1'
57
+ -
58
+ headers: 'User-Agent: AppEngine-Google; (+http://code.google.com/appengine; appid: xbmacx)'
59
+ result: { browser: { name: 'Google App Engine' }, device: { type: bot } }
60
+ readable: 'Google App Engine'
61
+ -
62
+ headers: 'User-Agent: ArchiveTeam ArchiveBot/20140807.01 (wpull 0.37a1) and not Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.125 Safari/537.36'
63
+ result: { browser: { name: ArchiveBot }, device: { type: bot } }
64
+ readable: ArchiveBot
65
+ -
66
+ headers: 'User-Agent: Backlink-Ceck.de (+http://www.backlink-check.de/bot.html)'
67
+ result: { browser: { name: Backlink-Check }, device: { type: bot } }
68
+ readable: Backlink-Check
69
+ -
70
+ headers: 'User-Agent: BacklinkCrawler (http://www.backlinktest.com/crawler.html)'
71
+ result: { browser: { name: BacklinkCrawler }, device: { type: bot } }
72
+ readable: BacklinkCrawler
73
+ -
74
+ headers: 'User-Agent: Baiduspider ( http://www.baidu.com/search/spider.htm)'
75
+ result: { browser: { name: Baiduspider }, device: { type: bot } }
76
+ readable: Baiduspider
77
+ -
78
+ headers: 'User-Agent: Baiduspider+(+http://www.baidu.com/search/spider_jp.html)'
79
+ result: { browser: { name: Baiduspider }, device: { type: bot } }
80
+ readable: Baiduspider
81
+ -
82
+ headers: 'User-Agent: Bloglovin/1.0 (http://www.bloglovin.com; 1 subscribers)'
83
+ result: { browser: { name: Bloglovin, version: '1.0' }, device: { type: bot } }
84
+ readable: 'Bloglovin 1.0'
85
+ -
86
+ headers: 'User-Agent: BlogramCrawler/1.0.1(+http://blogram.jp/)'
87
+ result: { browser: { name: Blogram, version: 1.0.1 }, device: { type: bot } }
88
+ readable: 'Blogram 1.0.1'
89
+ -
90
+ headers: 'User-Agent: Browsershots'
91
+ result: { browser: { name: Browsershots }, device: { type: bot } }
92
+ readable: Browsershots
93
+ -
94
+ headers: 'User-Agent: CCBot/2.0 (http://commoncrawl.org/faq/)'
95
+ result: { browser: { name: CommonCrawl, version: '2.0' }, device: { type: bot } }
96
+ readable: 'CommonCrawl 2.0'
97
+ -
98
+ headers: 'User-Agent: Cliqzbot/0.1 (+http://cliqz.com/company/cliqzbot)'
99
+ result: { browser: { name: Cliqzbot, version: '0.1' }, device: { type: bot } }
100
+ readable: 'Cliqzbot 0.1'
101
+ -
102
+ headers: 'User-Agent: CommaFeed/1.0 (http://www.commafeed.com)'
103
+ result: { browser: { name: CommaFeed, version: '1.0' }, device: { type: bot } }
104
+ readable: 'CommaFeed 1.0'
105
+ -
106
+ headers: 'User-Agent: CrawlerProcess (http://www.PowerMapper.com) /5.5.678.0'
107
+ result: { browser: { name: PowerMapper, version: 5.5.678.0 }, device: { type: bot } }
108
+ readable: 'PowerMapper 5.5.678.0'
109
+ -
110
+ headers: 'User-Agent: Curious George - www.analyticsseo.com/crawler'
111
+ result: { browser: { name: 'Analytics SEO' }, device: { type: bot } }
112
+ readable: 'Analytics SEO'
113
+ -
114
+ headers: 'User-Agent: Data-Hotel-Watchdog/1.1'
115
+ result: { browser: { name: 'Data Hotel Watchdog', version: '1.1' }, device: { type: bot } }
116
+ readable: 'Data Hotel Watchdog 1.1'
117
+ -
118
+ headers: 'User-Agent: DoCoMo/2.0 N905i(c100;TB;W24H16) (compatible; Googlebot-Mobile/2.1; +http://www.google.com/bot.html)'
119
+ result: { browser: { name: 'Googlebot Mobile', version: '2.1' }, device: { type: bot } }
120
+ readable: 'Googlebot Mobile 2.1'
121
+ -
122
+ headers: 'User-Agent: DoCoMo/2.0 P900i(c100;TB;W24H11) (compatible; ichiro/mobile goo; +http://help.goo.ne.jp/help/article/1142/)'
123
+ result: { browser: { name: Goo }, device: { type: bot } }
124
+ readable: Goo
125
+ -
126
+ headers: 'User-Agent: DoCoMo/2.0 SH905i(c100;TB;W24H16) (compatible; Mediapartners-Google/2.1; +http://www.google.com/bot.html)'
127
+ result: { browser: { name: 'Google Mediapartners', version: '2.1' }, device: { type: bot } }
128
+ readable: 'Google Mediapartners 2.1'
129
+ -
130
+ headers: 'User-Agent: ExactSeek Crawler (nutch 1.4)/Nutch-1.4 (ExactSeek Crawler; http://www.exactseek.com)'
131
+ result: { browser: { name: ExactSeek }, device: { type: bot } }
132
+ readable: ExactSeek
133
+ -
134
+ headers: 'User-Agent: FAST Enterprise Crawler/5.3.4 (crawler@fast.no)'
135
+ result: { browser: { name: 'FAST Enterprise Crawler', version: 5.3.4 }, device: { type: bot } }
136
+ readable: 'FAST Enterprise Crawler 5.3.4'
137
+ -
138
+ headers: 'User-Agent: FAST-WebCrawler/3.8 (atw-crawler at fast dot no; http://fast.no/support/crawler.asp)'
139
+ result: { browser: { name: 'FAST Web Crawler', version: '3.8' }, device: { type: bot } }
140
+ readable: 'FAST Web Crawler 3.8'
141
+ -
142
+ headers: 'User-Agent: FTRF: Friendly robot/1.3'
143
+ result: { browser: { name: 'FTRF: Friendly Robot', version: '1.3' }, device: { type: bot } }
144
+ readable: 'FTRF: Friendly Robot 1.3'
145
+ -
146
+ headers: 'User-Agent: FacebookSecurity/2.1 ([www.FacebookSecurity.com])'
147
+ result: { browser: { name: Facebook, version: '2.1' }, device: { type: bot } }
148
+ readable: 'Facebook 2.1'
149
+ -
150
+ headers: 'User-Agent: Fastladder FeedFetcher/0.01 (http://fastladder.com/; 27 subscribers)'
151
+ result: { browser: { name: Fastladder, version: '0.01' }, device: { type: bot } }
152
+ readable: 'Fastladder 0.01'
153
+ -
154
+ headers: 'User-Agent: Feed Wrangler/1.0 (3 subscribers; feed-id=248559; http://feedwrangler.net; Allow like Gecko)'
155
+ result: { browser: { name: FeedWrangler, version: '1.0' }, device: { type: bot } }
156
+ readable: 'FeedWrangler 1.0'
157
+ -
158
+ headers: 'User-Agent: FeedBurner/1.0 (http://www.FeedBurner.com)'
159
+ result: { browser: { name: 'Google FeedBurner', version: '1.0' }, device: { type: bot } }
160
+ readable: 'Google FeedBurner 1.0'
161
+ -
162
+ headers: 'User-Agent: FeedFetcher-Google; ( http://www.google.com/feedfetcher.html)'
163
+ result: { browser: { name: 'Google Feedfetcher' }, device: { type: bot } }
164
+ readable: 'Google Feedfetcher'
165
+ -
166
+ headers: 'User-Agent: Feedbin - 9 subscribers'
167
+ result: { browser: { name: Feedbin }, device: { type: bot } }
168
+ readable: Feedbin
169
+ -
170
+ headers: 'User-Agent: Feedfetcher-Google; (+http://www.google.com/feedfetcher.html; 19 subscribers; feed-id=13965549748850348809)'
171
+ result: { browser: { name: 'Google Feedfetcher' }, device: { type: bot } }
172
+ readable: 'Google Feedfetcher'
173
+ -
174
+ headers: 'User-Agent: FeedlyApp/1.0 (http://www.feedly.com)'
175
+ result: { browser: { name: Feedly, version: '1.0' }, device: { type: bot } }
176
+ readable: 'Feedly 1.0'
177
+ -
178
+ headers: 'User-Agent: FeedlyBot/1.0 (http://feedly.com)'
179
+ result: { browser: { name: Feedly, version: '1.0' }, device: { type: bot } }
180
+ readable: 'Feedly 1.0'
181
+ -
182
+ headers: 'User-Agent: Feedspot http://www.feedspot.com'
183
+ result: { browser: { name: Feedspot }, device: { type: bot } }
184
+ readable: Feedspot
185
+ -
186
+ headers: 'User-Agent: Fever/1.38 (Feed Parser; http://feedafever.com; Allow like Gecko)'
187
+ result: { browser: { name: Fever, version: '1.38' }, device: { type: bot } }
188
+ readable: 'Fever 1.38'
189
+ -
190
+ headers: 'User-Agent: Flamingo_SearchEngine (+http://www.flamingosearch.com/bot)'
191
+ result: { browser: { name: 'Flamingo Search' }, device: { type: bot } }
192
+ readable: 'Flamingo Search'
193
+ -
194
+ headers: 'User-Agent: Google-Sitemaps/1.0'
195
+ result: { browser: { name: 'Google Sitemaps', version: '1.0' }, device: { type: bot } }
196
+ readable: 'Google Sitemaps 1.0'
197
+ -
198
+ headers: 'User-Agent: GoogleProducer; (+http://goo.gl/7y4SX)'
199
+ result: { browser: { name: 'Google Play Newsstand' }, device: { type: bot } }
200
+ readable: 'Google Play Newsstand'
201
+ -
202
+ headers: 'User-Agent: Googlebot (gocrawl v0.4)'
203
+ result: { browser: { name: Gocrawl, version: '0.4' }, device: { type: bot } }
204
+ readable: 'Gocrawl 0.4'
205
+ -
206
+ headers: 'User-Agent: Googlebot-Image/1.0'
207
+ result: { browser: { name: 'Googlebot Image', version: '1.0' }, device: { type: bot } }
208
+ readable: 'Googlebot Image 1.0'
209
+ -
210
+ headers: 'User-Agent: Googlebot-News'
211
+ result: { browser: { name: 'Google News' }, device: { type: bot } }
212
+ readable: 'Google News'
213
+ -
214
+ headers: 'User-Agent: Googlebot-Video/1.0'
215
+ result: { browser: { name: 'Googlebot Video', version: '1.0' }, device: { type: bot } }
216
+ readable: 'Googlebot Video 1.0'
217
+ -
218
+ headers: 'User-Agent: Googlebot/2.1 ( http://www.googlebot.com/bot.html)'
219
+ result: { browser: { name: Googlebot, version: '2.1' }, device: { type: bot } }
220
+ readable: 'Googlebot 2.1'
221
+ -
222
+ headers: 'User-Agent: Googlebot/2.1 (+http://www.google.com/bot.html)'
223
+ result: { browser: { name: Googlebot, version: '2.1' }, device: { type: bot } }
224
+ readable: 'Googlebot 2.1'
225
+ -
226
+ headers: 'User-Agent: Googlebot/2.1(+http://www.googlebot.com/bot.html)'
227
+ result: { browser: { name: Googlebot, version: '2.1' }, device: { type: bot } }
228
+ readable: 'Googlebot 2.1'
229
+ -
230
+ headers: 'User-Agent: Mediapartners-Google'
231
+ result: { browser: { name: 'Google Mediapartners' }, device: { type: bot } }
232
+ readable: 'Google Mediapartners'
233
+ -
234
+ headers: 'User-Agent: MetaFeedly/1.0 (http://www.feedly.com)'
235
+ result: { browser: { name: Feedly, version: '1.0' }, device: { type: bot } }
236
+ readable: 'Feedly 1.0'
237
+ -
238
+ headers: 'User-Agent: Mozilla/2.0 (compatible; Ask Jeeves/Teoma)'
239
+ result: { browser: { name: 'Ask Jeeves' }, device: { type: bot } }
240
+ readable: 'Ask Jeeves'
241
+ -
242
+ headers: 'User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; Google Wireless Transcoder;)'
243
+ result: { browser: { name: 'Google Wireless Transcoder' }, device: { type: bot } }
244
+ readable: 'Google Wireless Transcoder'
245
+ -
246
+ headers: 'User-Agent: Mozilla/5.0 (Android; Mobile; rv:29.0) Gecko/29.0 Firefox/29.0 AppEngine-Google; (+http://code.google.com/appengine; appid: s~oldecreator)'
247
+ result: { browser: { name: 'Google App Engine' }, device: { type: bot } }
248
+ readable: 'Google App Engine'
249
+ -
250
+ headers: 'User-Agent: Mozilla/5.0 (Linux; U; Android 2.3.4; generic) AppleWebKit/537.4 (KHTML, like Gecko; Google Web Preview) Version/4.0 Mobile Safari/537.4'
251
+ result: { browser: { name: 'Google Web Preview' }, device: { type: bot } }
252
+ readable: 'Google Web Preview'
253
+ -
254
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Safari/537.36 Edge/13.11067 BingPreview/1.0b'
255
+ result: { browser: { name: 'Bing Preview', version: '1.0' }, device: { type: bot } }
256
+ readable: 'Bing Preview 1.0'
257
+ -
258
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.89 Safari/537.1; 360Spider'
259
+ result: { browser: { name: 360spider }, device: { type: bot } }
260
+ readable: 360spider
261
+ -
262
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1626.1 Safari/537.36 AppEngine-Google; (+http://code.google.com/appengine; appid: s~hex-plus)'
263
+ result: { browser: { name: 'Google App Engine' }, device: { type: bot } }
264
+ readable: 'Google App Engine'
265
+ -
266
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko AppEngine-Google; (+http://code.google.com/appengine; appid: s~oowsxs)'
267
+ result: { browser: { name: 'Google App Engine' }, device: { type: bot } }
268
+ readable: 'Google App Engine'
269
+ -
270
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/538.14 (KHTML, like Gecko) BingPreview/1.0b'
271
+ result: { browser: { name: 'Bing Preview', version: '1.0' }, device: { type: bot } }
272
+ readable: 'Bing Preview 1.0'
273
+ -
274
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:27.0) Gecko/20100101 Firefox/27.0 AppEngine-Google; (+http://code.google.com/appengine; appid: s~chengzhoukun)'
275
+ result: { browser: { name: 'Google App Engine' }, device: { type: bot } }
276
+ readable: 'Google App Engine'
277
+ -
278
+ headers: 'User-Agent: Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Nokia; Lumia 520) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Mobile Safari/537.36 Edge/12.0 BingPreview/1.0b'
279
+ result: { browser: { name: 'Bing Preview', version: '1.0' }, device: { type: bot } }
280
+ readable: 'Bing Preview 1.0'
281
+ -
282
+ headers: 'User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko; Google Page Speed Insights) Chrome/27.0.1453 Safari/537.36'
283
+ result: { browser: { name: 'Google Page Speed' }, device: { type: bot } }
284
+ readable: 'Google Page Speed'
285
+ -
286
+ headers: 'User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko; Google Page Speed Insights) Chrome/27.0.1453 Safari/537.36 GoogleBot/2.1'
287
+ result: { browser: { name: Googlebot, version: '2.1' }, device: { type: bot } }
288
+ readable: 'Googlebot 2.1'
289
+ -
290
+ headers: 'User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko; Google Web Preview) Chrome/27.0.1453 Safari/537.36'
291
+ result: { browser: { name: 'Google Web Preview' }, device: { type: bot } }
292
+ readable: 'Google Web Preview'
293
+ -
294
+ headers: 'User-Agent: Mozilla/5.0 (X11; U; Linux i686; xx; rv:1.9.2.18) Gecko/20110622 HeartRails_Capture/1.0.5 (+http://capture.heartrails.com/) Namoroka/3.6.18'
295
+ result: { browser: { name: 'HeartRails Capture', version: 1.0.5 }, device: { type: bot } }
296
+ readable: 'HeartRails Capture 1.0.5'
297
+ -
298
+ headers: 'User-Agent: Mozilla/5.0 (compatible; 008/0.83; http://www.80legs.com/webcrawler.html) Gecko/2008032620'
299
+ result: { browser: { name: 80legs, version: '0.83' }, device: { type: bot } }
300
+ readable: '80legs 0.83'
301
+ -
302
+ headers: 'User-Agent: Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html) ASProxy/5.5b5'
303
+ result: { browser: { name: Googlebot, version: '2.1' }, device: { type: bot } }
304
+ readable: 'Googlebot 2.1'
305
+ -
306
+ headers: 'User-Agent: Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Trident/6.0) BingPreview/1.0b'
307
+ result: { browser: { name: 'Bing Preview', version: '1.0' }, device: { type: bot } }
308
+ readable: 'Bing Preview 1.0'
309
+ -
310
+ headers: 'User-Agent: Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Trident/6.0; WOW64; Trident/6.0; BingPreview/1.0b)'
311
+ result: { browser: { name: 'Bing Preview', version: '1.0' }, device: { type: bot } }
312
+ readable: 'Bing Preview 1.0'
313
+ -
314
+ headers: 'User-Agent: Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0) CrawlerProcess (http://www.PowerMapper.com) /5.10.736.0'
315
+ result: { browser: { name: PowerMapper, version: 5.10.736.0 }, device: { type: bot } }
316
+ readable: 'PowerMapper 5.10.736.0'
317
+ -
318
+ headers: 'User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0); 360Spider'
319
+ result: { browser: { name: 360spider }, device: { type: bot } }
320
+ readable: 360spider
321
+ -
322
+ headers: 'User-Agent: Mozilla/5.0 (compatible; Yahoo! Slurp China; http://misc.yahoo.com.cn/help.html)'
323
+ result: { browser: { name: 'Yahoo! Slurp' }, device: { type: bot } }
324
+ readable: 'Yahoo! Slurp'
325
+ -
326
+ headers: 'User-Agent: Mozilla/5.0 (compatible; Yahoo! Slurp/3.0; http://help.yahoo.com/help/us/ysearch/slurp)'
327
+ result: { browser: { name: 'Yahoo! Slurp', version: '3.0' }, device: { type: bot } }
328
+ readable: 'Yahoo! Slurp 3.0'
329
+ -
330
+ headers: 'User-Agent: Mozilla/5.0 (compatible; Yahoo! Slurp/3.0; http://help.yahoo.com/help/us/ysearch/slurp) NOT Firefox/3.5'
331
+ result: { browser: { name: 'Yahoo! Slurp', version: '3.0' }, device: { type: bot } }
332
+ readable: 'Yahoo! Slurp 3.0'
333
+ -
334
+ headers: 'User-Agent: Mozilla/5.0 (compatible; bingbot/2.0 +http://www.bing.com/bingbot.htm)'
335
+ result: { browser: { name: Bing, version: '2.0' }, device: { type: bot } }
336
+ readable: 'Bing 2.0'
337
+ -
338
+ headers: 'User-Agent: Mozilla/5.0 (compatible; bingbot/2.0; )"'
339
+ result: { browser: { name: Bing, version: '2.0' }, device: { type: bot } }
340
+ readable: 'Bing 2.0'
341
+ -
342
+ headers: 'User-Agent: Mozilla/5.0 (compatible; bingbot/2.1; +http://www.bing.com/bingbot.htm)'
343
+ result: { browser: { name: Bing, version: '2.1' }, device: { type: bot } }
344
+ readable: 'Bing 2.1'
345
+ -
346
+ headers: 'User-Agent: Mozilla/5.0 (compatible; heritrix/1.14.4 +http://netarkivet.dk/webcrawler/)'
347
+ result: { browser: { name: CiteSeerX, version: 1.14.4 }, device: { type: bot } }
348
+ readable: 'CiteSeerX 1.14.4'
349
+ -
350
+ headers: 'User-Agent: Mozilla/5.0 (compatible; heritrix/3.1.2-SNAPSHOT-20131029-0036 +http://archive.org/details/archive.org_bot)'
351
+ result: { browser: { name: Archive.org }, device: { type: bot } }
352
+ readable: Archive.org
353
+ -
354
+ headers: 'User-Agent: Mozilla/5.0 (en-us) AppleWebKit/525.13 (KHTML, like Gecko; Google Web Preview) Version/3.1 Safari/525.13'
355
+ result: { browser: { name: 'Google Web Preview' }, device: { type: bot } }
356
+ readable: 'Google Web Preview'
357
+ -
358
+ headers: 'User-Agent: Mozilla/5.0 (en-us) AppleWebKit/534.14 (KHTML, like Gecko; Google Wireless Transcoder) Chrome/9.0.597 Safari/534.14'
359
+ result: { browser: { name: 'Google Wireless Transcoder' }, device: { type: bot } }
360
+ readable: 'Google Wireless Transcoder'
361
+ -
362
+ headers: 'User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A5376e Safari/8536.25 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)'
363
+ result: { browser: { name: Googlebot, version: '2.1' }, device: { type: bot } }
364
+ readable: 'Googlebot 2.1'
365
+ -
366
+ headers: 'User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 7_0 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11A465 Safari/9537.53 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)'
367
+ result: { browser: { name: Bing, version: '2.0' }, device: { type: bot } }
368
+ readable: 'Bing 2.0'
369
+ -
370
+ headers: 'User-Agent: Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; Google Web Preview Analytics) Chrome/27.0.1453 Safari/537.36 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)'
371
+ result: { browser: { name: Googlebot, version: '2.1' }, device: { type: bot } }
372
+ readable: 'Googlebot 2.1'
373
+ -
374
+ headers: 'User-Agent: Mozilla/5.0 AppleWebKit/537.4 (KHTML, like Gecko; compatible; Googlebot/2.1; +http://www.google.com/bot.html) Safari/537.4'
375
+ result: { browser: { name: Googlebot, version: '2.1' }, device: { type: bot } }
376
+ readable: 'Googlebot 2.1'
377
+ -
378
+ headers: 'User-Agent: Mozilla/5.0+(compatible;+Baiduspider/2.0;++http://www.baidu.com/search/spider.html)'
379
+ result: { browser: { name: Baiduspider, version: '2.0' }, device: { type: bot } }
380
+ readable: 'Baiduspider 2.0'
381
+ -
382
+ headers: 'User-Agent: Opera/30.0.1835.59 (X11; Linux i686; Ubuntu/14.10) Presto/2.12.388 Version/29.16 AppleWebKit/599.0+ (KHTML, like Gecko) Chrome/41.0.2272.118 Safari/537.36 FAST-WebCrawler/3.8'
383
+ result: { browser: { name: 'FAST Web Crawler', version: '3.8' }, device: { type: bot } }
384
+ readable: 'FAST Web Crawler 3.8'
385
+ -
386
+ headers: 'User-Agent: Scrapy/0.24.6 (+http://scrapy.org)'
387
+ result: { browser: { name: Scrapy, version: 0.24.6 }, device: { type: bot } }
388
+ readable: 'Scrapy 0.24.6'
389
+ -
390
+ headers: 'User-Agent: Wget/1.11.4'
391
+ result: { browser: { name: Wget, version: 1.11.4 }, device: { type: bot } }
392
+ readable: 'Wget 1.11.4'
393
+ -
394
+ headers: 'User-Agent: Wget/1.15 (linux-gnu)'
395
+ result: { browser: { name: Wget, version: '1.15' }, device: { type: bot } }
396
+ readable: 'Wget 1.15'
397
+ -
398
+ headers: 'User-Agent: Wget/1.16.1 (darwin14.0.0)'
399
+ result: { browser: { name: Wget, version: 1.16.1 }, device: { type: bot } }
400
+ readable: 'Wget 1.16.1'
401
+ -
402
+ headers: 'User-Agent: Wget/1.6'
403
+ result: { browser: { name: Wget, version: '1.6' }, device: { type: bot } }
404
+ readable: 'Wget 1.6'
405
+ -
406
+ headers: 'User-Agent: facebookexternalhit/1.1'
407
+ result: { browser: { name: Facebook, version: '1.1' }, device: { type: bot } }
408
+ readable: 'Facebook 1.1'
409
+ -
410
+ headers: 'User-Agent: facebookexternalhit/1.1 (+http(s)://www.facebook.com/externalhit_uatext.php)'
411
+ result: { browser: { name: Facebook, version: '1.1' }, device: { type: bot } }
412
+ readable: 'Facebook 1.1'
413
+ -
414
+ headers: 'User-Agent: facebookexternalhit/1.1 (+http://www.facebook.com/externalhit_uatext.php)'
415
+ result: { browser: { name: Facebook, version: '1.1' }, device: { type: bot } }
416
+ readable: 'Facebook 1.1'
417
+ -
418
+ headers: 'User-Agent: facebookscraper/1.0( http://www.facebook.com/sharescraper_help.php)'
419
+ result: { browser: { name: Facebook, version: '1.0' }, device: { type: bot } }
420
+ readable: 'Facebook 1.0'
421
+ -
422
+ headers: 'User-Agent: grub-client-1.5.3; (grub-client-1.5.3; Crawl your own stuff with http://grub.org)'
423
+ result: { browser: { name: Grub, version: 1.5.3 }, device: { type: bot } }
424
+ readable: 'Grub 1.5.3'
425
+ -
426
+ headers: 'User-Agent: mapion-news-bot/1.0 (http://www.mapion.co.jp/news/)'
427
+ result: { browser: { name: 'Mapian News Bot', version: '1.0' }, device: { type: bot } }
428
+ readable: 'Mapian News Bot 1.0'
429
+ -
430
+ headers: 'User-Agent: msnbot-NewsBlogs/2.0b (+http://search.msn.com/msnbot.htm)'
431
+ result: { browser: { name: Bing, version: '2.0' }, device: { type: bot } }
432
+ readable: 'Bing 2.0'
433
+ -
434
+ headers: 'User-Agent: msnbot/1.1 ( http://search.msn.com/msnbot.htm)'
435
+ result: { browser: { name: Bing, version: '1.1' }, device: { type: bot } }
436
+ readable: 'Bing 1.1'
437
+ -
438
+ headers: 'User-Agent: msnbot/2.0b ( http://search.msn.com/msnbot.htm)'
439
+ result: { browser: { name: Bing, version: '2.0' }, device: { type: bot } }
440
+ readable: 'Bing 2.0'
441
+ -
442
+ headers: 'User-Agent: Mozilla/3.0 (compatible; Indy Library)'
443
+ result: { browser: { name: 'Borland Delphi' }, device: { type: bot } }
444
+ readable: 'Borland Delphi'
445
+ -
446
+ headers: 'User-Agent: 1NET/Crawler (compatible; 1NET; robot; http://www.1NET.gr)'
447
+ result: { device: { type: bot } }
448
+ readable: 'an unknown bot'
449
+ -
450
+ headers: 'User-Agent: abot/0.1 (abot; http://www.abot.com; abot@abot.com)'
451
+ result: { device: { type: bot } }
452
+ readable: 'an unknown bot'
453
+ -
454
+ headers: 'User-Agent: Amfibibot/0.07 (Amfibi Robot; http://www.amfibi.com; agent@amfibi.com)'
455
+ result: { device: { type: bot } }
456
+ readable: 'an unknown bot'
457
+ -
458
+ headers: 'User-Agent: envolk/1.7 (+http://www.envolk.com/envolkspiderinfo.html)'
459
+ result: { device: { type: bot } }
460
+ readable: 'an unknown bot'
461
+ -
462
+ headers: 'User-Agent: EnaBot/1.2 (http://www.enaball.com/crawler.html)'
463
+ result: { device: { type: bot } }
464
+ readable: 'an unknown bot'
465
+ -
466
+ headers: 'User-Agent: EuripBot/0.5 (+http://www.eurip.com) PreCheck'
467
+ result: { device: { type: bot } }
468
+ readable: 'an unknown bot'
469
+ -
470
+ headers: 'User-Agent: FaviconArchiver/1.0 (+http://moblur.org/workshop/favicon_archive/)'
471
+ result: { device: { type: bot } }
472
+ readable: 'an unknown bot'
473
+ -
474
+ headers: 'User-Agent: Feedfetcher-feedraider; (+http://feedraider.com/help/feedfetcher.html; X subscribers; Allow like Gecko)'
475
+ result: { device: { type: bot } }
476
+ readable: 'an unknown bot'
477
+ -
478
+ headers: 'User-Agent: Mozilla/4.0 (compatible; MSIE 5.01; GomezAgent 2.0; Windows NT)'
479
+ result: { browser: { name: GomezAgent, version: '2.0' }, device: { type: bot } }
480
+ readable: 'GomezAgent 2.0'
481
+ -
482
+ headers: 'User-Agent: Mozilla/4.0 (compatible; MSIE 4.01; Windows CE; PPC; 240x320; SPV M700; OpVer 19.123.2.733) OrangeBot-Mobile 2008.0 (mobilesearch.support@orange-ftgroup.com)'
483
+ result: { browser: { name: OrangeBot }, device: { type: bot } }
484
+ readable: OrangeBot
485
+ -
486
+ headers: 'User-Agent: Mozilla/5.0 (compatible; XML Sitemaps Generator; http://www.xml-sitemaps.com) Gecko XML-Sitemaps/1.0'
487
+ result: { browser: { name: 'XML Sitemaps Generator', version: '1.0' }, device: { type: bot } }
488
+ readable: 'XML Sitemaps Generator 1.0'
489
+ -
490
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534+ (KHTML, like Gecko) MsnBot-Media /1.0b'
491
+ result: { browser: { name: Bing, version: '1.0' }, device: { type: bot } }
492
+ readable: 'Bing 1.0'
493
+ -
494
+ headers: 'User-Agent: Mozilla/5.0 (compatible; MSIE or Firefox mutant; not on Windows server;) Daumoa 4.0'
495
+ result: { browser: { name: Daumoa, version: '4.0' }, device: { type: bot } }
496
+ readable: 'Daumoa 4.0'
497
+ -
498
+ headers: 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.6) Gecko/20070725 Firefox/2.0.0.6 - James BOT - WebCrawler http://cognitiveseo.com/bot.html'
499
+ result: { browser: { name: JamesBOT }, device: { type: bot } }
500
+ readable: JamesBOT
501
+ -
502
+ headers: 'User-Agent: Pinterest/0.1'
503
+ readable: 'Pinterest 0.1'
504
+ result: { browser: { name: Pinterest, version: '0.1' }, device: { type: bot } }
505
+ -
506
+ headers: 'User-Agent: Pinterest/0.2 (+http://www.pinterest.com/)'
507
+ readable: 'Pinterest 0.2'
508
+ result: { browser: { name: Pinterest, version: '0.2' }, device: { type: bot } }
includes/vendor/whichbrowser/parser/tests/data/camera/os-android.yaml ADDED
@@ -0,0 +1,4 @@
 
 
 
 
1
+ -
2
+ headers: 'User-Agent: Mozilla/5.0 (Linux; U; Android 2.3.3; ja-jp; COOLPIX S800c Build/CP01_WW) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1'
3
+ result: { browser: { name: 'Android Browser' }, engine: { name: Webkit, version: '533.1' }, os: { name: Android, version: 2.3.3 }, device: { type: camera, manufacturer: Nikon, model: 'Coolpix S800c' } }
4
+ readable: 'Android Browser on a Nikon Coolpix S800c running Android 2.3.3'
includes/vendor/whichbrowser/parser/tests/data/camera/os-tizen.yaml ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ -
2
+ headers: 'User-Agent: Mozilla/5.0 (Linux; U; Android 4.3; ko-kr; SAMSUNG; NX30) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Mobile Safari/535.19'
3
+ result: { browser: { family: { name: Chrome, version: 18 } }, engine: { name: Webkit, version: '535.19' }, os: { name: Tizen }, device: { type: camera, manufacturer: Samsung, model: NX30 } }
4
+ readable: 'a Samsung NX30 running Tizen'
5
+ -
6
+ headers: 'User-Agent: Mozilla/5.0 (Linux; U; Tizen 1.0; xx; Samsung NX300) AppleWebKit/534.16 (KHTML, like Gecko) Version/1.0 Mobile Android compatible'
7
+ result: { engine: { name: Webkit, version: '534.16' }, os: { name: Tizen, version: '1.0' }, device: { type: camera, manufacturer: Samsung, model: NX300 } }
8
+ readable: 'a Samsung NX300 running Tizen 1.0'
includes/vendor/whichbrowser/parser/tests/data/car/tesla.yaml ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ -
2
+ headers: 'User-Agent: Mozilla/5.0 (X11; Linux) AppleWebKit/534.34 (KHTML, like Gecko) QtCarBrowser Safari/534.34'
3
+ result: { engine: { name: Webkit, version: '534.34' }, device: { type: car, manufacturer: Tesla, model: 'Model S' } }
4
+ readable: 'a Tesla Model S'
5
+ -
6
+ headers: 'User-Agent: Mozilla/5.0 (X11; U; Linux; C) AppleWebKit/533.3 (KHTML, like Gecko) QtCarBrowser Safari/533.3'
7
+ result: { engine: { name: Webkit, version: '533.3' }, device: { type: car, manufacturer: Tesla, model: 'Model S' } }
8
+ readable: 'a Tesla Model S'
includes/vendor/whichbrowser/parser/tests/data/car/volvo.yaml ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ -
2
+ headers: 'User-Agent: Mozilla/5.0 (VCC; 1.0; like Gecko) NetFront/4.2'
3
+ readable: 'NetFront 4.2'
4
+ result: { browser: { name: NetFront, version: '4.2', type: browser }, engine: { name: NetFront }, device: { type: car } }
5
+ -
6
+ headers: 'User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; MSIE 5.5; Windows NT 5.0) Opera 7.02 Bork-edition [en]'
7
+ useragent: 'Mozilla/5.0 (VCC; 1.0; like Gecko) NetFront/4.2'
8
+ readable: 'Opera 7.02 on Windows 2000'
9
+ result: { browser: { name: Opera, version: '7.02', type: browser }, engine: { name: Presto }, os: { name: Windows, version: { value: '5.0', alias: '2000' } }, device: { type: desktop } }
includes/vendor/whichbrowser/parser/tests/data/desktop/app-editor.yaml ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ -
2
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Brackets/1.1.0 Chrome/39.0.2171.36 Safari/537.36'
3
+ result: { browser: { name: Brackets, family: { name: Chrome, version: 39 }, version: 1.1.0, type: 'app:editor' }, engine: { name: Blink }, os: { name: 'OS X', version: { value: '10.9', nickname: Mavericks } }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
4
+ readable: 'Brackets 1.1.0 on OS X Mavericks 10.9'
5
+ -
6
+ headers: 'User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Atom/1.0.19 Chrome/43.0.2357.65 Electron/0.30.7 Safari/537.36'
7
+ result: { browser: { name: Atom, using: { name: Electron, version: 0.30.7 }, family: { name: Chrome, version: 43 }, version: 1.0.19, type: 'app:editor' }, engine: { name: Blink }, os: { name: Linux }, device: { type: desktop } }
8
+ readable: 'Atom 1.0.19 on Linux'
9
+ -
10
+ headers: 'User-Agent: Mozilla/3.0 (compatible; GoLive 6.0; Windows 2000)'
11
+ result: { browser: { name: 'Adobe GoLive', version: '6.0', type: 'app:editor' }, os: { name: Windows, version: { value: '5.0', alias: '2000' } }, device: { type: desktop } }
12
+ readable: 'Adobe GoLive 6.0 on Windows 2000'
13
+ -
14
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10) AppleWebKit/600.1.25 (KHTML, like Gecko) iWeb/304'
15
+ result: { browser: { name: iWeb, version: '3', type: 'app:editor' }, engine: { name: Webkit, version: 600.1.25 }, os: { name: 'OS X', version: { value: '10.10', nickname: Yosemite } }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
16
+ readable: 'iWeb 3 on OS X Yosemite 10.10'
17
+ -
18
+ headers: 'User-Agent: Mozilla/4.0 (IBM WebSphere Homepage Builder V12.0/Version 12.0.4.0)'
19
+ readable: 'IBM WebSphere Homepage Builder 12.0'
20
+ result: { browser: { name: 'IBM WebSphere Homepage Builder', version: '12.0', type: 'app:editor' } }
21
+ -
22
+ headers: 'User-Agent: Mozilla/4.0 (IBM WebSphere Homepage Builder V7.0/Version 7.0.1.0)'
23
+ readable: 'IBM WebSphere Homepage Builder 7.0'
24
+ result: { browser: { name: 'IBM WebSphere Homepage Builder', version: '7.0', type: 'app:editor' } }
25
+ -
26
+ headers: 'User-Agent: Mozilla/4.0 (IBM WebSphere Homepage Builder V10.0/Version 10.0.3.0)'
27
+ readable: 'IBM WebSphere Homepage Builder 10.0'
28
+ result: { browser: { name: 'IBM WebSphere Homepage Builder', version: '10.0', type: 'app:editor' } }
includes/vendor/whichbrowser/parser/tests/data/desktop/app-mediaplayer.yaml ADDED
@@ -0,0 +1,4 @@
 
 
 
 
1
+ -
2
+ headers: 'User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.28) Gecko/20130316 Nightingale/1.12.2 (20140112193149)'
3
+ result: { browser: { name: Nightingale, version: 1.12.2, type: 'app:mediaplayer' }, engine: { name: Gecko, version: 1.9.2 }, os: { name: Linux }, device: { type: desktop } }
4
+ readable: 'Nightingale 1.12.2 on Linux'
includes/vendor/whichbrowser/parser/tests/data/desktop/browser-arachne.yaml ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ -
2
+ headers: 'User-Agent: xChaos_Arachne/4.1.71;UE01 (DOS x86;WATTCP/1.05; 640x480,16c; www.arachne.cz)'
3
+ result: { browser: { name: Arachne, version: '1.71', type: browser }, device: { type: desktop } }
4
+ readable: 'Arachne 1.71'
5
+ -
6
+ headers: 'User-Agent: xChaos_Arachne/5.1.89;GPL,386+'
7
+ result: { browser: { name: Arachne, version: '1.89', type: browser }, device: { type: desktop } }
8
+ readable: 'Arachne 1.89'
includes/vendor/whichbrowser/parser/tests/data/desktop/browser-brave.yaml ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ -
2
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_2) AppleWebKit/537.36 (KHTML, like Gecko) brave/0.0.2 Chrome/47.0.2526.73 Electron/0.36.1 Safari/537.36'
3
+ result: { browser: { name: Brave, using: { name: Electron, version: 0.36.1 }, family: { name: Chrome, version: 47 }, version: 0.0.2, type: browser }, engine: { name: Blink }, os: { name: 'OS X', version: { value: '10.11', nickname: 'El Capitan' } }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
4
+ readable: 'Brave 0.0.2 on OS X El Capitan 10.11'
5
+ -
6
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_0) AppleWebKit/537.36 (KHTML, like Gecko) brave/0.7.7 Chrome/47.0.2526.73 Electron/0.36.2 Safari/537.36'
7
+ result: { browser: { name: Brave, using: { name: Electron, version: 0.36.2 }, family: { name: Chrome, version: 47 }, version: 0.7.7, type: browser }, engine: { name: Blink }, os: { name: 'OS X', version: { value: '10.11', nickname: 'El Capitan' } }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
8
+ readable: 'Brave 0.7.7 on OS X El Capitan 10.11'
9
+ -
10
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_2) AppleWebKit/537.36 (KHTML, like Gecko) brave/0.7.7 Chrome/47.0.2526.73 Electron/0.36.2 Safari/537.36'
11
+ result: { browser: { name: Brave, using: { name: Electron, version: 0.36.2 }, family: { name: Chrome, version: 47 }, version: 0.7.7, type: browser }, engine: { name: Blink }, os: { name: 'OS X', version: { value: '10.11', nickname: 'El Capitan' } }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
12
+ readable: 'Brave 0.7.7 on OS X El Capitan 10.11'
includes/vendor/whichbrowser/parser/tests/data/desktop/browser-chrome.yaml ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ -
2
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_8; en-US) AppleWebKit/532.0 (KHTML, like Gecko) Chrome/4.0.202.0 Safari/532.0'
3
+ result: { browser: { name: Chrome, version: 4.0.202.0, type: browser }, engine: { name: Webkit, version: '532.0' }, os: { name: 'OS X', alias: 'Mac OS X', version: '10.5' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
4
+ readable: 'Chrome Dev 4.0.202.0 on Mac OS X 10.5'
5
+ -
6
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_2; en-US) AppleWebKit/533.4 (KHTML, like Gecko) Chrome/5.0.375.99 Safari/533.4'
7
+ result: { browser: { name: Chrome, version: '5', type: browser }, engine: { name: Webkit, version: '533.4' }, os: { name: 'OS X', alias: 'Mac OS X', version: '10.6' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
8
+ readable: 'Chrome 5 on Mac OS X 10.6'
9
+ -
10
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 6.0) AppleWebKit/535.2 (KHTML, like Gecko) Chrome/15.0.874.120 Safari/535.2'
11
+ result: { browser: { name: Chrome, version: '15', type: browser }, engine: { name: Webkit, version: '535.2' }, os: { name: Windows, version: { value: '6.0', alias: Vista } }, device: { type: desktop } }
12
+ readable: 'Chrome 15 on Windows Vista'
13
+ -
14
+ headers: 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US) AppleWebKit/525.13 (KHTML, like Gecko) Chrome/0.2.149.27 Safari/525.13'
15
+ result: { browser: { name: Chrome, version: 0.2.149.27, type: browser }, engine: { name: Webkit, version: '525.13' }, os: { name: Windows, version: { value: '5.0', alias: '2000' } }, device: { type: desktop } }
16
+ readable: 'Chrome Beta 0.2.149.27 on Windows 2000'
17
+ -
18
+ headers: 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/525.19 (KHTML, like Gecko) Chrome/0.2.153.0 Safari/525.19'
19
+ result: { browser: { name: Chrome, version: 0.2.153.0, type: browser }, engine: { name: Webkit, version: '525.19' }, os: { name: Windows, version: { value: '5.1', alias: XP } }, device: { type: desktop } }
20
+ readable: 'Chrome Dev 0.2.153.0 on Windows XP'
21
+ -
22
+ headers: 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/525.19 (KHTML, like Gecko) Chrome/0.4.154.18 Safari/525.19'
23
+ result: { browser: { name: Chrome, version: 0.4.154.18, type: browser }, engine: { name: Webkit, version: '525.19' }, os: { name: Windows, version: { value: '5.1', alias: XP } }, device: { type: desktop } }
24
+ readable: 'Chrome Beta 0.4.154.18 on Windows XP'
25
+ -
26
+ headers: 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/525.19 (KHTML, like Gecko) Chrome/1.0.154.39 Safari/525.19'
27
+ result: { browser: { name: Chrome, version: '1', type: browser }, engine: { name: Webkit, version: '525.19' }, os: { name: Windows, version: { value: '5.1', alias: XP } }, device: { type: desktop } }
28
+ readable: 'Chrome 1 on Windows XP'
29
+ -
30
+ headers: 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.2; en-US) AppleWebKit/525.13 (KHTML, like Gecko) Chrome/0.2.149.6 Safari/525.13'
31
+ result: { browser: { name: Chrome, version: 0.2.149.6, type: browser }, engine: { name: Webkit, version: '525.13' }, os: { name: Windows, version: { value: '5.2', alias: 'Server 2003' } }, device: { type: desktop } }
32
+ readable: 'Chrome Beta 0.2.149.6 on Windows Server 2003'
33
+ -
34
+ headers: 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.2; en-US) AppleWebKit/530.4 (KHTML, like Gecko) Chrome/2.0.172.0 Safari/530.4'
35
+ result: { browser: { name: Chrome, version: '2', type: browser }, engine: { name: Webkit, version: '530.4' }, os: { name: Windows, version: { value: '5.2', alias: 'Server 2003' } }, device: { type: desktop } }
36
+ readable: 'Chrome 2 on Windows Server 2003'
37
+ -
38
+ headers: 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US) AppleWebKit/525.19 (KHTML, like Gecko) Chrome/1.0.154.43 Safari/525.19'
39
+ result: { browser: { name: Chrome, version: '1', type: browser }, engine: { name: Webkit, version: '525.19' }, os: { name: Windows, version: { value: '6.0', alias: Vista } }, device: { type: desktop } }
40
+ readable: 'Chrome 1 on Windows Vista'
41
+ -
42
+ headers: 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US) AppleWebKit/528.8 (KHTML, like Gecko) Chrome/2.0.156.1 Safari/528.8'
43
+ result: { browser: { name: Chrome, version: 2.0.156.1, type: browser }, engine: { name: Webkit, version: '528.8' }, os: { name: Windows, version: { value: '6.0', alias: Vista } }, device: { type: desktop } }
44
+ readable: 'Chrome Dev 2.0.156.1 on Windows Vista'
45
+ -
46
+ headers: 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US) AppleWebKit/531.3 (KHTML, like Gecko) Chrome/3.0.193.2 Safari/531.3'
47
+ result: { browser: { name: Chrome, version: 3.0.193.2, type: browser }, engine: { name: Webkit, version: '531.3' }, os: { name: Windows, version: { value: '6.0', alias: Vista } }, device: { type: desktop } }
48
+ readable: 'Chrome Dev 3.0.193.2 on Windows Vista'
49
+ -
50
+ headers: 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/525.19 (KHTML, like Gecko) Chrome/0.3.154.9 Safari/525.19'
51
+ result: { browser: { name: Chrome, version: 0.3.154.9, type: browser }, engine: { name: Webkit, version: '525.19' }, os: { name: Windows, version: { value: '6.1', alias: '7' } }, device: { type: desktop } }
52
+ readable: 'Chrome Beta 0.3.154.9 on Windows 7'
53
+ -
54
+ headers: 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/532.5 (KHTML, like Gecko) Chrome/4.1.249.1025 Safari/532.5'
55
+ result: { browser: { name: Chrome, version: '4.1', type: browser }, engine: { name: Webkit, version: '532.5' }, os: { name: Windows, version: { value: '6.1', alias: '7' } }, device: { type: desktop } }
56
+ readable: 'Chrome 4.1 on Windows 7'
57
+ -
58
+ headers: 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; it-IT) AppleWebKit/532.5 (KHTML, like Gecko) Chrome/4.0.249.25 Safari/532.5'
59
+ result: { browser: { name: Chrome, version: '4', type: browser }, engine: { name: Webkit, version: '532.5' }, os: { name: Windows, version: { value: '6.1', alias: '7' } }, device: { type: desktop } }
60
+ readable: 'Chrome 4 on Windows 7'
61
+ -
62
+ headers: 'User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.11 Safari/534.16'
63
+ result: { browser: { name: Chrome, version: '10', type: browser }, engine: { name: Webkit, version: '534.16' }, os: { name: Linux }, device: { type: desktop } }
64
+ readable: 'Chrome 10 on Linux'
includes/vendor/whichbrowser/parser/tests/data/desktop/browser-chromium.yaml ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ -
2
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.6+ (KHTML, like Gecko) Chromium/17.0.963.56 Chrome/17.0.963.56 Safari/537.6+'
3
+ result: { browser: { name: Chromium, family: { name: Chrome, version: 17 }, version: 17.0.963.56, type: browser }, engine: { name: Webkit, version: '537.6' }, os: { name: Windows, version: { value: '6.1', alias: '7' } }, device: { type: desktop } }
4
+ readable: 'Chromium 17.0.963.56 on Windows 7'
5
+ -
6
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.6+ (KHTML, like Gecko) Chromium/23.0.1271.95 Chrome/23.0.1271.95 Safari/537.6+'
7
+ result: { browser: { name: Chromium, family: { name: Chrome, version: 23 }, version: 23.0.1271.95, type: browser }, engine: { name: Webkit, version: '537.6' }, os: { name: Windows, version: { value: '6.2', alias: '8' } }, device: { type: desktop } }
8
+ readable: 'Chromium 23.0.1271.95 on Windows 8'
9
+ -
10
+ headers: 'User-Agent: Mozilla/5.0 (X11; FreeBSD amd64) AppleWebKit/538.1 (KHTML, like Gecko) Chromium/25.0.1349.2 Chrome/25.0.1349.2 Safari/538.1'
11
+ result: { browser: { name: Chromium, family: { name: Chrome, version: 25 }, version: 25.0.1349.2, type: browser }, engine: { name: Webkit, version: '538.1' }, os: { name: FreeBSD, family: BSD }, device: { type: desktop } }
12
+ readable: 'Chromium 25.0.1349.2 on FreeBSD'
13
+ -
14
+ headers: 'User-Agent: Mozilla/5.0 (X11; Linux armv7l) AppleWebKit/535.22+ (KHTML, like Gecko) Chromium/17.0.963.56 Chrome/17.0.963.56 Safari/535.22+'
15
+ result: { browser: { name: Chromium, family: { name: Chrome, version: 17 }, version: 17.0.963.56, type: browser }, engine: { name: Webkit, version: '535.22' }, os: { name: Linux }, device: { type: desktop } }
16
+ readable: 'Chromium 17.0.963.56 on Linux'
17
+ -
18
+ headers: 'User-Agent: Mozilla/5.0 (X11; Linux armv7l) AppleWebKit/537.42+ (KHTML, like Gecko) Chromium/25.0.1349.2 Chrome/25.0.1349.2 Safari/537.42+'
19
+ result: { browser: { name: Chromium, family: { name: Chrome, version: 25 }, version: 25.0.1349.2, type: browser }, engine: { name: Webkit, version: '537.42' }, os: { name: Linux }, device: { type: desktop } }
20
+ readable: 'Chromium 25.0.1349.2 on Linux'
21
+ -
22
+ headers: 'User-Agent: Mozilla/5.0 (X11; Linux i686 (x86_64)) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/33.0.1750.152 Chrome/33.0.1750.152 Safari/537.36'
23
+ result: { browser: { name: Chromium, family: { name: Chrome, version: 33 }, version: 33.0.1750.152, type: browser }, engine: { name: Blink }, os: { name: Ubuntu }, device: { type: desktop } }
24
+ readable: 'Chromium 33.0.1750.152 on Ubuntu'
25
+ -
26
+ headers: 'User-Agent: Mozilla/5.0 (X11; Linux i686) AppleWebKit/534.24 (KHTML, like Gecko) Ubuntu/11.04 Chromium/11.0.696.68 Chrome/11.0.696.68 Safari/534.24'
27
+ result: { browser: { name: Chromium, family: { name: Chrome, version: 11 }, version: 11.0.696.68, type: browser }, engine: { name: Webkit, version: '534.24' }, os: { name: Ubuntu, version: '11.04' }, device: { type: desktop } }
28
+ readable: 'Chromium 11.0.696.68 on Ubuntu 11.04'
29
+ -
30
+ headers: 'User-Agent: Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/29.0.1547.62 Chrome/29.0.1547.62 Safari/537.36'
31
+ result: { browser: { name: Chromium, family: { name: Chrome, version: 29 }, version: 29.0.1547.62, type: browser }, engine: { name: Blink }, os: { name: Ubuntu }, device: { type: desktop } }
32
+ readable: 'Chromium 29.0.1547.62 on Ubuntu'
33
+ -
34
+ headers: 'User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.2 (KHTML, like Gecko) Fedora/16 (NRCBBXGu8kHISSSeydKmMptKvoa0gMvZ1htgTp2WpNQ=) Chromium/21.0.1180.81 Chrome/21.0.1180.81 Safari/535.2'
35
+ result: { browser: { name: Chromium, family: { name: Chrome, version: 21 }, version: 21.0.1180.81, type: browser }, engine: { name: Webkit, version: '535.2' }, os: { name: Fedora }, device: { type: desktop } }
36
+ readable: 'Chromium 21.0.1180.81 on Fedora'
37
+ -
38
+ headers: 'User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/45.0.2454.7 Chrome/45.0.2454.7 Safari/537.36'
39
+ result: { browser: { name: Chromium, family: { name: Chrome, version: 45 }, version: 45.0.2454.7, type: browser }, engine: { name: Blink }, os: { name: Ubuntu }, device: { type: desktop } }
40
+ readable: 'Chromium 45.0.2454.7 on Ubuntu'
41
+ -
42
+ headers: 'User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.4 (KHTML, like Gecko) Chromium/18.0.1025.168 Chrome/18.0.1025.168 Safari/537.4'
43
+ result: { browser: { name: Chromium, family: { name: Chrome, version: 18 }, version: 18.0.1025.168, type: browser }, engine: { name: Webkit, version: '537.4' }, os: { name: Linux }, device: { type: desktop } }
44
+ readable: 'Chromium 18.0.1025.168 on Linux'
45
+ -
46
+ headers: 'User-Agent: Mozilla/5.0 (X11; U; Linux i686; xx) AppleWebKit/534.13 (KHTML, like Gecko) Ubuntu/10.10 Chromium/9.0.597.107 Chrome/9.0.597.107 Safari/534.13'
47
+ result: { browser: { name: Chromium, family: { name: Chrome, version: 9 }, version: 9.0.597.107, type: browser }, engine: { name: Webkit, version: '534.13' }, os: { name: Ubuntu, version: '10.10' }, device: { type: desktop } }
48
+ readable: 'Chromium 9.0.597.107 on Ubuntu 10.10'
49
+ -
50
+ headers: 'User-Agent: Mozilla/5.0 (Unknown; Linux mips) Chromium/25.0.1349.2'
51
+ result: { browser: { name: Chromium, family: { name: Chrome, version: 25 }, version: 25.0.1349.2, type: browser }, os: { name: Linux }, device: { type: desktop } }
52
+ readable: 'Chromium 25.0.1349.2 on Linux'
includes/vendor/whichbrowser/parser/tests/data/desktop/browser-edge.yaml ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ -
2
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.10162'
3
+ result: { browser: { name: Edge, version: '12', type: browser }, engine: { name: EdgeHTML, version: '12.10162' }, os: { name: Windows, version: { value: '10.0', alias: '10' } }, device: { type: desktop } }
4
+ readable: 'Edge 12 on Windows 10'
5
+ -
6
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.10240'
7
+ result: { browser: { name: Edge, version: '12', type: browser }, engine: { name: EdgeHTML, version: '12.10240' }, os: { name: Windows, version: { value: '10.0', alias: '10' } }, device: { type: desktop } }
8
+ readable: 'Edge 12 on Windows 10'
9
+ -
10
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.10525'
11
+ result: { browser: { name: Edge, version: '12', type: browser }, engine: { name: EdgeHTML, version: '12.10525' }, os: { name: Windows, version: { value: '10.0', alias: '10' } }, device: { type: desktop } }
12
+ readable: 'Edge 12 on Windows 10'
13
+ -
14
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Safari/537.36 Edge/13.10537'
15
+ result: { browser: { name: Edge, version: '13', type: browser }, engine: { name: EdgeHTML, version: '13.10537' }, os: { name: Windows, version: { value: '10.0', alias: '10' } }, device: { type: desktop } }
16
+ readable: 'Edge 13 on Windows 10'
17
+ -
18
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36 Edge/12.0'
19
+ result: { browser: { name: Edge, version: '12', type: browser }, engine: { name: EdgeHTML, version: '12.0' }, os: { name: Windows, version: { value: '10.0', alias: '10' } }, device: { type: desktop } }
20
+ readable: 'Edge 12 on Windows 10'
21
+ -
22
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.10240'
23
+ result: { browser: { name: Edge, version: '12', type: browser }, engine: { name: EdgeHTML, version: '12.10240' }, os: { name: Windows, version: { value: '10.0', alias: '10' } }, device: { type: desktop } }
24
+ readable: 'Edge 12 on Windows 10'
25
+ -
26
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.10514'
27
+ result: { browser: { name: Edge, version: '12', type: browser }, engine: { name: EdgeHTML, version: '12.10514' }, os: { name: Windows, version: { value: '10.0', alias: '10' } }, device: { type: desktop } }
28
+ readable: 'Edge 12 on Windows 10'
29
+ -
30
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 10.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Safari/537.36 Edge/14.11111'
31
+ result: { browser: { name: Edge, version: '14', type: browser }, engine: { name: EdgeHTML, version: '14.11111' }, os: { name: Windows, version: { value: '10.1', alias: '10' } }, device: { type: desktop } }
32
+ readable: 'Edge 14 on Windows 10'
includes/vendor/whichbrowser/parser/tests/data/desktop/browser-firefox.yaml ADDED
@@ -0,0 +1,256 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ -
2
+ headers: 'User-Agent: Mozilla/5.0 (BeOS; U; Haiku BePC; xx; rv:1.8.1.25pre) Gecko/20120930 BonEcho/2.0.0.22pre'
3
+ result: { browser: { name: Firefox, version: 2.0.0.22, type: browser }, engine: { name: Gecko, version: 1.8.1 }, os: { name: Haiku }, device: { type: desktop } }
4
+ readable: 'Firefox BonEcho 2.0.0.22 on Haiku'
5
+ -
6
+ headers: 'User-Agent: Mozilla/5.0 (ChoX11; U; RISC OS; xx; rv:1.8.1.20) Gecko/20090803 BonEcho/2.0.0.20'
7
+ result: { browser: { name: Firefox, version: 2.0.0.20, type: browser }, engine: { name: Gecko, version: 1.8.1 }, os: { name: 'RISC OS' }, device: { type: desktop } }
8
+ readable: 'Firefox BonEcho 2.0.0.20 on RISC OS'
9
+ -
10
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:19.0) Gecko/20121220 Firefox/19.0'
11
+ result: { browser: { name: Firefox, version: '19.0', type: browser }, engine: { name: Gecko, version: '19.0' }, os: { name: 'OS X', version: { value: '10.8', nickname: 'Mountain Lion' } }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
12
+ readable: 'Firefox 19.0 on OS X Mountain Lion 10.8'
13
+ -
14
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:20.0) Gecko/20130102 Firefox/20.0'
15
+ result: { browser: { name: Firefox, version: '20.0', type: browser }, engine: { name: Gecko, version: '20.0' }, os: { name: 'OS X', version: { value: '10.8', nickname: 'Mountain Lion' } }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
16
+ readable: 'Firefox 20.0 on OS X Mountain Lion 10.8'
17
+ -
18
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.8; xx; rv:1.9.0.19) Gecko/2010031218 Firefox/3.0.19'
19
+ result: { browser: { name: Firefox, version: 3.0.19, type: browser }, engine: { name: Gecko, version: 1.9.0 }, os: { name: 'OS X', version: { value: '10.8', nickname: 'Mountain Lion' } }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
20
+ readable: 'Firefox 3.0.19 on OS X Mountain Lion 10.8'
21
+ -
22
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; xx; rv:1.8.0.12) Gecko/20070508 Firefox/1.5.0.12'
23
+ result: { browser: { name: Firefox, version: 1.5.0.12, type: browser }, engine: { name: Gecko, version: 1.8.0 }, os: { name: 'OS X' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
24
+ readable: 'Firefox 1.5.0.12 on OS X'
25
+ -
26
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; xx; rv:1.8.1.15) Gecko/20080623 Firefox/2.0.0.15'
27
+ result: { browser: { name: Firefox, version: 2.0.0.15, type: browser }, engine: { name: Gecko, version: 1.8.1 }, os: { name: 'OS X' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
28
+ readable: 'Firefox 2.0.0.15 on OS X'
29
+ -
30
+ headers: 'User-Agent: Mozilla/5.0 (OS/2; U; Warp 3; xx; rv:1.8.1.17) Gecko/20080925 Firefox/2.0.0.17'
31
+ result: { browser: { name: Firefox, version: 2.0.0.17, type: browser }, engine: { name: Gecko, version: 1.8.1 }, os: { name: OS/2, version: { value: '3', nickname: Warp } }, device: { type: desktop } }
32
+ readable: 'Firefox 2.0.0.17 on OS/2 Warp 3'
33
+ -
34
+ headers: 'User-Agent: Mozilla/5.0 (OS/2; U; Warp 4.5; xx; rv:1.7.12) Gecko/20050922 Firefox/1.0.7'
35
+ result: { browser: { name: Firefox, version: 1.0.7, type: browser }, engine: { name: Gecko, version: 1.7.12 }, os: { name: OS/2, version: { value: '4.5', nickname: Warp } }, device: { type: desktop } }
36
+ readable: 'Firefox 1.0.7 on OS/2 Warp 4.5'
37
+ -
38
+ headers: 'User-Agent: Mozilla/5.0 (OS/2; U; Warp 4.5; xx; rv:1.8.1.11) Gecko/20071209 Firefox/2.0.0.11'
39
+ result: { browser: { name: Firefox, version: 2.0.0.11, type: browser }, engine: { name: Gecko, version: 1.8.1 }, os: { name: OS/2, version: { value: '4.5', nickname: Warp } }, device: { type: desktop } }
40
+ readable: 'Firefox 2.0.0.11 on OS/2 Warp 4.5'
41
+ -
42
+ headers: 'User-Agent: Mozilla/5.0 (OS/2; Warp 4.5; rv:10.0.9) Gecko/20100101 Firefox/10.0.9'
43
+ result: { browser: { name: Firefox, version: 10.0.9, type: browser }, engine: { name: Gecko, version: 10.0.9 }, os: { name: OS/2, version: { value: '4.5', nickname: Warp } }, device: { type: desktop } }
44
+ readable: 'Firefox 10.0.9 on OS/2 Warp 4.5'
45
+ -
46
+ headers: 'User-Agent: Mozilla/5.0 (OS/2; Warp 4.5; rv:17.0) Gecko/20100101 Firefox/17.0'
47
+ result: { browser: { name: Firefox, version: '17.0', type: browser }, engine: { name: Gecko, version: '17.0' }, os: { name: OS/2, version: { value: '4.5', nickname: Warp } }, device: { type: desktop } }
48
+ readable: 'Firefox 17.0 on OS/2 Warp 4.5'
49
+ -
50
+ headers: 'User-Agent: Mozilla/5.0 (OS/2; Warp 4.5; rv:31.0) Gecko/20100101 Firefox/31.0'
51
+ result: { browser: { name: Firefox, version: '31.0', type: browser }, engine: { name: Gecko, version: '31.0' }, os: { name: OS/2, version: { value: '4.5', nickname: Warp } }, device: { type: desktop } }
52
+ readable: 'Firefox 31.0 on OS/2 Warp 4.5'
53
+ -
54
+ headers: 'User-Agent: Mozilla/5.0 (OS/2; Warp 4.5; rv:6.0) Gecko/20100101 Firefox/6.0'
55
+ result: { browser: { name: Firefox, version: '6.0', type: browser }, engine: { name: Gecko, version: '6.0' }, os: { name: OS/2, version: { value: '4.5', nickname: Warp } }, device: { type: desktop } }
56
+ readable: 'Firefox 6.0 on OS/2 Warp 4.5'
57
+ -
58
+ headers: 'User-Agent: Mozilla/5.0 (Photon; U; QNX x86pc; xx; rv:1.8.1.20) Gecko/-0000001 BonEcho/2.0.0.20'
59
+ result: { browser: { name: Firefox, version: 2.0.0.20, type: browser }, engine: { name: Gecko, version: 1.8.1 }, os: { name: QNX }, device: { type: mobile, subtype: feature } }
60
+ readable: 'Firefox BonEcho 2.0.0.20 on QNX'
61
+ -
62
+ headers: 'User-Agent: Mozilla/5.0 (Photon; U; QNX x86pc; xx; rv:1.8.1.5pre) Gecko/20070709 BonEcho/2.0.0.5pre'
63
+ result: { browser: { name: Firefox, version: 2.0.0.5, type: browser }, engine: { name: Gecko, version: 1.8.1 }, os: { name: QNX }, device: { type: mobile, subtype: feature } }
64
+ readable: 'Firefox BonEcho 2.0.0.5 on QNX'
65
+ -
66
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 4.0; rv:35.0) Gecko/20100101 Firefox/35.0'
67
+ result: { browser: { name: Firefox, version: '35.0', type: browser }, engine: { name: Gecko, version: '35.0' }, os: { name: Windows, version: { value: '4.0', alias: 'NT 4.0' } }, device: { type: desktop } }
68
+ readable: 'Firefox 35.0 on Windows NT 4.0'
69
+ -
70
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:13.0) Gecko/20120329 Firefox/13.0a2'
71
+ result: { browser: { name: Firefox, version: 13.0a2, type: browser }, engine: { name: Gecko, version: '13.0' }, os: { name: Windows, version: { value: '5.1', alias: XP } }, device: { type: desktop } }
72
+ readable: 'Firefox Aurora 13.0a2 on Windows XP'
73
+ -
74
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:19.0) Gecko/19.0 Firefox/19.0'
75
+ result: { browser: { name: Firefox, version: '19.0', type: browser }, engine: { name: Gecko, version: '19.0' }, os: { name: Windows, version: { value: '5.1', alias: XP } }, device: { type: desktop } }
76
+ readable: 'Firefox 19.0 on Windows XP'
77
+ -
78
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:2.0b6) Gecko/20100101 Firefox/4.0b6'
79
+ result: { browser: { name: Firefox, version: 4.0b6, type: browser }, engine: { name: Gecko, version: 2.0b6 }, os: { name: Windows, version: { value: '5.1', alias: XP } }, device: { type: desktop } }
80
+ readable: 'Firefox Beta 4.0b6 on Windows XP'
81
+ -
82
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 5.2; WOW64; rv:15.0) Gecko/20100101 Firefox/15.0'
83
+ result: { browser: { name: Firefox, version: '15.0', type: browser }, engine: { name: Gecko, version: '15.0' }, os: { name: Windows, version: { value: '5.2', alias: 'Server 2003' } }, device: { type: desktop } }
84
+ readable: 'Firefox 15.0 on Windows Server 2003'
85
+ -
86
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 6.0; rv:21.0) Gecko/20130113 Firefox/21.0'
87
+ result: { browser: { name: Firefox, version: '21.0', type: browser }, engine: { name: Gecko, version: '21.0' }, os: { name: Windows, version: { value: '6.0', alias: Vista } }, device: { type: desktop } }
88
+ readable: 'Firefox 21.0 on Windows Vista'
89
+ -
90
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 6.0; rv:3.0) Gecko/20100101 Firefox/3.0'
91
+ result: { browser: { name: Firefox, version: '3.0', type: browser }, engine: { name: Gecko, version: '3.0' }, os: { name: Windows, version: { value: '6.0', alias: Vista } }, device: { type: desktop } }
92
+ readable: 'Firefox 3.0 on Windows Vista'
93
+ -
94
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 6.0; rv:5.0) Gecko/20100101 Firefox/5.0'
95
+ result: { browser: { name: Firefox, version: '5.0', type: browser }, engine: { name: Gecko, version: '5.0' }, os: { name: Windows, version: { value: '6.0', alias: Vista } }, device: { type: desktop } }
96
+ readable: 'Firefox 5.0 on Windows Vista'
97
+ -
98
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:25.0) Gecko/20130627 Firefox/25.0'
99
+ result: { browser: { name: Firefox, version: '25.0', type: browser }, engine: { name: Gecko, version: '25.0' }, os: { name: Windows, version: { value: '6.1', alias: '7' } }, device: { type: desktop } }
100
+ readable: 'Firefox 25.0 on Windows 7'
101
+ -
102
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:16.0) Gecko/16.0 Firefox/16.0'
103
+ result: { browser: { name: Firefox, version: '16.0', type: browser }, engine: { name: Gecko, version: '16.0' }, os: { name: Windows, version: { value: '6.1', alias: '7' } }, device: { type: desktop } }
104
+ readable: 'Firefox 16.0 on Windows 7'
105
+ -
106
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:7.0) Gecko/20110814 Firefox/7.0'
107
+ result: { browser: { name: Firefox, version: '7.0', type: browser }, engine: { name: Gecko, version: '7.0' }, os: { name: Windows, version: { value: '6.1', alias: '7' } }, device: { type: desktop } }
108
+ readable: 'Firefox 7.0 on Windows 7'
109
+ -
110
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 6.2; rv:20.0) Gecko/20130129 Firefox/20.0'
111
+ result: { browser: { name: Firefox, version: '20.0', type: browser }, engine: { name: Gecko, version: '20.0' }, os: { name: Windows, version: { value: '6.2', alias: '8' } }, device: { type: desktop } }
112
+ readable: 'Firefox 20.0 on Windows 8'
113
+ -
114
+ headers: 'User-Agent: Mozilla/5.0 (Windows; U; Win95; xx; rv:1.7.13) Gecko/20060410 Firefox/1.0.8'
115
+ result: { browser: { name: Firefox, version: 1.0.8, type: browser }, engine: { name: Gecko, version: 1.7.13 }, os: { name: Windows, version: { value: '4.0', alias: '95' } }, device: { type: desktop } }
116
+ readable: 'Firefox 1.0.8 on Windows 95'
117
+ -
118
+ headers: 'User-Agent: Mozilla/5.0 (Windows; U; Win98; xx; rv:1.7.12) Gecko/20050915 Firefox/1.0.7'
119
+ result: { browser: { name: Firefox, version: 1.0.7, type: browser }, engine: { name: Gecko, version: 1.7.12 }, os: { name: Windows, version: { value: '4.1', alias: '98' } }, device: { type: desktop } }
120
+ readable: 'Firefox 1.0.7 on Windows 98'
121
+ -
122
+ headers: 'User-Agent: Mozilla/5.0 (Windows; U; WinNT4.0; xx; rv:1.8.1) Gecko/20061010 Firefox/2.0'
123
+ result: { browser: { name: Firefox, version: '2.0', type: browser }, engine: { name: Gecko, version: 1.8.1 }, os: { name: Windows, version: { value: '4.0', alias: 'NT 4.0' } }, device: { type: desktop } }
124
+ readable: 'Firefox 2.0 on Windows NT 4.0'
125
+ -
126
+ headers: 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; xx; rv:1.9.1.5pre) Gecko/20091017 Shiretoko/3.5.5pre'
127
+ result: { browser: { name: Firefox, version: 3.5.5, type: browser }, engine: { name: Gecko, version: 1.9.1 }, os: { name: Windows, version: { value: '5.1', alias: XP } }, device: { type: desktop } }
128
+ readable: 'Firefox Shiretoko 3.5.5 on Windows XP'
129
+ -
130
+ headers: 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; xx; rv:1.9.0.12) Gecko/2009070611 Firefox/3.0.12'
131
+ result: { browser: { name: Firefox, version: 3.0.12, type: browser }, engine: { name: Gecko, version: 1.9.0 }, os: { name: Windows, version: { value: '6.0', alias: Vista } }, device: { type: desktop } }
132
+ readable: 'Firefox 3.0.12 on Windows Vista'
133
+ -
134
+ headers: 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; xx; rv:1.5a) Gecko/20030728 Mozilla Firebird/0.6.1'
135
+ result: { browser: { name: Firebird, family: { name: Firefox, version: 0.6.1 }, version: 0.6.1, type: browser }, engine: { name: Gecko, version: 1.5a }, os: { name: Windows, version: { value: '6.1', alias: '7' } }, device: { type: desktop } }
136
+ readable: 'Firebird 0.6.1 on Windows 7'
137
+ -
138
+ headers: 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; xx; rv:1.8.1.22pre) Gecko/20090330 BonEcho/2.0.0.22pre'
139
+ result: { browser: { name: Firefox, version: 2.0.0.22, type: browser }, engine: { name: Gecko, version: 1.8.1 }, os: { name: Windows, version: { value: '6.1', alias: '7' } }, device: { type: desktop } }
140
+ readable: 'Firefox BonEcho 2.0.0.22 on Windows 7'
141
+ -
142
+ headers: 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; xx; rv:1.9.3a4pre) Gecko/20100405 Minefield/3.7a4pre'
143
+ result: { browser: { name: Firefox, version: 3.7a4, type: browser }, engine: { name: Gecko, version: 1.9.3a4pre }, os: { name: Windows, version: { value: '6.1', alias: '7' } }, device: { type: desktop } }
144
+ readable: 'Firefox Minefield 3.7a4 on Windows 7'
145
+ -
146
+ headers: 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.2; xx; rv:1.5) Gecko/20031006 Firebird/0.7'
147
+ result: { browser: { name: Firebird, family: { name: Firefox, version: '0.7' }, version: '0.7', type: browser }, engine: { name: Gecko, version: '1.5' }, os: { name: Windows, version: { value: '6.2', alias: '8' } }, device: { type: desktop } }
148
+ readable: 'Firebird 0.7 on Windows 8'
149
+ -
150
+ headers: 'User-Agent: Mozilla/5.0 (X11; Fedora; Linux x86_64; rv:41.0) Gecko/20100101 Firefox/41.0'
151
+ result: { browser: { name: Firefox, version: '41.0', type: browser }, engine: { name: Gecko, version: '41.0' }, os: { name: Fedora }, device: { type: desktop } }
152
+ readable: 'Firefox 41.0 on Fedora'
153
+ -
154
+ headers: 'User-Agent: Mozilla/5.0 (X11; FreeBSD amd64; rv:17.0) Gecko/201071 Firefox/17.0'
155
+ result: { browser: { name: Firefox, version: '17.0', type: browser }, engine: { name: Gecko, version: '17.0' }, os: { name: FreeBSD, family: BSD }, device: { type: desktop } }
156
+ readable: 'Firefox 17.0 on FreeBSD'
157
+ -
158
+ headers: 'User-Agent: Mozilla/5.0 (X11; FreeBSD amd64; rv:27.0) Gecko/20100101 Firefox/27.0'
159
+ result: { browser: { name: Firefox, version: '27.0', type: browser }, engine: { name: Gecko, version: '27.0' }, os: { name: FreeBSD, family: BSD }, device: { type: desktop } }
160
+ readable: 'Firefox 27.0 on FreeBSD'
161
+ -
162
+ headers: 'User-Agent: Mozilla/5.0 (X11; Linux x86_64) Gecko/20100101 Firefox/17.0'
163
+ result: { browser: { name: Firefox, version: '17.0', type: browser }, engine: { name: Gecko }, os: { name: Linux }, device: { type: desktop } }
164
+ readable: 'Firefox 17.0 on Linux'
165
+ -
166
+ headers: 'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:20.0) Gecko/20130117 Firefox/20.0 Aurora/20.0a2'
167
+ result: { browser: { name: Firefox, version: 20.0a2, type: browser }, engine: { name: Gecko, version: '20.0' }, os: { name: Linux }, device: { type: desktop } }
168
+ readable: 'Firefox Aurora 20.0a2 on Linux'
169
+ -
170
+ headers: 'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20130614 Firefox/24.0'
171
+ result: { browser: { name: Firefox, version: '24.0', type: browser }, engine: { name: Gecko, version: '24.0' }, os: { name: Linux }, device: { type: desktop } }
172
+ readable: 'Firefox 24.0 on Linux'
173
+ -
174
+ headers: 'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20130717 Firefox/24.0 Aurora/24.0a2'
175
+ result: { browser: { name: Firefox, version: 24.0a2, type: browser }, engine: { name: Gecko, version: '24.0' }, os: { name: Linux }, device: { type: desktop } }
176
+ readable: 'Firefox Aurora 24.0a2 on Linux'
177
+ -
178
+ headers: 'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:27.0) Gecko/20100101 Firefox/27.0 Aurora/27.0a2'
179
+ result: { browser: { name: Firefox, version: 27.0a2, type: browser }, engine: { name: Gecko, version: '27.0' }, os: { name: Linux }, device: { type: desktop } }
180
+ readable: 'Firefox Aurora 27.0a2 on Linux'
181
+ -
182
+ headers: 'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:8.0) Gecko/20111218 Firefox/8.0'
183
+ result: { browser: { name: Firefox, version: '8.0', type: browser }, engine: { name: Gecko, version: '8.0' }, os: { name: Linux }, device: { type: desktop } }
184
+ readable: 'Firefox 8.0 on Linux'
185
+ -
186
+ headers: 'User-Agent: Mozilla/5.0 (X11; OpenBSD amd64; rv:12.0) Gecko/20100101 Firefox/12.0'
187
+ result: { browser: { name: Firefox, version: '12.0', type: browser }, engine: { name: Gecko, version: '12.0' }, os: { name: OpenBSD, family: BSD }, device: { type: desktop } }
188
+ readable: 'Firefox 12.0 on OpenBSD'
189
+ -
190
+ headers: 'User-Agent: Mozilla/5.0 (X11; OpenBSD i386; rv:25.0) Gecko/20100101 Firefox/25.0'
191
+ result: { browser: { name: Firefox, version: '25.0', type: browser }, engine: { name: Gecko, version: '25.0' }, os: { name: OpenBSD, family: BSD }, device: { type: desktop } }
192
+ readable: 'Firefox 25.0 on OpenBSD'
193
+ -
194
+ headers: 'User-Agent: Mozilla/5.0 (X11; OpenBSD i386; rv:8.0.1) Gecko/20100101 Firefox/8.0.1'
195
+ result: { browser: { name: Firefox, version: 8.0.1, type: browser }, engine: { name: Gecko, version: 8.0.1 }, os: { name: OpenBSD, family: BSD }, device: { type: desktop } }
196
+ readable: 'Firefox 8.0.1 on OpenBSD'
197
+ -
198
+ headers: 'User-Agent: Mozilla/5.0 (X11; Scientific Linux x86_64; rv:17.0) Red Hat/6.4 Gecko/20130917 Firefox/17.0'
199
+ result: { browser: { name: Firefox, version: '17.0', type: browser }, engine: { name: Gecko, version: '17.0' }, os: { name: 'Red Hat' }, device: { type: desktop } }
200
+ readable: 'Firefox 17.0 on Red Hat'
201
+ -
202
+ headers: 'User-Agent: Mozilla/5.0 (X11; SunOS i86pc; rv:2.0) Gecko/20100101 Firefox/4.0'
203
+ result: { browser: { name: Firefox, version: '4.0', type: browser }, engine: { name: Gecko, version: '2.0' }, os: { name: Solaris, family: UNIX }, device: { type: desktop } }
204
+ readable: 'Firefox 4.0 on Solaris'
205
+ -
206
+ headers: 'User-Agent: Mozilla/5.0 (X11; SunOS sun4u; rv:17.0) Gecko/17.0 Firefox/17.0'
207
+ result: { browser: { name: Firefox, version: '17.0', type: browser }, engine: { name: Gecko, version: '17.0' }, os: { name: Solaris, family: UNIX }, device: { type: desktop } }
208
+ readable: 'Firefox 17.0 on Solaris'
209
+ -
210
+ headers: 'User-Agent: Mozilla/5.0 (X11; U; Linux i686; xx; rv:1.8.1.18) Gecko/20110906 BonEcho/2.0.0.18'
211
+ result: { browser: { name: Firefox, version: 2.0.0.18, type: browser }, engine: { name: Gecko, version: 1.8.1 }, os: { name: Linux }, device: { type: desktop } }
212
+ readable: 'Firefox BonEcho 2.0.0.18 on Linux'
213
+ -
214
+ headers: 'User-Agent: Mozilla/5.0 (X11; U; Linux i686; xx; rv:1.9.1.7) Gecko/20100303 Shiretoko/3.5.7'
215
+ result: { browser: { name: Firefox, version: 3.5.7, type: browser }, engine: { name: Gecko, version: 1.9.1 }, os: { name: Linux }, device: { type: desktop } }
216
+ readable: 'Firefox Shiretoko 3.5.7 on Linux'
217
+ -
218
+ headers: 'User-Agent: Mozilla/5.0 (X11; U; Linux i686; xx; rv:1.9.1.9) Gecko/20100330 Fedora/3.5.9-2.fc12 Firefox/3.5.9'
219
+ result: { browser: { name: Firefox, version: 3.5.9, type: browser }, engine: { name: Gecko, version: 1.9.1 }, os: { name: Fedora, version: '12' }, device: { type: desktop } }
220
+ readable: 'Firefox 3.5.9 on Fedora 12'
221
+ -
222
+ headers: 'User-Agent: Mozilla/5.0 (X11; U; Linux i686; xx; rv:1.9b3pre) Gecko/2008020404 Minefield/3.0b3pre'
223
+ result: { browser: { name: Firefox, version: 3.0b3, type: browser }, engine: { name: Gecko, version: 1.9b3pre }, os: { name: Linux }, device: { type: desktop } }
224
+ readable: 'Firefox Minefield 3.0b3 on Linux'
225
+ -
226
+ headers: 'User-Agent: Mozilla/5.0 (X11; U; OpenVMS HP_rx2660__(1.42GHz/6.0MB); xx; rv:1.8.1.18) Gecko/20081201 BonEcho/2.0.0.18'
227
+ result: { browser: { name: Firefox, version: 2.0.0.18, type: browser }, engine: { name: Gecko, version: 1.8.1 }, os: { name: OpenVMS }, device: { type: desktop } }
228
+ readable: 'Firefox BonEcho 2.0.0.18 on OpenVMS'
229
+ -
230
+ headers: 'User-Agent: Mozilla/5.0 (X11; U; QNX x86pc; xx; rv:1.9.2.15) Gecko/20110316 Namoroka/3.6.15'
231
+ result: { browser: { name: Firefox, version: 3.6.15, type: browser }, engine: { name: Gecko, version: 1.9.2 }, os: { name: QNX }, device: { type: mobile, subtype: feature } }
232
+ readable: 'Firefox Namoroka 3.6.15 on QNX'
233
+ -
234
+ headers: 'User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:15.0) Gecko/20120426 Firefox/15.0a1'
235
+ result: { browser: { name: Firefox, version: 15.0a1, type: browser }, engine: { name: Gecko, version: '15.0' }, os: { name: Ubuntu }, device: { type: desktop } }
236
+ readable: 'Firefox Aurora 15.0a1 on Ubuntu'
237
+ -
238
+ headers: 'User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:37.0) Gecko/20100101 Firefox/37.0'
239
+ result: { browser: { name: Firefox, version: '37.0', type: browser }, engine: { name: Gecko, version: '37.0' }, os: { name: Ubuntu }, device: { type: desktop } }
240
+ readable: 'Firefox 37.0 on Ubuntu'
241
+ -
242
+ headers: 'User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.0.3) Gecko/2008100314 GranParadiso/3.0.3'
243
+ result: { browser: { name: Firefox, version: 3.0.3, type: browser }, engine: { name: Gecko, version: 1.9.0 }, os: { name: Linux }, device: { type: desktop } }
244
+ readable: 'Firefox Gran Paradiso 3.0.3 on Linux'
245
+ -
246
+ headers: 'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:33.0) Gecko/20100101 Firefox/33.0 Slackware/14.1'
247
+ result: { browser: { name: Firefox, version: '33.0', type: browser }, engine: { name: Gecko, version: '33.0' }, os: { name: Slackware, version: '14.1' }, device: { type: desktop } }
248
+ readable: 'Firefox 33.0 on Slackware 14.1'
249
+ -
250
+ headers: 'User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.2b) Gecko/20021029 Phoenix/0.4'
251
+ result: { browser: { name: Phoenix, version: '0.4', type: browser }, engine: { name: Gecko, version: 1.2b }, os: { name: Linux }, device: { type: desktop } }
252
+ readable: 'Phoenix 0.4 on Linux'
253
+ -
254
+ headers: 'User-Agent: Mozilla/5.0 (X11; U; Darwin i386; en-US; rv:1.9.1.4) Gecko/20100311 Shiretoko/3.5.5'
255
+ readable: 'Firefox Shiretoko 3.5.5 on Darwin'
256
+ result: { browser: { name: Firefox, version: 3.5.5, type: browser }, engine: { name: Gecko, version: 1.9.1 }, os: { name: Darwin }, device: { type: desktop } }
includes/vendor/whichbrowser/parser/tests/data/desktop/browser-icab.yaml ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ -
2
+ headers: 'User-Agent: iCab J/2.8.2 (Macintosh; U; PPC)'
3
+ result: { browser: { name: iCab, version: 2.8.2, type: browser }, os: { name: 'Mac OS' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
4
+ readable: 'iCab 2.8.2 on Mac OS'
5
+ -
6
+ headers: 'User-Agent: iCab J/2.9.8 (Macintosh; U; PPC; Mac OS X)'
7
+ result: { browser: { name: iCab, version: 2.9.8, type: browser }, os: { name: 'OS X' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
8
+ readable: 'iCab 2.9.8 on OS X'
9
+ -
10
+ headers: 'User-Agent: iCab/2.9 (Macintosh; U; PPC)'
11
+ result: { browser: { name: iCab, version: '2.9', type: browser }, os: { name: 'Mac OS' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
12
+ readable: 'iCab 2.9 on Mac OS'
13
+ -
14
+ headers: 'User-Agent: iCab/2.9 (Macintosh; U; PPC; Mac OS X)'
15
+ result: { browser: { name: iCab, version: '2.9', type: browser }, os: { name: 'OS X' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
16
+ readable: 'iCab 2.9 on OS X'
17
+ -
18
+ headers: 'User-Agent: iCab/5.0 (Macintosh; U; Intel Mac OS X)'
19
+ result: { browser: { name: iCab, version: '5.0', type: browser }, os: { name: 'OS X' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
20
+ readable: 'iCab 5.0 on OS X'
21
+ -
22
+ headers: 'User-Agent: iCab/5.0 (Macintosh; U; PPC Mac OS X)'
23
+ result: { browser: { name: iCab, version: '5.0', type: browser }, os: { name: 'OS X' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
24
+ readable: 'iCab 5.0 on OS X'
25
+ -
26
+ headers: 'User-Agent: iCab/5.0 CFNetwork/454.12.4 Darwin/10.8.0 (i386) (iMac7%2C1)'
27
+ result: { browser: { name: iCab, version: '5.0', type: browser }, os: { name: 'OS X', alias: 'Mac OS X', version: 10.6.8 }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
28
+ readable: 'iCab 5.0 on Mac OS X 10.6.8'
29
+ -
30
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/600.1.25 (KHTML, like Gecko) iCab/5.5 Safari/533.16'
31
+ result: { browser: { name: iCab, version: '5.5', type: browser }, engine: { name: Webkit, version: 600.1.25 }, os: { name: 'OS X', version: { value: '10.10', nickname: Yosemite } }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
32
+ readable: 'iCab 5.5 on OS X Yosemite 10.10'
33
+ -
34
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_2) AppleWebKit/534.52.7 (KHTML, like Gecko) iCab/4.8 Safari/533.16'
35
+ result: { browser: { name: iCab, version: '4.8', type: browser }, engine: { name: Webkit, version: 534.52.7 }, os: { name: 'OS X', version: { value: '10.7', nickname: Lion } }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
36
+ readable: 'iCab 4.8 on OS X Lion 10.7'
37
+ -
38
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; U; PPC Mac OS X; xx) AppleWebKit/523.10.3 (KHTML, like Gecko) iCab/4.9 Safari/533.16'
39
+ result: { browser: { name: iCab, version: '4.9', type: browser }, engine: { name: Webkit, version: 523.10.3 }, os: { name: 'OS X' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
40
+ readable: 'iCab 4.9 on OS X'
includes/vendor/whichbrowser/parser/tests/data/desktop/browser-ie.yaml ADDED
@@ -0,0 +1,104 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ -
2
+ headers: 'User-Agent: Mozilla/1.0 (compatible; MSIE 1.0; Windows 95)'
3
+ result: { browser: { name: 'Internet Explorer', version: '1.0', type: browser }, os: { name: Windows, version: { value: '4.0', alias: '95' } }, device: { type: desktop } }
4
+ readable: 'Internet Explorer 1.0 on Windows 95'
5
+ -
6
+ headers: 'User-Agent: Mozilla/1.22 (compatible; MSIE 2.0; Windows 95)'
7
+ result: { browser: { name: 'Internet Explorer', version: '2.0', type: browser }, os: { name: Windows, version: { value: '4.0', alias: '95' } }, device: { type: desktop } }
8
+ readable: 'Internet Explorer 2.0 on Windows 95'
9
+ -
10
+ headers: 'User-Agent: Mozilla/2.0 (compatible; MSIE 2.1; Mac_PowerPC)'
11
+ result: { browser: { name: 'Internet Explorer', version: '2.1', type: browser }, engine: { name: Tasman }, os: { name: 'Mac OS' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
12
+ readable: 'Internet Explorer 2.1 on Mac OS'
13
+ -
14
+ headers: 'User-Agent: Mozilla/2.0 (compatible; MSIE 3.01; Windows 95)'
15
+ result: { browser: { name: 'Internet Explorer', version: 3.0.1, type: browser }, os: { name: Windows, version: { value: '4.0', alias: '95' } }, device: { type: desktop } }
16
+ readable: 'Internet Explorer 3.0.1 on Windows 95'
17
+ -
18
+ headers: 'User-Agent: Mozilla/2.0 (compatible; MSIE 3.02; Update a; AOL 3.0; Windows 95)'
19
+ result: { browser: { name: 'Internet Explorer', version: 3.0.2, type: browser }, os: { name: Windows, version: { value: '4.0', alias: '95' } }, device: { type: desktop } }
20
+ readable: 'Internet Explorer 3.0.2 on Windows 95'
21
+ -
22
+ headers: 'User-Agent: Mozilla/2.0 (compatible; MSIE 3.0; Windows 3.1)'
23
+ result: { browser: { name: 'Internet Explorer', version: '3.0', type: browser }, os: { name: Windows, version: '3.1' }, device: { type: desktop } }
24
+ readable: 'Internet Explorer 3.0 on Windows 3.1'
25
+ -
26
+ headers: 'User-Agent: Mozilla/2.0 (compatible; MSIE 4.0; Windows 98)'
27
+ result: { browser: { name: 'Internet Explorer', version: '4.0', type: browser }, engine: { name: Trident }, os: { name: Windows, version: { value: '4.1', alias: '98' } }, device: { type: desktop } }
28
+ readable: 'Internet Explorer 4.0 on Windows 98'
29
+ -
30
+ headers: 'User-Agent: Mozilla/4.0 (compatible; MSIE 4.01; Mac_PowerPC)'
31
+ result: { browser: { name: 'Internet Explorer', version: 4.0.1, type: browser }, engine: { name: Tasman }, os: { name: 'Mac OS' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
32
+ readable: 'Internet Explorer 4.0.1 on Mac OS'
33
+ -
34
+ headers: 'User-Agent: Mozilla/4.0 (compatible; MSIE 4.01; Mac_PowerPC)'
35
+ result: { browser: { name: 'Internet Explorer', version: 4.0.1, type: browser }, engine: { name: Tasman }, os: { name: 'Mac OS' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
36
+ readable: 'Internet Explorer 4.0.1 on Mac OS'
37
+ -
38
+ headers: 'User-Agent: Mozilla/4.0 (compatible; MSIE 4.5; Mac_PowerPC)'
39
+ result: { browser: { name: 'Internet Explorer', version: '4.5', type: browser }, engine: { name: Tasman }, os: { name: 'Mac OS' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
40
+ readable: 'Internet Explorer 4.5 on Mac OS'
41
+ -
42
+ headers: 'User-Agent: Mozilla/4.0 (compatible; MSIE 5.0; SunOS 5.10 sun4u; X11)'
43
+ result: { browser: { name: 'Internet Explorer', version: '5.0', type: browser }, engine: { name: Trident }, os: { name: Solaris, family: UNIX, version: '10' }, device: { type: desktop } }
44
+ readable: 'Internet Explorer 5.0 on Solaris 10'
45
+ -
46
+ headers: 'User-Agent: Mozilla/4.0 (compatible; MSIE 5.0b1; Mac_PowerPC)'
47
+ result: { browser: { name: 'Internet Explorer', version: '5.0', type: browser }, engine: { name: Tasman }, os: { name: 'Mac OS' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
48
+ readable: 'Internet Explorer 5.0 on Mac OS'
49
+ -
50
+ headers: 'User-Agent: Mozilla/4.0 (compatible; MSIE 5.12; Mac_PowerPC)'
51
+ result: { browser: { name: 'Internet Explorer', version: 5.1.2, type: browser }, engine: { name: Tasman }, os: { name: 'OS X' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
52
+ readable: 'Internet Explorer 5.1.2 on OS X'
53
+ -
54
+ headers: 'User-Agent: Mozilla/4.0 (compatible; MSIE 5.22; Mac_PowerPC)'
55
+ result: { browser: { name: 'Internet Explorer', version: 5.2.2, type: browser }, engine: { name: Tasman }, os: { name: 'OS X' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
56
+ readable: 'Internet Explorer 5.2.2 on OS X'
57
+ -
58
+ headers: 'User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows 98; Win 9x 4.90)'
59
+ result: { browser: { name: 'Internet Explorer', version: '5.5', type: browser }, engine: { name: Trident }, os: { name: Windows, version: { value: '4.9', alias: ME } }, device: { type: desktop } }
60
+ readable: 'Internet Explorer 5.5 on Windows ME'
61
+ -
62
+ headers: 'User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0 )'
63
+ result: { browser: { name: 'Internet Explorer', version: '5.5', type: browser }, engine: { name: Trident }, os: { name: Windows, version: { value: '5.0', alias: '2000' } }, device: { type: desktop } }
64
+ readable: 'Internet Explorer 5.5 on Windows 2000'
65
+ -
66
+ headers: 'User-Agent: Mozilla/4.0 (compatible; MSIE 5.5b1; Mac_PowerPC)'
67
+ result: { browser: { name: 'Internet Explorer', version: '5.5', type: browser }, engine: { name: Tasman }, os: { name: 'OS X' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
68
+ readable: 'Internet Explorer 5.5 on OS X'
69
+ -
70
+ headers: 'User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows 98; Win 9x 4.90; .NET CLR 1.1.4322)'
71
+ result: { browser: { name: 'Internet Explorer', version: '6.0', type: browser }, engine: { name: Trident }, os: { name: Windows, version: { value: '4.9', alias: ME } }, device: { type: desktop } }
72
+ readable: 'Internet Explorer 6.0 on Windows ME'
73
+ -
74
+ headers: 'User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; InfoPath.1)'
75
+ result: { browser: { name: 'Internet Explorer', version: '6.0', type: browser }, engine: { name: Trident }, os: { name: Windows, version: { value: '5.0', alias: '2000' } }, device: { type: desktop } }
76
+ readable: 'Internet Explorer 6.0 on Windows 2000'
77
+ -
78
+ headers: 'User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.3; .NET4.0C; .NET4.0E)'
79
+ result: { browser: { name: 'Internet Explorer', version: '8.0', type: browser }, engine: { name: Trident, version: '4.0' }, os: { name: Windows, version: { value: '6.1', alias: '7' } }, device: { type: desktop } }
80
+ readable: 'Internet Explorer 8.0 on Windows 7'
81
+ -
82
+ headers: 'User-Agent: Mozilla/5.0 (IE 11.0; Windows NT 6.2; WOW64; Trident/7.0; .NET4.0E; .NET4.0C; rv:11.0) like Gecko'
83
+ result: { browser: { name: 'Internet Explorer', version: '11.0', type: browser }, engine: { name: Trident, version: '7.0' }, os: { name: Windows, version: { value: '6.2', alias: '8' } }, device: { type: desktop } }
84
+ readable: 'Internet Explorer 11.0 on Windows 8'
85
+ -
86
+ headers: 'User-Agent: Mozilla/5.0 (IE 11.0; Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko'
87
+ result: { browser: { name: 'Internet Explorer', version: '11.0', type: browser }, engine: { name: Trident, version: '7.0' }, os: { name: Windows, version: { value: '6.3', alias: '8.1' } }, device: { type: desktop } }
88
+ readable: 'Internet Explorer 11.0 on Windows 8.1'
89
+ -
90
+ headers: 'User-Agent: Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E)'
91
+ result: { browser: { name: 'Internet Explorer', version: '9.0', type: browser }, engine: { name: Trident, version: '5.0' }, os: { name: Windows, version: { value: '6.1', alias: '7' } }, device: { type: desktop } }
92
+ readable: 'Internet Explorer 9.0 on Windows 7'
93
+ -
94
+ headers: 'User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/6.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET4.0C; .NET4.0E; MALN)'
95
+ result: { browser: { name: 'Internet Explorer', version: '10.0', type: browser }, engine: { name: Trident, version: '6.0' }, os: { name: Windows, version: { value: '6.1', alias: '7' } }, device: { type: desktop, manufacturer: Lenovo } }
96
+ readable: 'Internet Explorer 10.0 on Windows 7'
97
+ -
98
+ headers: 'User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/7.0)'
99
+ result: { browser: { name: 'Internet Explorer', version: '11.0', type: browser }, engine: { name: Trident, version: '7.0' }, os: { name: Windows, version: { value: '6.1', alias: '7' } }, device: { type: desktop } }
100
+ readable: 'Internet Explorer 11.0 on Windows 7'
101
+ -
102
+ headers: 'User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 10.0; Trident/8.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729; SLCC2)'
103
+ readable: 'Internet Explorer 11.0 on Windows 10'
104
+ result: { browser: { name: 'Internet Explorer', version: '11.0', type: browser }, engine: { name: Trident, version: '8.0' }, os: { name: Windows, version: { value: '10.0', alias: '10' } }, device: { type: desktop } }
includes/vendor/whichbrowser/parser/tests/data/desktop/browser-konqueror.yaml ADDED
@@ -0,0 +1,80 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ -
2
+ headers: 'User-Agent: Mozilla/5.0 (X11) KHTML/4.14.3 (like Gecko) Konqueror/4.14'
3
+ result: { browser: { name: Konqueror, version: '4.14', type: browser }, engine: { name: KHTML, version: 4.14.3 }, device: { type: desktop } }
4
+ readable: 'Konqueror 4.14'
5
+ -
6
+ headers: 'User-Agent: Mozilla/5.0 (X11; BSD Four) AppleWebKit/534.34 (KHTML, like Gecko) konqueror/4.10.5 Safari/534.34'
7
+ result: { browser: { name: Konqueror, version: 4.10.5, type: browser }, engine: { name: Webkit, version: '534.34' }, device: { type: desktop } }
8
+ readable: 'Konqueror 4.10.5'
9
+ -
10
+ headers: 'User-Agent: Mozilla/5.0 (X11; Cygwin) AppleWebKit/534.34 (KHTML, like Gecko) konqueror/4.13.3 Safari/534.34'
11
+ result: { browser: { name: Konqueror, version: 4.13.3, type: browser }, engine: { name: Webkit, version: '534.34' }, device: { type: desktop } }
12
+ readable: 'Konqueror 4.13.3'
13
+ -
14
+ headers: 'User-Agent: Mozilla/5.0 (X11; FreeBSD amd64) KHTML/4.12.4 (like Gecko) Konqueror/4.12'
15
+ result: { browser: { name: Konqueror, version: '4.12', type: browser }, engine: { name: KHTML, version: 4.12.4 }, os: { name: FreeBSD, family: BSD }, device: { type: desktop } }
16
+ readable: 'Konqueror 4.12 on FreeBSD'
17
+ -
18
+ headers: 'User-Agent: Mozilla/5.0 (X11; FreeBSD) KHTML/4.9.1 (like Gecko) Konqueror/4.9'
19
+ result: { browser: { name: Konqueror, version: '4.9', type: browser }, engine: { name: KHTML, version: 4.9.1 }, os: { name: FreeBSD, family: BSD }, device: { type: desktop } }
20
+ readable: 'Konqueror 4.9 on FreeBSD'
21
+ -
22
+ headers: 'User-Agent: Mozilla/5.0 (X11; Linux 3.13.0-30-generic) KHTML/4.13.2 (like Gecko) Konqueror/4.13'
23
+ result: { browser: { name: Konqueror, version: '4.13', type: browser }, engine: { name: KHTML, version: 4.13.2 }, os: { name: Linux }, device: { type: desktop } }
24
+ readable: 'Konqueror 4.13 on Linux'
25
+ -
26
+ headers: 'User-Agent: Mozilla/5.0 (X11; Linux 3.15.3-1-ARCH x86_64) KHTML/4.13.2 (like Gecko) Konqueror/4.13'
27
+ result: { browser: { name: Konqueror, version: '4.13', type: browser }, engine: { name: KHTML, version: 4.13.2 }, os: { name: Linux }, device: { type: desktop } }
28
+ readable: 'Konqueror 4.13 on Linux'
29
+ -
30
+ headers: 'User-Agent: Mozilla/5.0 (X11; Linux ; xx) AppleWebKit/534.34 (KHTML, like Gecko) konqueror/4.11.5 Safari/534.34'
31
+ result: { browser: { name: Konqueror, version: 4.11.5, type: browser }, engine: { name: Webkit, version: '534.34' }, os: { name: Linux }, device: { type: desktop } }
32
+ readable: 'Konqueror 4.11.5 on Linux'
33
+ -
34
+ headers: 'User-Agent: Mozilla/5.0 (X11; Linux armv7l) KHTML/4.10.4 (like Gecko) Konqueror/4.10'
35
+ result: { browser: { name: Konqueror, version: '4.10', type: browser }, engine: { name: KHTML, version: 4.10.4 }, os: { name: Linux }, device: { type: desktop } }
36
+ readable: 'Konqueror 4.10 on Linux'
37
+ -
38
+ headers: 'User-Agent: Mozilla/5.0 (X11; Linux i686) AppleWebKit/534.34 (KHTML, like Gecko) konqueror/4.14.1 Safari/534.34'
39
+ result: { browser: { name: Konqueror, version: 4.14.1, type: browser }, engine: { name: Webkit, version: '534.34' }, os: { name: Linux }, device: { type: desktop } }
40
+ readable: 'Konqueror 4.14.1 on Linux'
41
+ -
42
+ headers: 'User-Agent: Mozilla/5.0 (X11; Linux i686) KHTML/4.8.2 (like Gecko) Konqueror/4.8'
43
+ result: { browser: { name: Konqueror, version: '4.8', type: browser }, engine: { name: KHTML, version: 4.8.2 }, os: { name: Linux }, device: { type: desktop } }
44
+ readable: 'Konqueror 4.8 on Linux'
45
+ -
46
+ headers: 'User-Agent: Mozilla/5.0 (X11; Linux x86_64) KHTML/4.10.4 (like Gecko) Konqueror/4.10 Fedora/4.10.4-1.fc18'
47
+ result: { browser: { name: Konqueror, version: '4.10', type: browser }, engine: { name: KHTML, version: 4.10.4 }, os: { name: Fedora, version: '18' }, device: { type: desktop } }
48
+ readable: 'Konqueror 4.10 on Fedora 18'
49
+ -
50
+ headers: 'User-Agent: Mozilla/5.0 (X11; Linux x86_64; en_US) KHTML/4.13.0 (like Gecko) Konqueror/4.13'
51
+ result: { browser: { name: Konqueror, version: '4.13', type: browser }, engine: { name: KHTML, version: 4.13.0 }, os: { name: Linux }, device: { type: desktop } }
52
+ readable: 'Konqueror 4.13 on Linux'
53
+ -
54
+ headers: 'User-Agent: Mozilla/5.0 (X11; Linux x86_64; xx) AppleWebKit/534.34 (KHTML, like Gecko) konqueror/4.14.2 Safari/534.34'
55
+ result: { browser: { name: Konqueror, version: 4.14.2, type: browser }, engine: { name: Webkit, version: '534.34' }, os: { name: Linux }, device: { type: desktop } }
56
+ readable: 'Konqueror 4.14.2 on Linux'
57
+ -
58
+ headers: 'User-Agent: Mozilla/5.0 (compatible; Konqueror/3.5; Linux) KHTML/3.5.10 (like Gecko) SUSE'
59
+ result: { browser: { name: Konqueror, version: '3.5', type: browser }, engine: { name: KHTML, version: 3.5.10 }, os: { name: SUSE }, device: { type: desktop } }
60
+ readable: 'Konqueror 3.5 on SUSE'
61
+ -
62
+ headers: 'User-Agent: Mozilla/5.0 (compatible; Konqueror/3.5; Linux) KHTML/3.5.7 (like Gecko)'
63
+ result: { browser: { name: Konqueror, version: '3.5', type: browser }, engine: { name: KHTML, version: 3.5.7 }, os: { name: Linux }, device: { type: desktop } }
64
+ readable: 'Konqueror 3.5 on Linux'
65
+ -
66
+ headers: 'User-Agent: Mozilla/5.0 (compatible; Konqueror/4.2; Linux) KHTML/4.2.4 (like Gecko)'
67
+ result: { browser: { name: Konqueror, version: '4.2', type: browser }, engine: { name: KHTML, version: 4.2.4 }, os: { name: Linux }, device: { type: desktop } }
68
+ readable: 'Konqueror 4.2 on Linux'
69
+ -
70
+ headers: 'User-Agent: Mozilla/5.0 (compatible; Konqueror/4.5; Linux) KHTML/4.5.5 (like Gecko)'
71
+ result: { browser: { name: Konqueror, version: '4.5', type: browser }, engine: { name: KHTML, version: 4.5.5 }, os: { name: Linux }, device: { type: desktop } }
72
+ readable: 'Konqueror 4.5 on Linux'
73
+ -
74
+ headers: 'User-Agent: Mozilla/5.0 (compatible; Konqueror/4.6; Linux) KHTML/4.6.5 (like Gecko) Fedora/4.6.5-8.fc14'
75
+ result: { browser: { name: Konqueror, version: '4.6', type: browser }, engine: { name: KHTML, version: 4.6.5 }, os: { name: Fedora, version: '14' }, device: { type: desktop } }
76
+ readable: 'Konqueror 4.6 on Fedora 14'
77
+ -
78
+ headers: 'User-Agent: Mozilla/5.0 (compatible; Konqueror/4.6; Linux; X11; x86_64; xx) KHTML/4.6.5 (like Gecko) Mageia/4.6.5-1.7.mga1'
79
+ result: { browser: { name: Konqueror, version: '4.6', type: browser }, engine: { name: KHTML, version: 4.6.5 }, os: { name: Mageia, version: '1' }, device: { type: desktop } }
80
+ readable: 'Konqueror 4.6 on Mageia 1'
includes/vendor/whichbrowser/parser/tests/data/desktop/browser-maxthon.yaml ADDED
@@ -0,0 +1,136 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ -
2
+ headers: 'User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; QQDownload 691; Maxthon; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)'
3
+ result: { browser: { name: Maxthon, type: browser }, os: { name: Windows, version: { value: '5.1', alias: XP } }, device: { type: desktop } }
4
+ readable: 'Maxthon on Windows XP'
5
+ -
6
+ headers: 'User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; Trident/4.0; .NET CLR 1.1.4322; MAXTHON 2.0)'
7
+ result: { browser: { name: Maxthon, version: '2', type: browser }, engine: { name: Trident, version: '4.0' }, os: { name: Windows, version: { value: '5.1', alias: XP } }, device: { type: desktop } }
8
+ readable: 'Maxthon 2 on Windows XP'
9
+ -
10
+ headers: 'User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; WOW64; Trident/4.0; .NET4.0E; .NET4.0C; InfoPath.3; MAXTHON)'
11
+ result: { browser: { name: Maxthon, type: browser }, engine: { name: Trident, version: '4.0' }, os: { name: Windows, version: { value: '5.1', alias: XP } }, device: { type: desktop } }
12
+ readable: 'Maxthon on Windows XP'
13
+ -
14
+ headers: 'User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; Maxthon/3.0)'
15
+ result: { browser: { name: Maxthon, version: '3', type: browser }, engine: { name: Trident, version: '4.0' }, os: { name: Windows, version: { value: '5.1', alias: XP } }, device: { type: desktop } }
16
+ readable: 'Maxthon 3 on Windows XP'
17
+ -
18
+ headers: 'User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; Maxthon 2.0)'
19
+ result: { browser: { name: Maxthon, version: '2', type: browser }, engine: { name: Trident, version: '4.0' }, os: { name: Windows, version: { value: '5.1', alias: XP } }, device: { type: desktop } }
20
+ readable: 'Maxthon 2 on Windows XP'
21
+ -
22
+ headers: 'User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; Maxthon/3.0)'
23
+ result: { browser: { name: Maxthon, version: '3', type: browser }, engine: { name: Trident, version: '4.0' }, os: { name: Windows, version: { value: '5.1', alias: XP } }, device: { type: desktop } }
24
+ readable: 'Maxthon 3 on Windows XP'
25
+ -
26
+ headers: 'User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; Maxthon; .NET CLR 1.1.4322; .NET CLR 2.0.50727)'
27
+ result: { browser: { name: Maxthon, type: browser }, engine: { name: Trident, version: '4.0' }, os: { name: Windows, version: { value: '5.1', alias: XP } }, device: { type: desktop } }
28
+ readable: 'Maxthon on Windows XP'
29
+ -
30
+ headers: 'User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.2; Trident/6.0; .NET4.0E; .NET4.0C; .NET CLR 3.5.30729; .NET CLR 2.0.50727; .NET CLR 3.0.30729; Maxthon/3.0)'
31
+ result: { browser: { name: Maxthon, version: '3', type: browser }, engine: { name: Trident, version: '6.0' }, os: { name: Windows, version: { value: '6.2', alias: '8' } }, device: { type: desktop } }
32
+ readable: 'Maxthon 3 on Windows 8'
33
+ -
34
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_5) AppleWebKit/537.22 (KHTML, like Gecko) Maxthon/4.1.2.1000 Chrome/25.0.1364.99 Safari/537.22'
35
+ result: { browser: { name: Maxthon, family: { name: Chrome, version: 25 }, version: 4.1.2, type: browser }, engine: { name: Webkit, version: '537.22' }, os: { name: 'OS X', version: { value: '10.8', nickname: 'Mountain Lion' } }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
36
+ readable: 'Maxthon 4.1.2 on OS X Mountain Lion 10.8'
37
+ -
38
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.22 (KHTML, like Gecko) Maxthon/4.0.6.3000 Chrome/25.0.1364.99 Safari/537.22'
39
+ result: { browser: { name: Maxthon, family: { name: Chrome, version: 25 }, version: 4.0.6, type: browser }, engine: { name: Webkit, version: '537.22' }, os: { name: 'OS X', version: { value: '10.9', nickname: Mavericks } }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
40
+ readable: 'Maxthon 4.0.6 on OS X Mavericks 10.9'
41
+ -
42
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_4) AppleWebKit/537.77.4 (KHTML, like Gecko) Maxthon/4.2.3'
43
+ result: { browser: { name: Maxthon, version: 4.2.3, type: browser }, engine: { name: Webkit, version: 537.77.4 }, os: { name: 'OS X', version: { value: '10.9', nickname: Mavericks } }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
44
+ readable: 'Maxthon 4.2.3 on OS X Mavericks 10.9'
45
+ -
46
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.22 (KHTML, like Gecko) Maxthon/4.1.2.1000 Chrome/25.0.1364.99 Safari/537.22'
47
+ result: { browser: { name: Maxthon, family: { name: Chrome, version: 25 }, version: 4.1.2, type: browser }, engine: { name: Webkit, version: '537.22' }, os: { name: 'OS X', version: { value: '10.9', nickname: Mavericks } }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
48
+ readable: 'Maxthon 4.1.2 on OS X Mavericks 10.9'
49
+ -
50
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.78.2 (KHTML, like Gecko) Maxthon/4.4.0'
51
+ result: { browser: { name: Maxthon, version: 4.4.0, type: browser }, engine: { name: Webkit, version: 537.78.2 }, os: { name: 'OS X', version: { value: '10.9', nickname: Mavericks } }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
52
+ readable: 'Maxthon 4.4.0 on OS X Mavericks 10.9'
53
+ -
54
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.78.2 (KHTML, like Gecko) Maxthon/4.5.0'
55
+ result: { browser: { name: Maxthon, version: 4.5.0, type: browser }, engine: { name: Webkit, version: 537.78.2 }, os: { name: 'OS X', version: { value: '10.9', nickname: Mavericks } }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
56
+ readable: 'Maxthon 4.5.0 on OS X Mavericks 10.9'
57
+ -
58
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Maxthon/4.0 Chrome/30.0.1599.101 Safari/537.36'
59
+ result: { browser: { name: Maxthon, family: { name: Chrome, version: 30 }, version: '4.0', type: browser }, engine: { name: Blink }, os: { name: Windows, version: { value: '10.0', alias: '10' } }, device: { type: desktop } }
60
+ readable: 'Maxthon 4.0 on Windows 10'
61
+ -
62
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Maxthon/4.0 Chrome/44.0.2403.69 Safari/537.36'
63
+ result: { browser: { name: Maxthon, family: { name: Chrome, version: 44 }, version: '4.0', type: browser }, engine: { name: Blink }, os: { name: Windows, version: { value: '10.0', alias: '10' } }, device: { type: desktop } }
64
+ readable: 'Maxthon 4.0 on Windows 10'
65
+ -
66
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 5.1) AppleWebKit/535.12 (KHTML, like Gecko) Maxthon/3.0 Chrome/23.0.1229.79 Safari/535.12'
67
+ result: { browser: { name: Maxthon, family: { name: Chrome, version: 23 }, version: '3', type: browser }, engine: { name: Webkit, version: '535.12' }, os: { name: Windows, version: { value: '5.1', alias: XP } }, device: { type: desktop } }
68
+ readable: 'Maxthon 3 on Windows XP'
69
+ -
70
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) MxNitro/1.0.0.1010 Chrome/39.0.2146.0 Safari/537.36'
71
+ result: { browser: { name: 'Maxthon Nitro', family: { name: Chrome, version: 39 }, version: 1.0.0, type: browser }, engine: { name: Blink }, os: { name: Windows, version: { value: '5.1', alias: XP } }, device: { type: desktop } }
72
+ readable: 'Maxthon Nitro 1.0.0 on Windows XP'
73
+ -
74
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) MxNitro/1.0.0.500 Chrome/35.0.1849.0 Safari/537.36'
75
+ result: { browser: { name: 'Maxthon Nitro', family: { name: Chrome, version: 35 }, version: 1.0.0, type: browser }, engine: { name: Blink }, os: { name: Windows, version: { value: '5.1', alias: XP } }, device: { type: desktop } }
76
+ readable: 'Maxthon Nitro 1.0.0 on Windows XP'
77
+ -
78
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 6.0) AppleWebKit/537.36 (KHTML, like Gecko) MxNitro/1.0.0.700 Chrome/35.0.1849.0 Safari/537.36'
79
+ result: { browser: { name: 'Maxthon Nitro', family: { name: Chrome, version: 35 }, version: 1.0.0, type: browser }, engine: { name: Blink }, os: { name: Windows, version: { value: '6.0', alias: Vista } }, device: { type: desktop } }
80
+ readable: 'Maxthon Nitro 1.0.0 on Windows Vista'
81
+ -
82
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) MxNitro/1.0.0.900 Chrome/35.0.1849.0 Safari/537.36'
83
+ result: { browser: { name: 'Maxthon Nitro', family: { name: Chrome, version: 35 }, version: 1.0.0, type: browser }, engine: { name: Blink }, os: { name: Windows, version: { value: '6.1', alias: '7' } }, device: { type: desktop } }
84
+ readable: 'Maxthon Nitro 1.0.0 on Windows 7'
85
+ -
86
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) MxNitro/1.0.1.2000 Chrome/35.0.1849.0 Safari/537.36'
87
+ result: { browser: { name: 'Maxthon Nitro', family: { name: Chrome, version: 35 }, version: 1.0.1, type: browser }, engine: { name: Blink }, os: { name: Windows, version: { value: '6.1', alias: '7' } }, device: { type: desktop } }
88
+ readable: 'Maxthon Nitro 1.0.1 on Windows 7'
89
+ -
90
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) MxNitro/1.1.0.601 Chrome/39.0.2146.0 Safari/537.36'
91
+ result: { browser: { name: 'Maxthon Nitro', family: { name: Chrome, version: 39 }, version: 1.1.0, type: browser }, engine: { name: Blink }, os: { name: Windows, version: { value: '6.1', alias: '7' } }, device: { type: desktop } }
92
+ readable: 'Maxthon Nitro 1.1.0 on Windows 7'
93
+ -
94
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) MxNitro/1.1.0.2000 Chrome/39.0.2146.0 Safari/537.36'
95
+ result: { browser: { name: 'Maxthon Nitro', family: { name: Chrome, version: 39 }, version: 1.1.0, type: browser }, engine: { name: Blink }, os: { name: Windows, version: { value: '6.2', alias: '8' } }, device: { type: desktop } }
96
+ readable: 'Maxthon Nitro 1.1.0 on Windows 8'
97
+ -
98
+ headers: 'User-Agent: Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0; Maxthon/3.0)'
99
+ result: { browser: { name: Maxthon, version: '3', type: browser }, engine: { name: Trident, version: '6.0' }, os: { name: Windows, version: { value: '6.1', alias: '7' } }, device: { type: desktop } }
100
+ readable: 'Maxthon 3 on Windows 7'
101
+ -
102
+ headers: 'User-Agent: Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0; Maxthon/4.0.1.1000)'
103
+ result: { browser: { name: Maxthon, version: 4.0.1, type: browser }, engine: { name: Trident, version: '6.0' }, os: { name: Windows, version: { value: '6.1', alias: '7' } }, device: { type: desktop } }
104
+ readable: 'Maxthon 4.0.1 on Windows 7'
105
+ -
106
+ headers: 'User-Agent: Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0; Maxthon/4.0.3.5000)'
107
+ result: { browser: { name: Maxthon, version: 4.0.3, type: browser }, engine: { name: Trident, version: '6.0' }, os: { name: Windows, version: { value: '6.1', alias: '7' } }, device: { type: desktop } }
108
+ readable: 'Maxthon 4.0.3 on Windows 7'
109
+ -
110
+ headers: 'User-Agent: Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0; Maxthon/4.1.2.3000)'
111
+ result: { browser: { name: Maxthon, version: 4.1.2, type: browser }, engine: { name: Trident, version: '6.0' }, os: { name: Windows, version: { value: '6.1', alias: '7' } }, device: { type: desktop } }
112
+ readable: 'Maxthon 4.1.2 on Windows 7'
113
+ -
114
+ headers: 'User-Agent: Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0; Maxthon/4.2.2.600)'
115
+ result: { browser: { name: Maxthon, version: 4.2.2, type: browser }, engine: { name: Trident, version: '6.0' }, os: { name: Windows, version: { value: '6.1', alias: '7' } }, device: { type: desktop } }
116
+ readable: 'Maxthon 4.2.2 on Windows 7'
117
+ -
118
+ headers: 'User-Agent: Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0; Maxthon/4.2.0.3000)'
119
+ result: { browser: { name: Maxthon, version: 4.2.0, type: browser }, engine: { name: Trident, version: '6.0' }, os: { name: Windows, version: { value: '6.1', alias: '7' } }, device: { type: desktop } }
120
+ readable: 'Maxthon 4.2.0 on Windows 7'
121
+ -
122
+ headers: 'User-Agent: Mozilla/5.0 (compatible; Windows NT 6.3) AppleWebKit/537.36 (KHTML, like Gecko) Maxthon/4.4.6.600 Chrome/43.0.2357.124 Safari/537.36'
123
+ result: { browser: { name: Maxthon, family: { name: Chrome, version: 43 }, version: 4.4.6, type: browser }, engine: { name: Blink }, os: { name: Windows, version: { value: '6.3', alias: '8.1' } }, device: { type: desktop } }
124
+ readable: 'Maxthon 4.4.6 on Windows 8.1'
125
+ -
126
+ headers: 'User-Agent: Mozilla/5.0 (compatible; Windows NT 6.3; U; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Maxthon/4.4.5.3000 Chrome/43.0.2357.81 Safari/537.36'
127
+ result: { browser: { name: Maxthon, family: { name: Chrome, version: 43 }, version: 4.4.5, type: browser }, engine: { name: Blink }, os: { name: Windows, version: { value: '6.3', alias: '8.1' } }, device: { type: desktop } }
128
+ readable: 'Maxthon 4.4.5 on Windows 8.1'
129
+ -
130
+ headers: 'User-Agent: Mozilla/5.0 (compatible; Windows NT 6.3; U; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Maxthon/4.4.7.1000 Chrome/44.0.2403.157 Safari/537.36'
131
+ result: { browser: { name: Maxthon, family: { name: Chrome, version: 44 }, version: 4.4.7, type: browser }, engine: { name: Blink }, os: { name: Windows, version: { value: '6.3', alias: '8.1' } }, device: { type: desktop } }
132
+ readable: 'Maxthon 4.4.7 on Windows 8.1'
133
+ -
134
+ headers: 'User-Agent: Mozilla/5.0 (compatible; Windows NT 6.3; U; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Maxthon/4.4.8.1000 Chrome/46.0.2490.86 Safari/537.36'
135
+ result: { browser: { name: Maxthon, family: { name: Chrome, version: 46 }, version: 4.4.8, type: browser }, engine: { name: Blink }, os: { name: Windows, version: { value: '6.3', alias: '8.1' } }, device: { type: desktop } }
136
+ readable: 'Maxthon 4.4.8 on Windows 8.1'
includes/vendor/whichbrowser/parser/tests/data/desktop/browser-midori.yaml ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ -
2
+ headers: 'User-Agent: Midori/0.1.9 (X11; Linux i686; U; xx) WebKit/532+'
3
+ result: { browser: { name: Midori, version: 0.1.9, type: browser }, engine: { name: Webkit, version: '532' }, os: { name: Linux }, device: { type: desktop } }
4
+ readable: 'Midori 0.1.9 on Linux'
5
+ -
6
+ headers: 'User-Agent: Midori/0.2 (X11; Linux; U; c) WebKit/534.7+'
7
+ result: { browser: { name: Midori, version: '0.2', type: browser }, engine: { name: Webkit, version: '534.7' }, os: { name: Linux }, device: { type: desktop } }
8
+ readable: 'Midori 0.2 on Linux'
9
+ -
10
+ headers: 'User-Agent: Midori/0.2.2 (X11; Linux ppc; U; xx) WebKit/531.2'
11
+ result: { browser: { name: Midori, version: 0.2.2, type: browser }, engine: { name: Webkit, version: '531.2' }, os: { name: Linux }, device: { type: desktop } }
12
+ readable: 'Midori 0.2.2 on Linux'
13
+ -
14
+ headers: 'User-Agent: Midori/0.3 (X11; Linux; U; xx) WebKit/534.21+'
15
+ result: { browser: { name: Midori, version: '0.3', type: browser }, engine: { name: Webkit, version: '534.21' }, os: { name: Linux }, device: { type: desktop } }
16
+ readable: 'Midori 0.3 on Linux'
17
+ -
18
+ headers: 'User-Agent: Midori/0.4 (CentOS 6.5)'
19
+ result: { browser: { name: Midori, version: '0.4', type: browser }, device: { type: desktop } }
20
+ readable: 'Midori 0.4'
21
+ -
22
+ headers: 'User-Agent: Midori/0.5 (X11; FreeBSD/11) WebKit/2.4.7 Midori/0.5.9'
23
+ result: { browser: { name: Midori, version: '0.5', type: browser }, engine: { name: Webkit, version: 2.4.7 }, os: { name: FreeBSD, family: BSD, version: '11' }, device: { type: desktop } }
24
+ readable: 'Midori 0.5 on FreeBSD 11'
25
+ -
26
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X; c) AppleWebKit/535+ (KHTML, like Gecko) Version/5.0 Safari/535.10+ Midori/0.4'
27
+ result: { browser: { name: Midori, version: '0.4', type: browser }, engine: { name: Webkit, version: '535' }, device: { type: desktop } }
28
+ readable: 'Midori 0.4'
29
+ -
30
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X; xx) AppleWebKit/538+ (KHTML, like Gecko) Version/8.0 Safari/538.15+ Midori/0.5'
31
+ result: { browser: { name: Midori, version: '0.5', type: browser }, engine: { name: Webkit, version: '538' }, device: { type: desktop } }
32
+ readable: 'Midori 0.5'
33
+ -
34
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 6.0) AppleWebKit/537.6 (KHTML, like Gecko) Chrome/18.0.1025.133 Safari/537.6 Midori/0.4'
35
+ result: { browser: { name: Midori, family: { name: Chrome, version: 18 }, version: '0.4', type: browser }, engine: { name: Webkit, version: '537.6' }, os: { name: Windows, version: { value: '6.0', alias: Vista } }, device: { type: desktop } }
36
+ readable: 'Midori 0.4 on Windows Vista'
37
+ -
38
+ headers: 'User-Agent: Mozilla/5.0 (X11; CYGWIN_NT-6.1) AppleWebKit/537.32 (KHTML, like Gecko) Chrome/18.0.1025.133 Safari/537.32 Midori/0.5'
39
+ result: { browser: { name: Midori, family: { name: Chrome, version: 18 }, version: '0.5', type: browser }, engine: { name: Webkit, version: '537.32' }, device: { type: desktop } }
40
+ readable: 'Midori 0.5'
41
+ -
42
+ headers: 'User-Agent: Mozilla/5.0 (X11; FreeBSD) AppleWebKit/535.22 (KHTML, like Gecko) Chrome/18.0.1025.133 Safari/535.22 Midori/0.5'
43
+ result: { browser: { name: Midori, family: { name: Chrome, version: 18 }, version: '0.5', type: browser }, engine: { name: Webkit, version: '535.22' }, os: { name: FreeBSD, family: BSD }, device: { type: desktop } }
44
+ readable: 'Midori 0.5 on FreeBSD'
45
+ -
46
+ headers: 'User-Agent: Mozilla/5.0 (X11; Linux) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/18.0.1025.133 Safari/537.4 Midori/0.4'
47
+ result: { browser: { name: Midori, family: { name: Chrome, version: 18 }, version: '0.4', type: browser }, engine: { name: Webkit, version: '537.4' }, os: { name: Linux }, device: { type: desktop } }
48
+ readable: 'Midori 0.4 on Linux'
49
+ -
50
+ headers: 'User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; xx) AppleWebKit/525.1+ (KHTML, like Gecko, Safari/525.1+) midori'
51
+ result: { browser: { name: Midori, type: browser }, engine: { name: Webkit, version: '525.1' }, os: { name: Linux }, device: { type: desktop } }
52
+ readable: 'Midori on Linux'
53
+ -
54
+ headers: 'User-Agent: Mozilla/5.0 (iPhone; U; CPU like Mac OS X; xx) AppleWebKit/532 (KHTML, like Gecko) Version/3.0 Mobile/1A538b Safari/419.3 Midori/0.4'
55
+ result: { browser: { name: Midori, version: '0.4', type: browser }, engine: { name: Webkit, version: '532' }, os: { name: iOS, alias: 'iPhone OS', version: '1.0' }, device: { type: desktop, manufacturer: Apple } }
56
+ readable: 'Midori 0.4 on iPhone OS 1.0'
57
+ -
58
+ headers: 'User-Agent: Mozilla/5.0 (X11; U; Linux i686; xx) AppleWebKit/525.1 (KHTML, like Gecko, Safari/525.1 ) midori/1.19'
59
+ result: { browser: { name: Midori, version: '1.19', type: browser }, engine: { name: Webkit, version: '525.1' }, os: { name: Linux }, device: { type: desktop } }
60
+ readable: 'Midori 1.19 on Linux'
includes/vendor/whichbrowser/parser/tests/data/desktop/browser-mosaic.yaml ADDED
@@ -0,0 +1,96 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ -
2
+ headers: 'User-Agent: NCSA Mosaic/2.1 (Windows x86)'
3
+ result: { browser: { name: 'NCSA Mosaic', family: Mosaic, version: '2.1', type: browser }, os: { name: Windows }, device: { type: desktop } }
4
+ readable: 'NCSA Mosaic 2.1 on Windows'
5
+ -
6
+ headers: 'User-Agent: NCSA Mosaic/2.6b1 (X11;UNIX_System_V 4.2 R4000) libwww/2.12 modified'
7
+ result: { browser: { name: 'NCSA Mosaic', family: Mosaic, version: '2.6', type: browser }, os: { name: 'UNIX System V', family: UNIX, version: '4.2' }, device: { type: desktop } }
8
+ readable: 'NCSA Mosaic 2.6 on UNIX System V 4.2'
9
+ -
10
+ headers: 'User-Agent: NCSA Mosaic/2.6b1 [en-gb] (X11;UNIX_System_V 4.2 R4000) libwww/2.12 modified'
11
+ result: { browser: { name: 'NCSA Mosaic', family: Mosaic, version: '2.6', type: browser }, os: { name: 'UNIX System V', family: UNIX, version: '4.2' }, device: { type: desktop } }
12
+ readable: 'NCSA Mosaic 2.6 on UNIX System V 4.2'
13
+ -
14
+ headers: 'User-Agent: NCSA Mosaic/3.0.0 (Windows x86)'
15
+ result: { browser: { name: 'NCSA Mosaic', family: Mosaic, version: 3.0.0, type: browser }, os: { name: Windows }, device: { type: desktop } }
16
+ readable: 'NCSA Mosaic 3.0.0 on Windows'
17
+ -
18
+ headers: 'User-Agent: NCSA_Mosaic/2.6L10N+ (X11;SunOS 5.6 sun4u) libwww/2.12 modified'
19
+ result: { browser: { name: 'NCSA Mosaic', family: Mosaic, version: '2.6', type: browser }, os: { name: Solaris, family: UNIX, version: '2.6' }, device: { type: desktop } }
20
+ readable: 'NCSA Mosaic 2.6 on Solaris 2.6'
21
+ -
22
+ headers: 'User-Agent: NEC MosaicView/1.0 libwww/2.15_Spyglass'
23
+ result: { browser: { name: 'Spyglass Mosaic', family: Mosaic, version: '1.0', type: browser } }
24
+ readable: 'Spyglass Mosaic 1.0'
25
+ -
26
+ headers: 'User-Agent: mMosaic/3.6.6 (X11;SunOS 5.8 sun4m)'
27
+ result: { browser: { name: mMosaic, family: Mosaic, version: 3.6.6, type: browser }, os: { name: Solaris, family: UNIX, version: '8' }, device: { type: desktop } }
28
+ readable: 'mMosaic 3.6.6 on Solaris 8'
29
+ -
30
+ headers: 'User-Agent: AIR_Mosaic(16bit)/v1.00.198.07'
31
+ result: { browser: { name: 'AIR Mosaic', family: Mosaic, version: '1.00', type: browser } }
32
+ readable: 'AIR Mosaic 1.00'
33
+ -
34
+ headers: 'User-Agent: AIR_Mosaic(16bit)/v3.09.04.02'
35
+ result: { browser: { name: 'AIR Mosaic', family: Mosaic, version: '3.09', type: browser } }
36
+ readable: 'AIR Mosaic 3.09'
37
+ -
38
+ headers: 'User-Agent: AIR_Mosaic(16bit)/v3.10.06.07'
39
+ result: { browser: { name: 'AIR Mosaic', family: Mosaic, version: '3.10', type: browser } }
40
+ readable: 'AIR Mosaic 3.10'
41
+ -
42
+ headers: 'User-Agent: DCL SuperMosaic/1.0.2.9J_Win32'
43
+ result: { browser: { name: SuperMosaic, family: Mosaic, version: '1.0', type: browser }, os: { name: Windows }, device: { type: desktop } }
44
+ readable: 'SuperMosaic 1.0 on Windows'
45
+ -
46
+ headers: 'User-Agent: SPRY_Mosaic(16bit)/v3.10.198.07'
47
+ result: { browser: { name: 'SPRY Mosaic', family: Mosaic, version: '3.10', type: browser } }
48
+ readable: 'SPRY Mosaic 3.10'
49
+ -
50
+ headers: 'User-Agent: SPRY_Mosaic/v8.01 (Windows 16-bit) SPRY_package/v4.00'
51
+ result: { browser: { name: 'SPRY Mosaic', family: Mosaic, version: '8.01', type: browser }, os: { name: Windows }, device: { type: desktop } }
52
+ readable: 'SPRY Mosaic 8.01 on Windows'
53
+ -
54
+ headers: 'User-Agent: WinMosaic/Version 2.0 (ALPHA 2)'
55
+ result: { browser: { name: WinMosaic, family: Mosaic, version: '2.0', type: browser }, os: { name: Windows }, device: { type: desktop } }
56
+ readable: 'WinMosaic 2.0 on Windows'
57
+ -
58
+ headers: 'User-Agent: Spyglass Mosaic/1.0'
59
+ result: { browser: { name: 'Spyglass Mosaic', family: Mosaic, version: '1.0', type: browser } }
60
+ readable: 'Spyglass Mosaic 1.0'
61
+ -
62
+ headers: 'User-Agent: Spyglass_Mosaic/2.10 Win32 TGV/2'
63
+ result: { browser: { name: 'Spyglass Mosaic', family: Mosaic, version: '2.10', type: browser }, os: { name: Windows }, device: { type: desktop } }
64
+ readable: 'Spyglass Mosaic 2.10 on Windows'
65
+ -
66
+ headers: 'User-Agent: Spyglass_Mosaic/2.11 IRIX5.2 Spyglass/11'
67
+ result: { browser: { name: 'Spyglass Mosaic', family: Mosaic, version: '2.11', type: browser }, os: { name: IRIX, family: UNIX }, device: { type: desktop } }
68
+ readable: 'Spyglass Mosaic 2.11 on IRIX'
69
+ -
70
+ headers: 'User-Agent: Spyglass_Mosaic/2.11 Mac_68000 Spyglass/6'
71
+ result: { browser: { name: 'Spyglass Mosaic', family: Mosaic, version: '2.11', type: browser } }
72
+ readable: 'Spyglass Mosaic 2.11'
73
+ -
74
+ headers: 'User-Agent: Quarterdeck Mosaic Version 1.0'
75
+ result: { browser: { name: 'Quarterdeck Mosaic', family: Mosaic, version: '1.0', type: browser } }
76
+ readable: 'Quarterdeck Mosaic 1.0'
77
+ -
78
+ headers: 'User-Agent: Quarterdeck Mosaic Version 2.0/Final/Export'
79
+ result: { browser: { name: 'Quarterdeck Mosaic', family: Mosaic, version: '2.0', type: browser } }
80
+ readable: 'Quarterdeck Mosaic 2.0'
81
+ -
82
+ headers: 'User-Agent: Quarterdeck Mosaic Version 2.01/Release/Export'
83
+ result: { browser: { name: 'Quarterdeck Mosaic', family: Mosaic, version: '2.01', type: browser } }
84
+ readable: 'Quarterdeck Mosaic 2.01'
85
+ -
86
+ headers: 'User-Agent: NCSA Mosaic for the X Window System/2.5b5 (L10N-2.4.0)'
87
+ result: { browser: { name: 'NCSA Mosaic', family: Mosaic, version: '2.5', type: browser } }
88
+ readable: 'NCSA Mosaic 2.5'
89
+ -
90
+ headers: 'User-Agent: NCSA Mosaic(tm) for Windows/Version 2.0 (ALPHA 7)'
91
+ result: { browser: { name: 'NCSA Mosaic', family: Mosaic, version: '2.0', type: browser }, os: { name: Windows }, device: { type: desktop } }
92
+ readable: 'NCSA Mosaic 2.0 on Windows'
93
+ -
94
+ headers: 'User-Agent: Mosaic/1.0r2 (Macintosh; I; 68040)'
95
+ result: { browser: { name: 'NCSA Mosaic', family: Mosaic, version: '1.0', type: browser }, os: { name: 'Mac OS' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
96
+ readable: 'NCSA Mosaic 1.0 on Mac OS'
includes/vendor/whichbrowser/parser/tests/data/desktop/browser-netfront.yaml ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ -
2
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 6.1; WKC) AppleWebKit/536.5.1 (KHTML, like Gecko) NetFrontBrowserNX/3.0.0'
3
+ result: { browser: { name: 'NetFront NX', version: '3.0', type: browser }, engine: { name: Webkit, version: 536.5.1 }, device: { type: desktop } }
4
+ readable: 'NetFront NX 3.0'
5
+ -
6
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 6.1; WKC) AppleWebKit/534.52.7 (KHTML, like Gecko) NetFrontBrowserNX/2.1.0'
7
+ result: { browser: { name: 'NetFront NX', version: '2.1', type: browser }, engine: { name: Webkit, version: 534.52.7 }, device: { type: desktop } }
8
+ readable: 'NetFront NX 2.1'
9
+ -
10
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.15 (KHTML, like Gecko) NX/3.0 Chrome/24.0.1295.0 Safari/537.15'
11
+ result: { browser: { name: 'NetFront NX', family: { name: Chrome, version: 24 }, version: '3.0', type: browser }, engine: { name: Webkit, version: '537.15' }, device: { type: desktop } }
12
+ readable: 'NetFront NX 3.0'
13
+ -
14
+ headers: 'User-Agent: NX/2.1'
15
+ result: { browser: { name: 'NetFront NX', version: '2.1', type: browser }, device: { type: desktop } }
16
+ readable: 'NetFront NX 2.1'
17
+ -
18
+ headers: 'User-Agent: NX/3.0'
19
+ result: { browser: { name: 'NetFront NX', version: '3.0', type: browser }, device: { type: desktop } }
20
+ readable: 'NetFront NX 3.0'
includes/vendor/whichbrowser/parser/tests/data/desktop/browser-netscape.yaml ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ -
2
+ headers: 'User-Agent: Mozilla/2.02E (Win95; U)'
3
+ result: { browser: { name: 'Netscape Navigator', version: 2.0.2, type: browser }, os: { name: Windows, version: { value: '4.0', alias: '95' } }, device: { type: desktop } }
4
+ readable: 'Netscape Navigator 2.0.2 on Windows 95'
5
+ -
6
+ headers: 'User-Agent: Mozilla/2.02Gold (Win95; I)'
7
+ result: { browser: { name: 'Netscape Navigator', version: 2.0.2, type: browser }, os: { name: Windows, version: { value: '4.0', alias: '95' } }, device: { type: desktop } }
8
+ readable: 'Netscape Navigator 2.0.2 on Windows 95'
9
+ -
10
+ headers: 'User-Agent: Mozilla/3.0 (Win95; N)'
11
+ result: { browser: { name: 'Netscape Navigator', version: '3.0', type: browser }, os: { name: Windows, version: { value: '4.0', alias: '95' } }, device: { type: desktop } }
12
+ readable: 'Netscape Navigator 3.0 on Windows 95'
13
+ -
14
+ headers: 'User-Agent: Mozilla/3.0 (X11; I; OSF1 V4.0 alpha)'
15
+ result: { browser: { name: 'Netscape Navigator', version: '3.0', type: browser }, os: { name: 'Digital Unix', family: UNIX, version: '4.0' }, device: { type: desktop } }
16
+ readable: 'Netscape Navigator 3.0 on Digital Unix 4.0'
17
+ -
18
+ headers: 'User-Agent: Mozilla/3.01Gold (X11; I; Linux 2.0.32 i486)'
19
+ result: { browser: { name: 'Netscape Navigator', version: 3.0.1, type: browser }, os: { name: Linux }, device: { type: desktop } }
20
+ readable: 'Netscape Navigator 3.0.1 on Linux'
21
+ -
22
+ headers: 'User-Agent: Mozilla/3.01Gold (X11; I; SunOS 5.5.1 sun4m)'
23
+ result: { browser: { name: 'Netscape Navigator', version: 3.0.1, type: browser }, os: { name: Solaris, family: UNIX, version: 2.5.1 }, device: { type: desktop } }
24
+ readable: 'Netscape Navigator 3.0.1 on Solaris 2.5.1'
25
+ -
26
+ headers: 'User-Agent: Mozilla/3.04Gold (X11; U; IRIX 5.3 IP22)'
27
+ result: { browser: { name: 'Netscape Navigator', version: 3.0.4, type: browser }, os: { name: IRIX, family: UNIX, version: '5.3' }, device: { type: desktop } }
28
+ readable: 'Netscape Navigator 3.0.4 on IRIX 5.3'
29
+ -
30
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en-US; rv:1.8.1.10pre) Gecko/20071127 Firefox/2.0.0.10 Navigator/9.0.0.4'
31
+ result: { browser: { name: 'Netscape Navigator', family: { name: Firefox, version: 2.0.0.10 }, version: 9.0.0, type: browser }, engine: { name: Gecko, version: 1.8.1 }, os: { name: 'OS X' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
32
+ readable: 'Netscape Navigator 9.0.0 on OS X'
33
+ -
34
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en-US; rv:1.8.1.8pre) Gecko/20071019 Firefox/2.0.0.8 Navigator/9.0.0.1'
35
+ result: { browser: { name: 'Netscape Navigator', family: { name: Firefox, version: 2.0.0.8 }, version: 9.0.0, type: browser }, engine: { name: Gecko, version: 1.8.1 }, os: { name: 'OS X' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
36
+ readable: 'Netscape Navigator 9.0.0 on OS X'
37
+ -
38
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; U; PPC; xx; rv:0.9.4.1) Gecko/20020508 Netscape6/6.2.3'
39
+ result: { browser: { name: Netscape, version: 6.2.3, type: browser }, engine: { name: Gecko, version: 0.9.4 }, os: { name: 'Mac OS' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
40
+ readable: 'Netscape 6.2.3 on Mac OS'
41
+ -
42
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; U; PPC; xx; rv:1.0.2) Gecko/20030208 Netscape/7.02'
43
+ result: { browser: { name: Netscape, version: '7.02', type: browser }, engine: { name: Gecko, version: 1.0.2 }, os: { name: 'Mac OS' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
44
+ readable: 'Netscape 7.02 on Mac OS'
45
+ -
46
+ headers: 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.12) Gecko/20080219 Firefox/2.0.0.12 Navigator/9.0.0.6'
47
+ result: { browser: { name: 'Netscape Navigator', family: { name: Firefox, version: 2.0.0.12 }, version: 9.0.0, type: browser }, engine: { name: Gecko, version: 1.8.1 }, os: { name: Windows, version: { value: '5.1', alias: XP } }, device: { type: desktop } }
48
+ readable: 'Netscape Navigator 9.0.0 on Windows XP'
49
+ -
50
+ headers: 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; xx; rv:1.7.5) Gecko/20051012 Netscape/8.0.4'
51
+ result: { browser: { name: Netscape, version: 8.0.4, type: browser }, engine: { name: Gecko, version: 1.7.5 }, os: { name: Windows, version: { value: '5.1', alias: XP } }, device: { type: desktop } }
52
+ readable: 'Netscape 8.0.4 on Windows XP'
53
+ -
54
+ headers: 'User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1) Netscape/8.0.4'
55
+ result: { browser: { name: Netscape, version: 8.0.4, type: browser }, os: { name: Windows, version: { value: '5.1', alias: XP } }, device: { type: desktop } }
56
+ readable: 'Netscape 8.0.4 on Windows XP'
57
+ -
58
+ headers: 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.7.5) Gecko/20070321 Netscape/8.1.3'
59
+ result: { browser: { name: Netscape, version: 8.1.3, type: browser }, engine: { name: Gecko, version: 1.7.5 }, os: { name: Windows, version: { value: '6.0', alias: Vista } }, device: { type: desktop } }
60
+ readable: 'Netscape 8.1.3 on Windows Vista'
61
+ -
62
+ headers: 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.2; xx; rv:1.7.5) Gecko/20060127 Netscape/8.1'
63
+ result: { browser: { name: Netscape, version: '8.1', type: browser }, engine: { name: Gecko, version: 1.7.5 }, os: { name: Windows, version: { value: '6.2', alias: '8' } }, device: { type: desktop } }
64
+ readable: 'Netscape 8.1 on Windows 8'
65
+ -
66
+ headers: 'User-Agent: Mozilla/5.0 (X11; U; Linux i686; xx; rv:0.9.4) Gecko/20011022 Netscape6/6.2'
67
+ result: { browser: { name: Netscape, version: '6.2', type: browser }, engine: { name: Gecko, version: 0.9.4 }, os: { name: Linux }, device: { type: desktop } }
68
+ readable: 'Netscape 6.2 on Linux'
69
+ -
70
+ headers: 'User-Agent: Mozilla/5.0 (X11; U; Linux i686; xx; rv:1.4) Gecko/20030624 Netscape/7.1'
71
+ result: { browser: { name: Netscape, version: '7.1', type: browser }, engine: { name: Gecko, version: '1.4' }, os: { name: Linux }, device: { type: desktop } }
72
+ readable: 'Netscape 7.1 on Linux'
73
+ -
74
+ headers: 'User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; xx; rv:1.7.2) Gecko/20040805 Netscape/7.2'
75
+ result: { browser: { name: Netscape, version: '7.2', type: browser }, engine: { name: Gecko, version: 1.7.2 }, os: { name: Linux }, device: { type: desktop } }
76
+ readable: 'Netscape 7.2 on Linux'
includes/vendor/whichbrowser/parser/tests/data/desktop/browser-omniweb.yaml ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ -
2
+ headers: 'User-Agent: DoCoMo/1.0/SH505i/c20/TC/W24H12 OmniWeb/4.1.1-v424.6'
3
+ readable: 'OmniWeb 4.1.1 on OS X'
4
+ result: { browser: { name: OmniWeb, version: 4.1.1, type: browser }, os: { name: 'OS X' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
5
+ -
6
+ headers: 'User-Agent: Mozilla/4.0 (compatible; MSIE 5.12; Mac_PowerPC) OmniWeb/4.1.1-v424.6'
7
+ readable: 'OmniWeb 4.1.1 on OS X'
8
+ result: { browser: { name: OmniWeb, version: 4.1.1, type: browser }, os: { name: 'OS X' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
9
+ -
10
+ headers: 'User-Agent: Mozilla/4.0 (compatible; MSIE 5.2; Mac_PowerPC) OmniWeb/4.1.1-v424.6'
11
+ readable: 'OmniWeb 4.1.1 on OS X'
12
+ result: { browser: { name: OmniWeb, version: 4.1.1, type: browser }, os: { name: 'OS X' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
13
+ -
14
+ headers: 'User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows 98). OmniWeb/v528'
15
+ readable: 'OmniWeb 5 on OS X'
16
+ result: { browser: { name: OmniWeb, version: '5', type: browser }, engine: { name: WebCore }, os: { name: 'OS X' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
17
+ -
18
+ headers: 'User-Agent: Mozilla/4.0 (compatible; MSIE 6.0b; Windows 98) OmniWeb/4.1.1-v424.6'
19
+ readable: 'OmniWeb 4.1.1 on OS X'
20
+ result: { browser: { name: OmniWeb, version: 4.1.1, type: browser }, os: { name: 'OS X' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
21
+ -
22
+ headers: 'User-Agent: Mozilla/4.0 (compatible; MSIE 6.0b; Windows 98) OmniWeb/v496'
23
+ readable: 'OmniWeb 4 on OS X'
24
+ result: { browser: { name: OmniWeb, version: '4', type: browser }, os: { name: 'OS X' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
25
+ -
26
+ headers: 'User-Agent: Mozilla/4.5 (compatible; OmniWeb/4.0.5; Mac_PowerPC)'
27
+ readable: 'OmniWeb 4.0.5 on OS X'
28
+ result: { browser: { name: OmniWeb, version: 4.0.5, type: browser }, os: { name: 'OS X' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
29
+ -
30
+ headers: 'User-Agent: Mozilla/4.5 (compatible; OmniWeb/4.1-v422; Mac_PowerPC)'
31
+ readable: 'OmniWeb 4.1 on OS X'
32
+ result: { browser: { name: OmniWeb, version: '4.1', type: browser }, os: { name: 'OS X' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
33
+ -
34
+ headers: 'User-Agent: Mozilla/4.5 (compatible; OmniWeb/4.2-v435.5; Mac_Intel )'
35
+ readable: 'OmniWeb 4.2 on OS X'
36
+ result: { browser: { name: OmniWeb, version: '4.2', type: browser }, os: { name: 'OS X' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
37
+ -
38
+ headers: 'User-Agent: Mozilla/4.5 (compatible; OmniWeb/4.2-v435.5; Mac_PowerPC)'
39
+ readable: 'OmniWeb 4.2 on OS X'
40
+ result: { browser: { name: OmniWeb, version: '4.2', type: browser }, os: { name: 'OS X' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
41
+ -
42
+ headers: 'User-Agent: Mozilla/4.5 (compatible; OmniWeb/5.1.1; Mac_PowerPC)'
43
+ readable: 'OmniWeb 5.1.1 on OS X'
44
+ result: { browser: { name: OmniWeb, version: 5.1.1, type: browser }, engine: { name: WebCore }, os: { name: 'OS X' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
45
+ -
46
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_2; xx) AppleWebKit/10600.3.18 (KHTML, like Gecko) Version/7.0 Safari/537.71 OmniWeb/v625.0'
47
+ readable: 'OmniWeb 6 on OS X Yosemite 10.10'
48
+ result: { browser: { name: OmniWeb, version: '6', type: browser }, engine: { name: WebKit }, os: { name: 'OS X', version: { value: '10.10', nickname: Yosemite } }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
49
+ -
50
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_0; xx) AppleWebKit/11601.1.43 (KHTML, like Gecko) Version/7.0 Safari/537.71 OmniWeb/v626.0'
51
+ readable: 'OmniWeb 6 on OS X El Capitan 10.11'
52
+ result: { browser: { name: OmniWeb, version: '6', type: browser }, engine: { name: WebKit }, os: { name: 'OS X', version: { value: '10.11', nickname: 'El Capitan' } }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
53
+ -
54
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2; xx) AppleWebKit/9537.75.14 (KHTML, like Gecko) Version/7.0 Safari/537.71 OmniWeb/v624.0'
55
+ readable: 'OmniWeb 6 on OS X Mavericks 10.9'
56
+ result: { browser: { name: OmniWeb, version: '6', type: browser }, engine: { name: WebKit }, os: { name: 'OS X', version: { value: '10.9', nickname: Mavericks } }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
57
+ -
58
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.74.8 (KHTML, like Gecko) OmniWeb'
59
+ readable: 'OmniWeb on OS X Mavericks 10.9'
60
+ result: { browser: { name: OmniWeb, type: browser }, os: { name: 'OS X', version: { value: '10.9', nickname: Mavericks } }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
61
+ -
62
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; xx) AppleWebKit/533.21.1 (KHTML, like Gecko, Safari/533.19.4) Version/5.11.1 OmniWeb/622.18.0'
63
+ readable: 'OmniWeb 6 on Mac OS X 10.6'
64
+ result: { browser: { name: OmniWeb, version: '6', type: browser }, engine: { name: WebKit }, os: { name: 'OS X', alias: 'Mac OS X', version: '10.6' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
65
+ -
66
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_9_3; xx) AppleWebKit/533.21.1+(KHTML, like Gecko, Safari/533.19.4) Version/5.11.2 OmniWeb/622.19.3.0'
67
+ readable: 'OmniWeb 6 on OS X Mavericks 10.9'
68
+ result: { browser: { name: OmniWeb, version: '6', type: browser }, engine: { name: WebKit }, os: { name: 'OS X', version: { value: '10.9', nickname: Mavericks } }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
69
+ -
70
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X; xx) AppleWebKit/528.16 (KHTML, like Gecko, Safari/528.16) OmniWeb/v622.8.0.112941'
71
+ readable: 'OmniWeb 6 on OS X'
72
+ result: { browser: { name: OmniWeb, version: '6', type: browser }, engine: { name: WebKit }, os: { name: 'OS X' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
73
+ -
74
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en-US) AppleWebKit/523 (KHTML, like Gecko, Safari/523.10) OmniWeb/v615.0.97558'
75
+ readable: 'OmniWeb 6 on OS X'
76
+ result: { browser: { name: OmniWeb, version: '6', type: browser }, engine: { name: WebKit }, os: { name: 'OS X' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
77
+ -
78
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en-US) AppleWebKit/85 (KHTML, like Gecko) OmniWeb/v558.48'
79
+ readable: 'OmniWeb 5 on OS X'
80
+ result: { browser: { name: OmniWeb, version: '5', type: browser }, engine: { name: WebCore }, os: { name: 'OS X' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
81
+ -
82
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; U; PPC; en-US; rv:0.9.2) Gecko/20010726 Netscape6/6.1 OmniWeb/4.1-v422'
83
+ readable: 'OmniWeb 4.1 on OS X'
84
+ result: { browser: { name: OmniWeb, version: '4.1', type: browser }, os: { name: 'OS X' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
85
+ -
86
+ headers: 'User-Agent: Mozilla/5.0 (Windows; U; Win98; en-US; rv:0.9.2) Gecko/20010726 Netscape 6/6.1 OmniWeb/4.1-v422'
87
+ readable: 'OmniWeb 4.1 on OS X'
88
+ result: { browser: { name: OmniWeb, version: '4.1', type: browser }, os: { name: 'OS X' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
89
+ -
90
+ headers: 'User-Agent: OmniWeb/2.5 OWF/1.0'
91
+ readable: 'OmniWeb 2.5 on NextStep'
92
+ result: { browser: { name: OmniWeb, version: '2.5', type: browser }, os: { name: NextStep }, device: { type: desktop } }
includes/vendor/whichbrowser/parser/tests/data/desktop/browser-opera.yaml ADDED
@@ -0,0 +1,431 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ -
2
+ headers: 'User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 4.0; xx) Opera 8.51'
3
+ result: { browser: { name: Opera, version: '8.51', type: browser }, engine: { name: Presto }, os: { name: Windows, version: { value: '4.0', alias: 'NT 4.0' } }, device: { type: desktop } }
4
+ readable: 'Opera 8.51 on Windows NT 4.0'
5
+ -
6
+ headers: 'User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; xx) Opera 8.53'
7
+ result: { browser: { name: Opera, version: '8.53', type: browser }, engine: { name: Presto }, os: { name: Windows, version: { value: '5.1', alias: XP } }, device: { type: desktop } }
8
+ readable: 'Opera 8.53 on Windows XP'
9
+ -
10
+ headers: 'User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; xx) Opera 9.64'
11
+ result: { browser: { name: Opera, version: '9.64', type: browser }, engine: { name: Presto }, os: { name: Windows, version: { value: '5.1', alias: XP } }, device: { type: desktop } }
12
+ readable: 'Opera 9.64 on Windows XP'
13
+ -
14
+ headers: 'User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 6.1; xx) Opera 8.50'
15
+ result: { browser: { name: Opera, version: '8.50', type: browser }, engine: { name: Presto }, os: { name: Windows, version: { value: '6.1', alias: '7' } }, device: { type: desktop } }
16
+ readable: 'Opera 8.50 on Windows 7'
17
+ -
18
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.44 Safari/537.36 OPR/24.0.1558.25 (Edition Next)'
19
+ result: { browser: { name: Opera, family: { name: Chrome, version: 37 }, version: '24.0', type: browser }, engine: { name: Blink }, os: { name: 'OS X', version: { value: '10.10', nickname: Yosemite } }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
20
+ readable: 'Opera Next 24.0 on OS X Yosemite 10.10'
21
+ -
22
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2101.0 Safari/537.36 OPR/25.0.1592.0 (Edition Developer)'
23
+ result: { browser: { name: Opera, family: { name: Chrome, version: 38 }, version: '25.0', type: browser }, engine: { name: Blink }, os: { name: 'OS X', version: { value: '10.10', nickname: Yosemite } }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
24
+ readable: 'Opera Developer 25.0 on OS X Yosemite 10.10'
25
+ -
26
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2159.4 Safari/537.36 OPR/26.0.1646.0 (Edition developer)'
27
+ result: { browser: { name: Opera, family: { name: Chrome, version: 39 }, version: '26.0', type: browser }, engine: { name: Blink }, os: { name: 'OS X', version: { value: '10.10', nickname: Yosemite } }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
28
+ readable: 'Opera Developer 26.0 on OS X Yosemite 10.10'
29
+ -
30
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.53 Safari/537.36 OPR/28.0.1750.31 (Edition beta)'
31
+ result: { browser: { name: Opera, family: { name: Chrome, version: 41 }, version: '28.0', type: browser }, engine: { name: Blink }, os: { name: 'OS X', version: { value: '10.10', nickname: Yosemite } }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
32
+ readable: 'Opera Beta 28.0 on OS X Yosemite 10.10'
33
+ -
34
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.85 Safari/537.36 OPR/32.0.1948.25'
35
+ result: { browser: { name: Opera, family: { name: Chrome, version: 45 }, version: '32.0', type: browser }, engine: { name: Blink }, os: { name: 'OS X', version: { value: '10.11', nickname: 'El Capitan' } }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
36
+ readable: 'Opera 32.0 on OS X El Capitan 10.11'
37
+ -
38
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.76 Safari/537.36 OPR/19.0.1326.47'
39
+ result: { browser: { name: Opera, family: { name: Chrome, version: 32 }, version: '19.0', type: browser }, engine: { name: Blink }, os: { name: 'OS X', version: { value: '10.7', nickname: Lion } }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
40
+ readable: 'Opera 19.0 on OS X Lion 10.7'
41
+ -
42
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.49 Safari/537.36 OPR/16.0.1196.45 (Edition Next)'
43
+ result: { browser: { name: Opera, family: { name: Chrome, version: 29 }, version: '16.0', type: browser }, engine: { name: Blink }, os: { name: 'OS X', version: { value: '10.9', nickname: Mavericks } }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
44
+ readable: 'Opera Next 16.0 on OS X Mavericks 10.9'
45
+ -
46
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.57 Safari/537.36 OPR/18.0.1284.49'
47
+ result: { browser: { name: Opera, family: { name: Chrome, version: 31 }, version: '18.0', type: browser }, engine: { name: Blink }, os: { name: 'OS X', version: { value: '10.9', nickname: Mavericks } }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
48
+ readable: 'Opera 18.0 on OS X Mavericks 10.9'
49
+ -
50
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.85 Safari/537.36 OPR/32.0.1948.25'
51
+ result: { browser: { name: Opera, family: { name: Chrome, version: 45 }, version: '32.0', type: browser }, engine: { name: Blink }, os: { name: 'OS X', version: { value: '10.9', nickname: Mavericks } }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
52
+ readable: 'Opera 32.0 on OS X Mavericks 10.9'
53
+ -
54
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.155 Safari/537.36 OPR/31.0.1889.180'
55
+ result: { browser: { name: Opera, family: { name: Chrome, version: 44 }, version: '31.0', type: browser }, engine: { name: Blink }, os: { name: Windows, version: { value: '10.0', alias: '10' } }, device: { type: desktop } }
56
+ readable: 'Opera 31.0 on Windows 10'
57
+ -
58
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.71 Safari/537.36 OPR/15.0.1147.138'
59
+ result: { browser: { name: Opera, family: { name: Chrome, version: 28 }, version: '15.0', type: browser }, engine: { name: Blink }, os: { name: Windows, version: { value: '5.1', alias: XP } }, device: { type: desktop } }
60
+ readable: 'Opera 15.0 on Windows XP'
61
+ -
62
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36 OPR/17.0.1241.53'
63
+ result: { browser: { name: Opera, family: { name: Chrome, version: 30 }, version: '17.0', type: browser }, engine: { name: Blink }, os: { name: Windows, version: { value: '5.1', alias: XP } }, device: { type: desktop } }
64
+ readable: 'Opera 17.0 on Windows XP'
65
+ -
66
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1664.3 Safari/537.36 OPR/19.0.1300.0 (Edition Developer)'
67
+ result: { browser: { name: Opera, family: { name: Chrome, version: 32 }, version: '19.0', type: browser }, engine: { name: Blink }, os: { name: Windows, version: { value: '5.1', alias: XP } }, device: { type: desktop } }
68
+ readable: 'Opera Developer 19.0 on Windows XP'
69
+ -
70
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.107 Safari/537.36 OPR/19.0.1326.63'
71
+ result: { browser: { name: Opera, family: { name: Chrome, version: 32 }, version: '19.0', type: browser }, engine: { name: Blink }, os: { name: Windows, version: { value: '5.1', alias: XP } }, device: { type: desktop } }
72
+ readable: 'Opera 19.0 on Windows XP'
73
+ -
74
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.149 Safari/537.36 OPR/20.0.1387.77'
75
+ result: { browser: { name: Opera, family: { name: Chrome, version: 33 }, version: '20.0', type: browser }, engine: { name: Blink }, os: { name: Windows, version: { value: '5.1', alias: XP } }, device: { type: desktop } }
76
+ readable: 'Opera 20.0 on Windows XP'
77
+ -
78
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.125 Safari/537.36 OPR/23.0.1522.75'
79
+ result: { browser: { name: Opera, family: { name: Chrome, version: 36 }, version: '23.0', type: browser }, engine: { name: Blink }, os: { name: Windows, version: { value: '5.1', alias: XP } }, device: { type: desktop } }
80
+ readable: 'Opera 23.0 on Windows XP'
81
+ -
82
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 6.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2305.3 Safari/537.36 OPR/29.0.1794.0 (Edition developer)'
83
+ result: { browser: { name: Opera, family: { name: Chrome, version: 42 }, version: '29.0', type: browser }, engine: { name: Blink }, os: { name: Windows, version: { value: '6.0', alias: Vista } }, device: { type: desktop } }
84
+ readable: 'Opera Developer 29.0 on Windows Vista'
85
+ -
86
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.32 Safari/537.36 OPR/16.0.1196.29 (Edition Next)'
87
+ result: { browser: { name: Opera, family: { name: Chrome, version: 29 }, version: '16.0', type: browser }, engine: { name: Blink }, os: { name: Windows, version: { value: '6.1', alias: '7' } }, device: { type: desktop } }
88
+ readable: 'Opera Next 16.0 on Windows 7'
89
+ -
90
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.57 Safari/537.36 OPR/18.0.1284.49'
91
+ result: { browser: { name: Opera, family: { name: Chrome, version: 31 }, version: '18.0', type: browser }, engine: { name: Blink }, os: { name: Windows, version: { value: '6.1', alias: '7' } }, device: { type: desktop } }
92
+ readable: 'Opera 18.0 on Windows 7'
93
+ -
94
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.65 Safari/537.36 OPR/26.0.1656.32'
95
+ result: { browser: { name: Opera, family: { name: Chrome, version: 39 }, version: '26.0', type: browser }, engine: { name: Blink }, os: { name: Windows, version: { value: '6.1', alias: '7' } }, device: { type: desktop } }
96
+ readable: 'Opera 26.0 on Windows 7'
97
+ -
98
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) Presto/2.12.388 Opera/12.16'
99
+ result: { browser: { name: Opera, version: '12.16', type: browser }, engine: { name: Presto, version: 2.12.388 }, os: { name: Windows, version: { value: '6.1', alias: '7' } }, device: { type: desktop } }
100
+ readable: 'Opera 12.16 on Windows 7'
101
+ -
102
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 6.3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.104 Safari/537.36 OPR/25.0.1614.63'
103
+ result: { browser: { name: Opera, family: { name: Chrome, version: 38 }, version: '25.0', type: browser }, engine: { name: Blink }, os: { name: Windows, version: { value: '6.3', alias: '8.1' } }, device: { type: desktop } }
104
+ readable: 'Opera 25.0 on Windows 8.1'
105
+ -
106
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 6.3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.81 Safari/537.36 OPR/30.0.1835.140'
107
+ result: { browser: { name: Opera, family: { name: Chrome, version: 43 }, version: '30.0', type: browser }, engine: { name: Blink }, os: { name: Windows, version: { value: '6.3', alias: '8.1' } }, device: { type: desktop } }
108
+ readable: 'Opera 30.0 on Windows 8.1'
109
+ -
110
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.30 Safari/537.36 OPR/31.0.1889.16 (Edition beta)'
111
+ result: { browser: { name: Opera, family: { name: Chrome, version: 44 }, version: '31.0', type: browser }, engine: { name: Blink }, os: { name: Windows, version: { value: '6.3', alias: '8.1' } }, device: { type: desktop } }
112
+ readable: 'Opera Beta 31.0 on Windows 8.1'
113
+ -
114
+ headers: 'User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.29 Safari/537.36 OPR/20.0.1396.70617'
115
+ result: { browser: { name: Opera, family: { name: Chrome, version: 33 }, version: '20.0', type: browser }, engine: { name: Blink }, os: { name: Linux }, device: { type: desktop } }
116
+ readable: 'Opera 20.0 on Linux'
117
+ -
118
+ headers: 'User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.44 Safari/537.36 OPR/25.0.1614.11 (Edition beta)'
119
+ result: { browser: { name: Opera, family: { name: Chrome, version: 38 }, version: '25.0', type: browser }, engine: { name: Blink }, os: { name: Linux }, device: { type: desktop } }
120
+ readable: 'Opera Beta 25.0 on Linux'
121
+ -
122
+ headers: 'User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.59 Safari/537.36 OPR/26.0.1656.87215'
123
+ result: { browser: { name: Opera, family: { name: Chrome, version: 39 }, version: '26.0', type: browser }, engine: { name: Blink }, os: { name: Linux }, device: { type: desktop } }
124
+ readable: 'Opera 26.0 on Linux'
125
+ -
126
+ headers: 'User-Agent: Mozilla/5.0 (X11; Slackware Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2188.2 Safari/537.36 OPR/27.0.1683.0 (Edition developer)'
127
+ result: { browser: { name: Opera, family: { name: Chrome, version: 40 }, version: '27.0', type: browser }, engine: { name: Blink }, os: { name: Slackware }, device: { type: desktop } }
128
+ readable: 'Opera Developer 27.0 on Slackware'
129
+ -
130
+ headers: 'User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 5.0) Opera 12.12'
131
+ result: { browser: { name: Opera, version: '12.12', type: browser }, engine: { name: Presto }, os: { name: Windows, version: { value: '5.0', alias: '2000' } }, device: { type: desktop } }
132
+ readable: 'Opera 12.12 on Windows 2000'
133
+ -
134
+ headers: 'User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 5.1) Opera 12.14'
135
+ result: { browser: { name: Opera, version: '12.14', type: browser }, engine: { name: Presto }, os: { name: Windows, version: { value: '5.1', alias: XP } }, device: { type: desktop } }
136
+ readable: 'Opera 12.14 on Windows XP'
137
+ -
138
+ headers: 'User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1) Opera 12.15'
139
+ result: { browser: { name: Opera, version: '12.15', type: browser }, engine: { name: Presto }, os: { name: Windows, version: { value: '6.1', alias: '7' } }, device: { type: desktop } }
140
+ readable: 'Opera 12.15 on Windows 7'
141
+ -
142
+ headers: 'User-Agent: Opera/10.00 (Windows NT 5.1; U; xx)'
143
+ result: { browser: { name: Opera, version: '10.00', type: browser }, engine: { name: Presto }, os: { name: Windows, version: { value: '5.1', alias: XP } }, device: { type: desktop } }
144
+ readable: 'Opera 10.00 on Windows XP'
145
+ -
146
+ headers: 'User-Agent: Opera/10.00 (Windows NT 5.1; U; xx) Presto/2.2.0'
147
+ result: { browser: { name: Opera, version: '10.00', type: browser }, engine: { name: Presto, version: 2.2.0 }, os: { name: Windows, version: { value: '5.1', alias: XP } }, device: { type: desktop } }
148
+ readable: 'Opera 10.00 on Windows XP'
149
+ -
150
+ headers: 'User-Agent: Opera/4.0 (Windows 98;US) [en]'
151
+ result: { browser: { name: Opera, version: '4.0', type: browser }, engine: { name: Electra }, os: { name: Windows, version: { value: '4.1', alias: '98' } }, device: { type: desktop } }
152
+ readable: 'Opera 4.0 on Windows 98'
153
+ -
154
+ headers: 'User-Agent: Opera/4.03 (Windows NT 4.0; U)'
155
+ result: { browser: { name: Opera, version: '4.03', type: browser }, engine: { name: Electra }, os: { name: Windows, version: { value: '4.0', alias: 'NT 4.0' } }, device: { type: desktop } }
156
+ readable: 'Opera 4.03 on Windows NT 4.0'
157
+ -
158
+ headers: 'User-Agent: Opera/6.03 (Windows 98; U) [en]'
159
+ result: { browser: { name: Opera, version: '6.03', type: browser }, engine: { name: Electra }, os: { name: Windows, version: { value: '4.1', alias: '98' } }, device: { type: desktop } }
160
+ readable: 'Opera 6.03 on Windows 98'
161
+ -
162
+ headers: 'User-Agent: Opera/8.01 (Windows 98; U; xx)'
163
+ result: { browser: { name: Opera, version: '8.01', type: browser }, engine: { name: Presto }, os: { name: Windows, version: { value: '4.1', alias: '98' } }, device: { type: desktop } }
164
+ readable: 'Opera 8.01 on Windows 98'
165
+ -
166
+ headers: 'User-Agent: Opera/8.52 (Windows NT 5.1; U; xx)'
167
+ result: { browser: { name: Opera, version: '8.52', type: browser }, engine: { name: Presto }, os: { name: Windows, version: { value: '5.1', alias: XP } }, device: { type: desktop } }
168
+ readable: 'Opera 8.52 on Windows XP'
169
+ -
170
+ headers: 'User-Agent: Opera/8.54 (Windows 95; U; xx)'
171
+ result: { browser: { name: Opera, version: '8.54', type: browser }, engine: { name: Presto }, os: { name: Windows, version: { value: '4.0', alias: '95' } }, device: { type: desktop } }
172
+ readable: 'Opera 8.54 on Windows 95'
173
+ -
174
+ headers: 'User-Agent: Opera/9.00 (Windows 95; U; xx)'
175
+ result: { browser: { name: Opera, version: '9.00', type: browser }, engine: { name: Presto }, os: { name: Windows, version: { value: '4.0', alias: '95' } }, device: { type: desktop } }
176
+ readable: 'Opera 9.00 on Windows 95'
177
+ -
178
+ headers: 'User-Agent: Opera/9.00 (Windows NT 4.0; U; xx)'
179
+ result: { browser: { name: Opera, version: '9.00', type: browser }, engine: { name: Presto }, os: { name: Windows, version: { value: '4.0', alias: 'NT 4.0' } }, device: { type: desktop } }
180
+ readable: 'Opera 9.00 on Windows NT 4.0'
181
+ -
182
+ headers: 'User-Agent: Opera/9.02 (Windows 98; U; xx)'
183
+ result: { browser: { name: Opera, version: '9.02', type: browser }, engine: { name: Presto }, os: { name: Windows, version: { value: '4.1', alias: '98' } }, device: { type: desktop } }
184
+ readable: 'Opera 9.02 on Windows 98'
185
+ -
186
+ headers: 'User-Agent: Opera/9.20 (Windows 98; U; xx)'
187
+ result: { browser: { name: Opera, version: '9.20', type: browser }, engine: { name: Presto }, os: { name: Windows, version: { value: '4.1', alias: '98' } }, device: { type: desktop } }
188
+ readable: 'Opera 9.20 on Windows 98'
189
+ -
190
+ headers: 'User-Agent: Opera/9.21 (X11; Linux i686; U; xx)'
191
+ result: { browser: { name: Opera, version: '9.21', type: browser }, engine: { name: Presto }, os: { name: Linux }, device: { type: desktop } }
192
+ readable: 'Opera 9.21 on Linux'
193
+ -
194
+ headers: 'User-Agent: Opera/9.25 (X11; Linux i686; U; xx)'
195
+ result: { browser: { name: Opera, version: '9.25', type: browser }, engine: { name: Presto }, os: { name: Linux }, device: { type: desktop } }
196
+ readable: 'Opera 9.25 on Linux'
197
+ -
198
+ headers: 'User-Agent: Opera/9.26 (Macintosh; Intel Mac OS X; U; xx)'
199
+ result: { browser: { name: Opera, version: '9.26', type: browser }, engine: { name: Presto }, os: { name: 'OS X' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
200
+ readable: 'Opera 9.26 on OS X'
201
+ -
202
+ headers: 'User-Agent: Opera/9.26 (Windows 95; U; xx)'
203
+ result: { browser: { name: Opera, version: '9.26', type: browser }, engine: { name: Presto }, os: { name: Windows, version: { value: '4.0', alias: '95' } }, device: { type: desktop } }
204
+ readable: 'Opera 9.26 on Windows 95'
205
+ -
206
+ headers: 'User-Agent: Opera/9.27 (X11; Linux i686; U; xx)'
207
+ result: { browser: { name: Opera, version: '9.27', type: browser }, engine: { name: Presto }, os: { name: Linux }, device: { type: desktop } }
208
+ readable: 'Opera 9.27 on Linux'
209
+ -
210
+ headers: 'User-Agent: Opera/9.52 (X11; Linux x86_64; U; xx)'
211
+ result: { browser: { name: Opera, version: '9.52', type: browser }, engine: { name: Presto }, os: { name: Linux }, device: { type: desktop } }
212
+ readable: 'Opera 9.52 on Linux'
213
+ -
214
+ headers: 'User-Agent: Opera/9.63 (Windows NT 5.0; U; xx) Presto/2.1.1'
215
+ result: { browser: { name: Opera, version: '9.63', type: browser }, engine: { name: Presto, version: 2.1.1 }, os: { name: Windows, version: { value: '5.0', alias: '2000' } }, device: { type: desktop } }
216
+ readable: 'Opera 9.63 on Windows 2000'
217
+ -
218
+ headers: 'User-Agent: Opera/9.64 (Macintosh; PPC Mac OS X; U; xx) Presto/2.1.1'
219
+ result: { browser: { name: Opera, version: '9.64', type: browser }, engine: { name: Presto, version: 2.1.1 }, os: { name: 'OS X' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
220
+ readable: 'Opera 9.64 on OS X'
221
+ -
222
+ headers: 'User-Agent: Opera/9.80 (Linux armv7l; U; xx) Presto/2.9.219 Version/12.00'
223
+ result: { browser: { name: Opera, version: '12.00', type: browser }, engine: { name: Presto, version: 2.9.219 }, os: { name: Linux }, device: { type: desktop } }
224
+ readable: 'Opera 12.00 on Linux'
225
+ -
226
+ headers: 'User-Agent: Opera/9.80 (Linux i686) Presto/2.12.407 Version/12.50'
227
+ result: { browser: { name: Opera, version: '12.50', type: browser }, engine: { name: Presto, version: 2.12.407 }, os: { name: Linux }, device: { type: desktop } }
228
+ readable: 'Opera 12.50 on Linux'
229
+ -
230
+ headers: 'User-Agent: Opera/9.80 (Linux; U) Version/12.17'
231
+ result: { browser: { name: Opera, version: '12.17', type: browser }, engine: { name: Presto }, os: { name: Linux }, device: { type: desktop } }
232
+ readable: 'Opera 12.17 on Linux'
233
+ -
234
+ headers: 'User-Agent: Opera/9.80 (Macintosh; Intel Mac OS X 10.10.5) Presto/2.12.388 Version/12.14'
235
+ result: { browser: { name: Opera, version: '12.14', type: browser }, engine: { name: Presto, version: 2.12.388 }, os: { name: 'OS X', version: { value: '10.10', nickname: Yosemite } }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
236
+ readable: 'Opera 12.14 on OS X Yosemite 10.10'
237
+ -
238
+ headers: 'User-Agent: Opera/9.80 (Macintosh; Intel Mac OS X 10.5.8; U; Edition Next; xx) Presto/2.10.269 Version/12.00'
239
+ result: { browser: { name: Opera, version: '12.00', type: browser }, engine: { name: Presto, version: 2.10.269 }, os: { name: 'OS X', alias: 'Mac OS X', version: '10.5' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
240
+ readable: 'Opera Next 12.00 on Mac OS X 10.5'
241
+ -
242
+ headers: 'User-Agent: Opera/9.80 (Macintosh; Intel Mac OS X 10.6.8; U; Edition Labs HTML5 Parser; xx) Presto/2.9.181 Version/12.00'
243
+ result: { browser: { name: Opera, version: '12.00', type: browser }, engine: { name: Presto, version: 2.9.181 }, os: { name: 'OS X', alias: 'Mac OS X', version: '10.6' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
244
+ readable: 'Opera Labs 12.00 on Mac OS X 10.6'
245
+ -
246
+ headers: 'User-Agent: Opera/9.80 (Macintosh; Intel Mac OS X 10.7.3; U; Edition MacAppStore; xx) Presto/2.9.168 Version/11.51'
247
+ result: { browser: { name: Opera, version: '11.51', type: browser }, engine: { name: Presto, version: 2.9.168 }, os: { name: 'OS X', version: { value: '10.7', nickname: Lion } }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
248
+ readable: 'Opera 11.51 on OS X Lion 10.7'
249
+ -
250
+ headers: 'User-Agent: Opera/9.80 (Macintosh; Intel Mac OS X 10.8.2) Presto/2.12.388 Version/12.15'
251
+ result: { browser: { name: Opera, version: '12.15', type: browser }, engine: { name: Presto, version: 2.12.388 }, os: { name: 'OS X', version: { value: '10.8', nickname: 'Mountain Lion' } }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
252
+ readable: 'Opera 12.15 on OS X Mountain Lion 10.8'
253
+ -
254
+ headers: 'User-Agent: Opera/9.80 (Macintosh; Intel Mac OS X 10.8.2; Edition Next) Presto/2.12.388 Version/12.10'
255
+ result: { browser: { name: Opera, version: '12.10', type: browser }, engine: { name: Presto, version: 2.12.388 }, os: { name: 'OS X', version: { value: '10.8', nickname: 'Mountain Lion' } }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
256
+ readable: 'Opera Next 12.10 on OS X Mountain Lion 10.8'
257
+ -
258
+ headers: 'User-Agent: Opera/9.80 (Macintosh; Intel Mac OS X 10.8.2; Mac App Store Edition) Presto/2.12.388 Version/12.11'
259
+ result: { browser: { name: Opera, version: '12.11', type: browser }, engine: { name: Presto, version: 2.12.388 }, os: { name: 'OS X', version: { value: '10.8', nickname: 'Mountain Lion' } }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
260
+ readable: 'Opera 12.11 on OS X Mountain Lion 10.8'
261
+ -
262
+ headers: 'User-Agent: Opera/9.80 (Macintosh; Intel Mac OS X 10.8.4) Presto/2.12.388 Version/12.12'
263
+ result: { browser: { name: Opera, version: '12.12', type: browser }, engine: { name: Presto, version: 2.12.388 }, os: { name: 'OS X', version: { value: '10.8', nickname: 'Mountain Lion' } }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
264
+ readable: 'Opera 12.12 on OS X Mountain Lion 10.8'
265
+ -
266
+ headers: 'User-Agent: Opera/9.80 (Macintosh; Intel Mac OS X 10.9.2; U; Edition Next; xx) Presto/2.11.310 Version/12.50'
267
+ result: { browser: { name: Opera, version: '12.50', type: browser }, engine: { name: Presto, version: 2.11.310 }, os: { name: 'OS X', version: { value: '10.9', nickname: Mavericks } }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
268
+ readable: 'Opera Next 12.50 on OS X Mavericks 10.9'
269
+ -
270
+ headers: 'User-Agent: Opera/9.80 (Macintosh; PPC Mac OS X; U; xx) Presto/2.6.30 Version/10.60'
271
+ result: { browser: { name: Opera, version: '10.60', type: browser }, engine: { name: Presto, version: 2.6.30 }, os: { name: 'OS X' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
272
+ readable: 'Opera 10.60 on OS X'
273
+ -
274
+ headers: 'User-Agent: Opera/9.80 (Windows 98; U; xx) Presto/2.10.229 Version/11.62'
275
+ result: { browser: { name: Opera, version: '11.62', type: browser }, engine: { name: Presto, version: 2.10.229 }, os: { name: Windows, version: { value: '4.1', alias: '98' } }, device: { type: desktop } }
276
+ readable: 'Opera 11.62 on Windows 98'
277
+ -
278
+ headers: 'User-Agent: Opera/9.80 (Windows ME; U; xx) Presto/2.10.229 Version/11.60'
279
+ result: { browser: { name: Opera, version: '11.60', type: browser }, engine: { name: Presto, version: 2.10.229 }, os: { name: Windows, version: { value: '4.9', alias: ME } }, device: { type: desktop } }
280
+ readable: 'Opera 11.60 on Windows ME'
281
+ -
282
+ headers: 'User-Agent: Opera/9.80 (Windows NT 5.0; U; xx) Presto/2.2.15 Version/10.10'
283
+ result: { browser: { name: Opera, version: '10.10', type: browser }, engine: { name: Presto, version: 2.2.15 }, os: { name: Windows, version: { value: '5.0', alias: '2000' } }, device: { type: desktop } }
284
+ readable: 'Opera 10.10 on Windows 2000'
285
+ -
286
+ headers: 'User-Agent: Opera/9.80 (Windows NT 5.1; Edition IBIS) Presto/2.12.388 Version/12.11'
287
+ result: { browser: { name: Opera, version: '12.11', type: browser }, engine: { name: Presto, version: 2.12.388 }, os: { name: Windows, version: { value: '5.1', alias: XP } }, device: { type: desktop } }
288
+ readable: 'Opera 12.11 on Windows XP'
289
+ -
290
+ headers: 'User-Agent: Opera/9.80 (Windows NT 5.1; Edition Labs ) Presto/2.12.388 Version/12.17'
291
+ result: { browser: { name: Opera, version: '12.17', type: browser }, engine: { name: Presto, version: 2.12.388 }, os: { name: Windows, version: { value: '5.1', alias: XP } }, device: { type: desktop } }
292
+ readable: 'Opera Labs 12.17 on Windows XP'
293
+ -
294
+ headers: 'User-Agent: Opera/9.80 (Windows NT 5.1; Edition Next) Presto/2.12.370 Version/12.50'
295
+ result: { browser: { name: Opera, version: '12.50', type: browser }, engine: { name: Presto, version: 2.12.370 }, os: { name: Windows, version: { value: '5.1', alias: XP } }, device: { type: desktop } }
296
+ readable: 'Opera Next 12.50 on Windows XP'
297
+ -
298
+ headers: 'User-Agent: Opera/9.80 (Windows NT 5.1; U; Edition Next; Edition IBIS; xx) Presto/2.10.238 Version/12.00'
299
+ result: { browser: { name: Opera, version: '12.00', type: browser }, engine: { name: Presto, version: 2.10.238 }, os: { name: Windows, version: { value: '5.1', alias: XP } }, device: { type: desktop } }
300
+ readable: 'Opera Next 12.00 on Windows XP'
301
+ -
302
+ headers: 'User-Agent: Opera/9.80 (Windows NT 5.1; U; Edition Next; xx) Presto/2.11.310 Version/12.50'
303
+ result: { browser: { name: Opera, version: '12.50', type: browser }, engine: { name: Presto, version: 2.11.310 }, os: { name: Windows, version: { value: '5.1', alias: XP } }, device: { type: desktop } }
304
+ readable: 'Opera Next 12.50 on Windows XP'
305
+ -
306
+ headers: 'User-Agent: Opera/9.80 (Windows NT 5.1; U; xx) Presto/2.7.62 Version/11.01'
307
+ result: { browser: { name: Opera, version: '11.01', type: browser }, engine: { name: Presto, version: 2.7.62 }, os: { name: Windows, version: { value: '5.1', alias: XP } }, device: { type: desktop } }
308
+ readable: 'Opera 11.01 on Windows XP'
309
+ -
310
+ headers: 'User-Agent: Opera/9.80 (Windows NT 5.2; U; Edition Labs HTML5 Parser; xx) Presto/2.9.181 Version/12.00'
311
+ result: { browser: { name: Opera, version: '12.00', type: browser }, engine: { name: Presto, version: 2.9.181 }, os: { name: Windows, version: { value: '5.2', alias: 'Server 2003' } }, device: { type: desktop } }
312
+ readable: 'Opera Labs 12.00 on Windows Server 2003'
313
+ -
314
+ headers: 'User-Agent: Opera/9.80 (Windows NT 5.2; U; Edition Next; xx) Presto/2.10.289 Version/12.00'
315
+ result: { browser: { name: Opera, version: '12.00', type: browser }, engine: { name: Presto, version: 2.10.289 }, os: { name: Windows, version: { value: '5.2', alias: 'Server 2003' } }, device: { type: desktop } }
316
+ readable: 'Opera Next 12.00 on Windows Server 2003'
317
+ -
318
+ headers: 'User-Agent: Opera/9.80 (Windows NT 5.2; WOW64; U; Edition Next; xx) Presto/2.10.282 Version/12.00'
319
+ result: { browser: { name: Opera, version: '12.00', type: browser }, engine: { name: Presto, version: 2.10.282 }, os: { name: Windows, version: { value: '5.2', alias: 'Server 2003' } }, device: { type: desktop } }
320
+ readable: 'Opera Next 12.00 on Windows Server 2003'
321
+ -
322
+ headers: 'User-Agent: Opera/9.80 (Windows NT 5.2; WOW64; U; xx) Presto/2.10.289 Version/12.02'
323
+ result: { browser: { name: Opera, version: '12.02', type: browser }, engine: { name: Presto, version: 2.10.289 }, os: { name: Windows, version: { value: '5.2', alias: 'Server 2003' } }, device: { type: desktop } }
324
+ readable: 'Opera 12.02 on Windows Server 2003'
325
+ -
326
+ headers: 'User-Agent: Opera/9.80 (Windows NT 5.2; Win64; x64; Edition Next) Presto/2.12.388 Version/12.13'
327
+ result: { browser: { name: Opera, version: '12.13', type: browser }, engine: { name: Presto, version: 2.12.388 }, os: { name: Windows, version: { value: '5.2', alias: 'Server 2003' } }, device: { type: desktop } }
328
+ readable: 'Opera Next 12.13 on Windows Server 2003'
329
+ -
330
+ headers: 'User-Agent: Opera/9.80 (Windows NT 5.2; Win64; x64; U; Edition Next; xx) Presto/2.10.289 Version/12.00'
331
+ result: { browser: { name: Opera, version: '12.00', type: browser }, engine: { name: Presto, version: 2.10.289 }, os: { name: Windows, version: { value: '5.2', alias: 'Server 2003' } }, device: { type: desktop } }
332
+ readable: 'Opera Next 12.00 on Windows Server 2003'
333
+ -
334
+ headers: 'User-Agent: Opera/9.80 (Windows NT 6.0) Presto/2.12.388 Version/12.15'
335
+ result: { browser: { name: Opera, version: '12.15', type: browser }, engine: { name: Presto, version: 2.12.388 }, os: { name: Windows, version: { value: '6.0', alias: Vista } }, device: { type: desktop } }
336
+ readable: 'Opera 12.15 on Windows Vista'
337
+ -
338
+ headers: 'User-Agent: Opera/9.80 (Windows NT 6.0; U; IBM EVV/3.0/EAK01AG9/LE; Edition NCSD0; xx) Presto/2.10.229 Version/11.62'
339
+ result: { browser: { name: Opera, version: '11.62', type: browser }, engine: { name: Presto, version: 2.10.229 }, os: { name: Windows, version: { value: '6.0', alias: Vista } }, device: { type: desktop } }
340
+ readable: 'Opera 11.62 on Windows Vista'
341
+ -
342
+ headers: 'User-Agent: Opera/9.80 (Windows NT 6.0; U; xx) Presto/2.5.24 Version/10.53'
343
+ result: { browser: { name: Opera, version: '10.53', type: browser }, engine: { name: Presto, version: 2.5.24 }, os: { name: Windows, version: { value: '6.0', alias: Vista } }, device: { type: desktop } }
344
+ readable: 'Opera 10.53 on Windows Vista'
345
+ -
346
+ headers: 'User-Agent: Opera/9.80 (Windows NT 6.0; WOW64; Edition Next) Presto/2.12.388 Version/12.12'
347
+ result: { browser: { name: Opera, version: '12.12', type: browser }, engine: { name: Presto, version: 2.12.388 }, os: { name: Windows, version: { value: '6.0', alias: Vista } }, device: { type: desktop } }
348
+ readable: 'Opera Next 12.12 on Windows Vista'
349
+ -
350
+ headers: 'User-Agent: Opera/9.80 (Windows NT 6.0; Win64; x64; U; Edition Next; xx) Presto/2.11.310 Version/12.50'
351
+ result: { browser: { name: Opera, version: '12.50', type: browser }, engine: { name: Presto, version: 2.11.310 }, os: { name: Windows, version: { value: '6.0', alias: Vista } }, device: { type: desktop } }
352
+ readable: 'Opera Next 12.50 on Windows Vista'
353
+ -
354
+ headers: 'User-Agent: Opera/9.80 (Windows NT 6.1; U; Edition Labs HTML5 Parser; xx) Presto/2.9.181 Version/12.00'
355
+ result: { browser: { name: Opera, version: '12.00', type: browser }, engine: { name: Presto, version: 2.9.181 }, os: { name: Windows, version: { value: '6.1', alias: '7' } }, device: { type: desktop } }
356
+ readable: 'Opera Labs 12.00 on Windows 7'
357
+ -
358
+ headers: 'User-Agent: Opera/9.80 (Windows NT 6.1; U; xx) Presto/2.6.31 Version/10.70'
359
+ result: { browser: { name: Opera, version: '10.70', type: browser }, engine: { name: Presto, version: 2.6.31 }, os: { name: Windows, version: { value: '6.1', alias: '7' } }, device: { type: desktop } }
360
+ readable: 'Opera 10.70 on Windows 7'
361
+ -
362
+ headers: 'User-Agent: Opera/9.80 (Windows NT 6.1; U;) Presto/2.10.229 Version/11.61'
363
+ result: { browser: { name: Opera, version: '11.61', type: browser }, engine: { name: Presto, version: 2.10.229 }, os: { name: Windows, version: { value: '6.1', alias: '7' } }, device: { type: desktop } }
364
+ readable: 'Opera 11.61 on Windows 7'
365
+ -
366
+ headers: 'User-Agent: Opera/9.80 (Windows NT 6.1; WOW64; Edition Labs ) Presto/2.12.388 Version/12.15'
367
+ result: { browser: { name: Opera, version: '12.15', type: browser }, engine: { name: Presto, version: 2.12.388 }, os: { name: Windows, version: { value: '6.1', alias: '7' } }, device: { type: desktop } }
368
+ readable: 'Opera Labs 12.15 on Windows 7'
369
+ -
370
+ headers: 'User-Agent: Opera/9.80 (Windows NT 6.1; Win64; x64; U; xx)'
371
+ result: { browser: { name: Opera, version: '9.80', type: browser }, engine: { name: Presto }, os: { name: Windows, version: { value: '6.1', alias: '7' } }, device: { type: desktop } }
372
+ readable: 'Opera 9.80 on Windows 7'
373
+ -
374
+ headers: 'User-Agent: Opera/9.80 (Windows NT 6.2) Presto/2.12.388 Version/12.10'
375
+ result: { browser: { name: Opera, version: '12.10', type: browser }, engine: { name: Presto, version: 2.12.388 }, os: { name: Windows, version: { value: '6.2', alias: '8' } }, device: { type: desktop } }
376
+ readable: 'Opera 12.10 on Windows 8'
377
+ -
378
+ headers: 'User-Agent: Opera/9.80 (Windows) Version/12.02'
379
+ result: { browser: { name: Opera, version: '12.02', type: browser }, engine: { name: Presto }, os: { name: Windows }, device: { type: desktop } }
380
+ readable: 'Opera 12.02 on Windows'
381
+ -
382
+ headers: 'User-Agent: Opera/9.80 (Windows) Version/12.10'
383
+ result: { browser: { name: Opera, version: '12.10', type: browser }, engine: { name: Presto }, os: { name: Windows }, device: { type: desktop } }
384
+ readable: 'Opera 12.10 on Windows'
385
+ -
386
+ headers: 'User-Agent: Opera/9.80 (X11; FreeBSD 8.4-RELEASE-p1 i386) Presto/2.12.388 Version/12.16'
387
+ result: { browser: { name: Opera, version: '12.16', type: browser }, engine: { name: Presto, version: 2.12.388 }, os: { name: FreeBSD, family: BSD, version: '8.4' }, device: { type: desktop } }
388
+ readable: 'Opera 12.16 on FreeBSD 8.4'
389
+ -
390
+ headers: 'User-Agent: Opera/9.80 (X11; Linux i686; U; Edition Labs Camera and Pages; xx) Presto/2.9.220 Version/12.00'
391
+ result: { browser: { name: Opera, version: '12.00', type: browser }, engine: { name: Presto, version: 2.9.220 }, os: { name: Linux }, device: { type: desktop } }
392
+ readable: 'Opera Labs 12.00 on Linux'
393
+ -
394
+ headers: 'User-Agent: Opera/9.80 (X11; Linux i686; U; xx) Presto/2.6.30 Version/10.60'
395
+ result: { browser: { name: Opera, version: '10.60', type: browser }, engine: { name: Presto, version: 2.6.30 }, os: { name: Linux }, device: { type: desktop } }
396
+ readable: 'Opera 10.60 on Linux'
397
+ -
398
+ headers: 'User-Agent: Opera/9.80 (X11; Linux x86_64) Presto/2.12.388 Version/12.16'
399
+ result: { browser: { name: Opera, version: '12.16', type: browser }, engine: { name: Presto, version: 2.12.388 }, os: { name: Linux }, device: { type: desktop } }
400
+ readable: 'Opera 12.16 on Linux'
401
+ -
402
+ headers: 'User-Agent: Opera/9.80 (X11; Linux x86_64; U; xx) Presto/2.6.30 Version/10.63'
403
+ result: { browser: { name: Opera, version: '10.63', type: browser }, engine: { name: Presto, version: 2.6.30 }, os: { name: Linux }, device: { type: desktop } }
404
+ readable: 'Opera 10.63 on Linux'
405
+ -
406
+ headers: 'User-Agent: Opera/9.80 (X11; SunOS i86pc; U; xx) Presto/2.2.15 Version/10.11'
407
+ result: { browser: { name: Opera, version: '10.11', type: browser }, engine: { name: Presto, version: 2.2.15 }, os: { name: Solaris, family: UNIX }, device: { type: desktop } }
408
+ readable: 'Opera 10.11 on Solaris'
409
+ -
410
+ headers: 'User-Agent: Opera/9.0 (Macintosh; U; PPC Mac OS; de)'
411
+ result: { browser: { name: Opera, version: '9.0', type: browser }, engine: { name: Presto }, os: { name: 'Mac OS' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
412
+ readable: 'Opera 9.0 on Mac OS'
413
+ -
414
+ headers: 'User-Agent: Opera/6.0 (Macintosh; PPC; U) [en]'
415
+ result: { browser: { name: Opera, version: '6.0', type: browser }, engine: { name: Electra }, os: { name: 'Mac OS' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
416
+ readable: 'Opera 6.0 on Mac OS'
417
+ -
418
+ headers: 'User-Agent: Opera/5.0 (Macintosh;US;PPC) TP [en]'
419
+ result: { browser: { name: Opera, version: '5.0', type: browser }, engine: { name: Electra }, os: { name: 'Mac OS' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
420
+ readable: 'Opera 5.0 on Mac OS'
421
+ -
422
+ headers: 'User-Agent: Opera/5.0 (Macintosh;US;PPC) [en]'
423
+ result: { browser: { name: Opera, version: '5.0', type: browser }, engine: { name: Electra }, os: { name: 'Mac OS' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
424
+ readable: 'Opera 5.0 on Mac OS'
425
+ -
426
+ headers: 'User-Agent: Opera/9.80 (Windows NT 6.2; Win64; x64) Presto/2.12.388 Version/12.16'
427
+ useragent: 'Opera/9.80 (Windows NT 6.2; Win64; x64) Presto/2.12.388 Version/12.16'
428
+ engine: 2
429
+ features: 94
430
+ result: { browser: { name: Opera, version: '12.16', type: browser }, engine: { name: Presto, version: 2.12.388 }, os: { name: Windows, version: { value: '6.2', alias: '8' } }, device: { type: desktop } }
431
+ readable: 'Opera 12.16 on Windows 8'
includes/vendor/whichbrowser/parser/tests/data/desktop/browser-other.yaml ADDED
@@ -0,0 +1,160 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ -
2
+ headers: 'User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; Avant Browser; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; CPDTDF; Avant Browser)'
3
+ result: { browser: { name: 'Avant Browser', type: browser }, engine: { name: Trident, version: '4.0' }, os: { name: Windows, version: { value: '6.1', alias: '7' } }, device: { type: desktop, manufacturer: Compaq } }
4
+ readable: 'Avant Browser on Windows 7'
5
+ -
6
+ headers: 'User-Agent: Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0; Avant Browser)'
7
+ result: { browser: { name: 'Avant Browser', type: browser }, engine: { name: Trident, version: '6.0' }, os: { name: Windows, version: { value: '6.2', alias: '8' } }, device: { type: desktop } }
8
+ readable: 'Avant Browser on Windows 8'
9
+ -
10
+ headers: 'User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.2; Trident/5.0; SlimBrowser)'
11
+ result: { browser: { name: SlimBrowser, type: browser }, engine: { name: Trident, version: '5.0' }, os: { name: Windows, version: { value: '6.2', alias: '8' } }, device: { type: desktop } }
12
+ readable: 'SlimBrowser on Windows 8'
13
+ -
14
+ headers: 'User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; InfoPath.2; SlimBrowser/7.00.061)'
15
+ result: { browser: { name: SlimBrowser, version: 7.00.061, type: browser }, engine: { name: Trident, version: '4.0' }, os: { name: Windows, version: { value: '5.1', alias: XP } }, device: { type: desktop } }
16
+ readable: 'SlimBrowser 7.00.061 on Windows XP'
17
+ -
18
+ headers: 'User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; BTRS122335; 126BROWSER; .NET CLR 2.0.50727)'
19
+ result: { browser: { name: '126 Browser', type: browser }, os: { name: Windows, version: { value: '5.1', alias: XP } }, device: { type: desktop } }
20
+ readable: '126 Browser on Windows XP'
21
+ -
22
+ headers: 'User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; TheWorld)'
23
+ result: { browser: { name: 'The World', type: browser }, os: { name: Windows, version: { value: '5.1', alias: XP } }, device: { type: desktop } }
24
+ readable: 'The World on Windows XP'
25
+ -
26
+ headers: 'User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; Shuame; TheWorld 6)'
27
+ result: { browser: { name: 'The World', version: '6', type: browser }, os: { name: Windows, version: { value: '5.1', alias: XP } }, device: { type: desktop } }
28
+ readable: 'The World 6 on Windows XP'
29
+ -
30
+ headers: 'User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; TheWorld)'
31
+ result: { browser: { name: 'The World', type: browser }, engine: { name: Trident, version: '4.0' }, os: { name: Windows, version: { value: '5.1', alias: XP } }, device: { type: desktop } }
32
+ readable: 'The World on Windows XP'
33
+ -
34
+ headers: 'User-Agent: Mozilla/5.0 (N; Windows NT 5.1) AppleWebKit/534.34 (KHTML, like Gecko) Raptr Safari/534.34'
35
+ result: { browser: { name: Raptr, type: 'app:game' }, engine: { name: Webkit, version: '534.34' }, os: { name: Windows, version: { value: '5.1', alias: XP } }, device: { type: desktop } }
36
+ readable: 'Raptr on Windows XP'
37
+ -
38
+ headers: 'User-Agent: Mozilla/5.0 (N; Windows NT 6.2; WOW64) AppleWebKit/534.34 (KHTML, like Gecko) Raptr Safari/534.34'
39
+ result: { browser: { name: Raptr, type: 'app:game' }, engine: { name: Webkit, version: '534.34' }, os: { name: Windows, version: { value: '6.2', alias: '8' } }, device: { type: desktop } }
40
+ readable: 'Raptr on Windows 8'
41
+ -
42
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; PPC Mac OS X 10.4; rv:10.0.10) Gecko/20121024 Firefox/10.0.10 TenFourFox/7450'
43
+ result: { browser: { name: TenFourFox, family: { name: Firefox, version: 10.0.10 }, type: browser }, engine: { name: Gecko, version: 10.0.10 }, os: { name: 'OS X', alias: 'Mac OS X', version: '10.4' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
44
+ readable: 'TenFourFox on Mac OS X 10.4'
45
+ -
46
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; PPC Mac OS X 10.5; rv:5.0) Gecko/20110616 Firefox/5.0 TenFourFox/G5'
47
+ result: { browser: { name: TenFourFox, family: { name: Firefox, version: '5.0' }, type: browser }, engine: { name: Gecko, version: '5.0' }, os: { name: 'OS X', alias: 'Mac OS X', version: '10.5' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
48
+ readable: 'TenFourFox on Mac OS X 10.5'
49
+ -
50
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; PPC Mac OS X 10.5; rv:38.0) Gecko/20100101 Firefox/38.0 TenFourFox/7400'
51
+ result: { browser: { name: TenFourFox, family: { name: Firefox, version: '38.0' }, type: browser }, engine: { name: Gecko, version: '38.0' }, os: { name: 'OS X', alias: 'Mac OS X', version: '10.5' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
52
+ readable: 'TenFourFox on Mac OS X 10.5'
53
+ -
54
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 7Star/1.45.0.407 Safari/537.36'
55
+ result: { browser: { name: 7Star, family: { name: Chrome, version: 45 }, version: 1.45.0.407, type: browser }, engine: { name: Blink }, os: { name: Windows, version: { value: '6.1', alias: '7' } }, device: { type: desktop } }
56
+ readable: '7Star 1.45.0.407 on Windows 7'
57
+ -
58
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_0) AppleWebKit/537.36 (KHTML, like Gecko) Iridium/43.8 Safari/537.36 Chrome/43.0.2357.132'
59
+ result: { browser: { name: Iridium, family: { name: Chrome, version: 43 }, version: '43.8', type: browser }, engine: { name: Blink }, os: { name: 'OS X', version: { value: '10.11', nickname: 'El Capitan' } }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
60
+ readable: 'Iridium 43.8 on OS X El Capitan 10.11'
61
+ -
62
+ headers: 'User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Iridium/41.2 Safari/537.36 Chrome/41.0.2272.118'
63
+ result: { browser: { name: Iridium, family: { name: Chrome, version: 41 }, version: '41.2', type: browser }, engine: { name: Blink }, os: { name: Linux }, device: { type: desktop } }
64
+ readable: 'Iridium 41.2 on Linux'
65
+ -
66
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.99 Safari/537.36 2345Explorer/6.1.0.8495'
67
+ result: { browser: { name: '2345 Explorer', family: { name: Chrome, version: 39 }, version: 6.1.0, type: browser }, engine: { name: Blink }, os: { name: Windows, version: { value: '10.0', alias: '10' } }, device: { type: desktop } }
68
+ readable: '2345 Explorer 6.1.0 on Windows 10'
69
+ -
70
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.69 Safari/537.36 2345chrome v2.5.0.4435'
71
+ result: { browser: { name: '2345 Chrome', family: { name: Chrome, version: 31 }, version: 2.5.0, type: browser }, engine: { name: Blink }, os: { name: Windows, version: { value: '5.1', alias: XP } }, device: { type: desktop } }
72
+ readable: '2345 Chrome 2.5.0 on Windows XP'
73
+ -
74
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.99 Safari/537.36 2345Explorer v6.0.0.7505'
75
+ result: { browser: { name: '2345 Explorer', family: { name: Chrome, version: 39 }, version: 6.0.0, type: browser }, engine: { name: Blink }, os: { name: Windows, version: { value: '6.1', alias: '7' } }, device: { type: desktop } }
76
+ readable: '2345 Explorer 6.0.0 on Windows 7'
77
+ -
78
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.99 Safari/537.36 2345chrome v3.0.0.6668'
79
+ result: { browser: { name: '2345 Chrome', family: { name: Chrome, version: 39 }, version: 3.0.0, type: browser }, engine: { name: Blink }, os: { name: Windows, version: { value: '6.1', alias: '7' } }, device: { type: desktop } }
80
+ readable: '2345 Chrome 3.0.0 on Windows 7'
81
+ -
82
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.114 Safari/537.36 Swing/2.4.2.0'
83
+ result: { browser: { name: 'Swing Browser', family: { name: Chrome, version: 35 }, version: 2.4.2, type: browser }, engine: { name: Blink }, os: { name: Windows, version: { value: '10.0', alias: '10' } }, device: { type: desktop } }
84
+ readable: 'Swing Browser 2.4.2 on Windows 10'
85
+ -
86
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.114 Safari/537.36 Swing/2.5.0.3'
87
+ result: { browser: { name: 'Swing Browser', family: { name: Chrome, version: 35 }, version: 2.5.0, type: browser }, engine: { name: Blink }, os: { name: Windows, version: { value: '10.0', alias: '10' } }, device: { type: desktop } }
88
+ readable: 'Swing Browser 2.5.0 on Windows 10'
89
+ -
90
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.152 Safari/537.22 Swing/1.0.0.40'
91
+ result: { browser: { name: 'Swing Browser', family: { name: Chrome, version: 25 }, version: 1.0.0, type: browser }, engine: { name: Webkit, version: '537.22' }, os: { name: Windows, version: { value: '5.1', alias: XP } }, device: { type: desktop } }
92
+ readable: 'Swing Browser 1.0.0 on Windows XP'
93
+ -
94
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.152 Safari/537.22 Swing/1.1.2.0'
95
+ result: { browser: { name: 'Swing Browser', family: { name: Chrome, version: 25 }, version: 1.1.2, type: browser }, engine: { name: Webkit, version: '537.22' }, os: { name: Windows, version: { value: '5.1', alias: XP } }, device: { type: desktop } }
96
+ readable: 'Swing Browser 1.1.2 on Windows XP'
97
+ -
98
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.152 Safari/537.22 Swing/1.3.2.0'
99
+ result: { browser: { name: 'Swing Browser', family: { name: Chrome, version: 25 }, version: 1.3.2, type: browser }, engine: { name: Webkit, version: '537.22' }, os: { name: Windows, version: { value: '5.1', alias: XP } }, device: { type: desktop } }
100
+ readable: 'Swing Browser 1.3.2 on Windows XP'
101
+ -
102
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.114 Safari/537.36 Swing/2.4.2.0'
103
+ result: { browser: { name: 'Swing Browser', family: { name: Chrome, version: 35 }, version: 2.4.2, type: browser }, engine: { name: Blink }, os: { name: Windows, version: { value: '5.1', alias: XP } }, device: { type: desktop } }
104
+ readable: 'Swing Browser 2.4.2 on Windows XP'
105
+ -
106
+ headers: 'User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.34 Safari/534.24 Swing(And)/1.10.5.0'
107
+ result: { browser: { name: 'Swing Browser', family: { name: Chrome, version: 11 }, version: 1.10.5, type: browser }, engine: { name: Webkit, version: '534.24' }, os: { name: Linux }, device: { type: desktop } }
108
+ readable: 'Swing Browser 1.10.5 on Linux'
109
+ -
110
+ headers: 'User-Agent: Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.115 Otter/0.9.08'
111
+ result: { browser: { name: Otter, family: { name: Chrome, version: 40 }, version: 0.9.08, type: browser }, engine: { name: Blink }, os: { name: Linux }, device: { type: desktop } }
112
+ readable: 'Otter 0.9.08 on Linux'
113
+ -
114
+ headers: 'User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.115 Otter/0.9.07'
115
+ result: { browser: { name: Otter, family: { name: Chrome, version: 40 }, version: 0.9.07, type: browser }, engine: { name: Blink }, os: { name: Linux }, device: { type: desktop } }
116
+ readable: 'Otter 0.9.07 on Linux'
117
+ -
118
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.157 Safari/537.36 TungstenBrowser/2.0'
119
+ result: { browser: { name: 'Tungsten Browser', family: { name: Chrome, version: 44 }, version: '2.0', type: browser }, engine: { name: Blink }, os: { name: Windows, version: { value: '10.0', alias: '10' } }, device: { type: desktop } }
120
+ readable: 'Tungsten Browser 2.0 on Windows 10'
121
+ -
122
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.66 Beamrise/29.3.0.6900 Safari/537.36'
123
+ result: { browser: { name: Beamrise, family: { name: Chrome, version: 29 }, version: 29.3.0.6900, type: browser }, engine: { name: Blink }, os: { name: Windows, version: { value: '6.1', alias: '7' } }, device: { type: desktop } }
124
+ readable: 'Beamrise 29.3.0.6900 on Windows 7'
125
+ -
126
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36 115Browser/5.1.6'
127
+ result: { browser: { name: '115 Browser', family: { name: Chrome, version: 31 }, version: 5.1.6, type: browser }, engine: { name: Blink }, os: { name: Windows, version: { value: '5.1', alias: XP } }, device: { type: desktop } }
128
+ readable: '115 Browser 5.1.6 on Windows XP'
129
+ -
130
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36 115Browser/5.2.2'
131
+ result: { browser: { name: '115 Browser', family: { name: Chrome, version: 31 }, version: 5.2.2, type: browser }, engine: { name: Blink }, os: { name: Windows, version: { value: '5.1', alias: XP } }, device: { type: desktop } }
132
+ readable: '115 Browser 5.2.2 on Windows XP'
133
+ -
134
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.79 Safari/537.1 115Chrome/1.0.3'
135
+ result: { browser: { name: '115 Chrome', family: { name: Chrome, version: 21 }, version: 1.0.3, type: browser }, engine: { name: Webkit, version: '537.1' }, os: { name: Windows, version: { value: '6.1', alias: '7' } }, device: { type: desktop } }
136
+ readable: '115 Chrome 1.0.3 on Windows 7'
137
+ -
138
+ headers: 'User-Agent: Mozilla/4.0 (compatible; Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; GTB6; Acoo Browser; .NET CLR 1.1.4322; .NET CLR 2.0.50727); Windows NT 5.1; Trident/4.0; Maxthon; .NET CLR 2.0.50727; .NET CLR 1.1.4322; InfoPath.2)'
139
+ readable: 'Acoo Browser on Windows XP'
140
+ result: { browser: { name: 'Acoo Browser', type: browser }, engine: { name: Trident, version: '4.0' }, os: { name: Windows, version: { value: '5.1', alias: XP } }, device: { type: desktop } }
141
+ -
142
+ headers: 'User-Agent: Mozilla/4.5 (compatible; iCab 2.7.1; Macintosh; I; PPC)'
143
+ readable: 'iCab 2.7.1 on Mac OS'
144
+ result: { browser: { name: iCab, version: 2.7.1, type: browser }, os: { name: 'Mac OS' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
145
+ -
146
+ headers: 'User-Agent: Mozilla/4.5 (compatible; iCab 2.9.8; Macintosh; U; PPC)'
147
+ readable: 'iCab 2.9.8 on Mac OS'
148
+ result: { browser: { name: iCab, version: 2.9.8, type: browser }, os: { name: 'Mac OS' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
149
+ -
150
+ headers: 'User-Agent: Mozilla/4.5 (compatible; iCab Pre2.3; Macintosh; I; PPC)'
151
+ readable: 'iCab 2.3 on Mac OS'
152
+ result: { browser: { name: iCab, version: '2.3', type: browser }, os: { name: 'Mac OS' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
153
+ -
154
+ headers: 'User-Agent: Mozilla/4/5 (compatible; iCab 2.9.8; Macintosh; U; 68K)'
155
+ readable: 'iCab 2.9.8 on Mac OS'
156
+ result: { browser: { name: iCab, version: 2.9.8, type: browser }, os: { name: 'Mac OS' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
157
+ -
158
+ headers: 'User-Agent: Mozilla/5.0 (compatible; iCab 3.0.3; Macintosh; U; PPC Mac OS)'
159
+ readable: 'iCab 3.0.3 on Mac OS'
160
+ result: { browser: { name: iCab, version: 3.0.3, type: browser }, os: { name: 'Mac OS' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
includes/vendor/whichbrowser/parser/tests/data/desktop/browser-qq.yaml ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ -
2
+ headers: 'User-Agent: AppleWebKit/532.7 (KHTML, like Gecko) Chrome/4.0.271.1 Safari/532.7 TencentTraveler/5.0 QQBrowser/5.0.6642.400 (webkit)'
3
+ result: { browser: { name: 'QQ Browser', family: { name: Chrome, version: 4 }, version: '5.0', type: browser }, engine: { name: Webkit, version: '532.7' }, os: { name: Windows }, device: { type: desktop } }
4
+ readable: 'QQ Browser 5.0 on Windows'
5
+ -
6
+ headers: 'User-Agent: Mozilla/4.0 (compatible; ; QDesk 2.3.1183.202; Windows NT 6.1; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; Tablet PC 2.0) QQBrowser/6.11.11981.201'
7
+ result: { browser: { name: 'QQ Browser', version: '6.11', type: browser }, engine: { name: Trident, version: '5.0' }, os: { name: Windows, version: { value: '6.1', alias: '7' } }, device: { type: desktop } }
8
+ readable: 'QQ Browser 6.11 on Windows 7'
9
+ -
10
+ headers: 'User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; QQDownload 691; SV1) QQBrowser/6.11.12388.201'
11
+ result: { browser: { name: 'QQ Browser', version: '6.11', type: browser }, os: { name: Windows, version: { value: '5.1', alias: XP } }, device: { type: desktop } }
12
+ readable: 'QQ Browser 6.11 on Windows XP'
13
+ -
14
+ headers: 'User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET4.0C; .NET4.0E; QQBrowser/7.7.25715.400)'
15
+ result: { browser: { name: 'QQ Browser', version: '7.7', type: browser }, os: { name: Windows, version: { value: '5.1', alias: XP } }, device: { type: desktop } }
16
+ readable: 'QQ Browser 7.7 on Windows XP'
17
+ -
18
+ headers: 'User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; QQBrowser/7.6.19177.400)'
19
+ result: { browser: { name: 'QQ Browser', version: '7.6', type: browser }, os: { name: Windows, version: { value: '5.1', alias: XP } }, device: { type: desktop } }
20
+ readable: 'QQ Browser 7.6 on Windows XP'
21
+ -
22
+ headers: 'User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; Tablet PC 2.0; .NET CLR 1.1.4322; InfoPath.3; BOIE9;ZHCN) QQBrowser/6.13.13461.201'
23
+ result: { browser: { name: 'QQ Browser', version: '6.13', type: browser }, engine: { name: Trident, version: '5.0' }, os: { name: Windows, version: { value: '6.1', alias: '7' } }, device: { type: desktop } }
24
+ readable: 'QQ Browser 6.13 on Windows 7'
25
+ -
26
+ headers: 'User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0) QQBrowser/6.11.12388.201'
27
+ result: { browser: { name: 'QQ Browser', version: '6.11', type: browser }, engine: { name: Trident, version: '4.0' }, os: { name: Windows, version: { value: '5.1', alias: XP } }, device: { type: desktop } }
28
+ readable: 'QQ Browser 6.11 on Windows XP'
29
+ -
30
+ headers: 'User-Agent: Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0; QQBrowser/7.7.28658.400)'
31
+ result: { browser: { name: 'QQ Browser', version: '7.7', type: browser }, engine: { name: Trident, version: '6.0' }, os: { name: Windows, version: { value: '6.1', alias: '7' } }, device: { type: desktop } }
32
+ readable: 'QQ Browser 7.7 on Windows 7'
33
+ -
34
+ headers: 'User-Agent: Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0; .NET4.0E; .NET4.0C; QQBrowser/7.4.15649.400)'
35
+ result: { browser: { name: 'QQ Browser', version: '7.4', type: browser }, engine: { name: Trident, version: '6.0' }, os: { name: Windows, version: { value: '6.2', alias: '8' } }, device: { type: desktop } }
36
+ readable: 'QQ Browser 7.4 on Windows 8'
37
+ -
38
+ headers: 'User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0; QQBrowser/8.0.1374.400)'
39
+ result: { browser: { name: 'QQ Browser', version: '8.0', type: browser }, engine: { name: Trident, version: '5.0' }, os: { name: Windows, version: { value: '6.1', alias: '7' } }, device: { type: desktop } }
40
+ readable: 'QQ Browser 8.0 on Windows 7'
41
+ -
42
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.85 Safari/537.36 QQBrowser/3.9.3952.400'
43
+ result: { browser: { name: 'QQ Browser', family: { name: Chrome, version: 45 }, version: '3.9', type: browser }, engine: { name: Blink }, os: { name: 'OS X', version: { value: '10.11', nickname: 'El Capitan' } }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
44
+ readable: 'QQ Browser 3.9 on OS X El Capitan 10.11'
45
+ -
46
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.79 QQBrowser/1.4.0.2117 Safari/535.11'
47
+ result: { browser: { name: 'QQ Browser', family: { name: Chrome, version: 17 }, version: '1.4', type: browser }, engine: { name: Webkit, version: '535.11' }, os: { name: 'OS X', alias: 'Mac OS X', version: '10.6' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
48
+ readable: 'QQ Browser 1.4 on Mac OS X 10.6'
49
+ -
50
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.87 Safari/537.36 QQBrowser/9.2.5006.400'
51
+ result: { browser: { name: 'QQ Browser', family: { name: Chrome, version: 45 }, version: '9.2', type: browser }, engine: { name: Blink }, os: { name: Windows, version: { value: '10.0', alias: '10' } }, device: { type: desktop } }
52
+ readable: 'QQ Browser 9.2 on Windows 10'
53
+ -
54
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 4.0) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.15 Safari/535.11 QQBrowser/6.12.12934.201'
55
+ result: { browser: { name: 'QQ Browser', family: { name: Chrome, version: 17 }, version: '6.12', type: browser }, engine: { name: Webkit, version: '535.11' }, os: { name: Windows, version: { value: '4.0', alias: 'NT 4.0' } }, device: { type: desktop } }
56
+ readable: 'QQ Browser 6.12 on Windows NT 4.0'
57
+ -
58
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 4.10) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.15 Safari/535.11 QQBrowser/6.11.12135.201'
59
+ result: { browser: { name: 'QQ Browser', family: { name: Chrome, version: 17 }, version: '6.11', type: browser }, engine: { name: Webkit, version: '535.11' }, os: { name: Windows, version: { value: '4.1', alias: 'NT 4.1' } }, device: { type: desktop } }
60
+ readable: 'QQ Browser 6.11 on Windows NT 4.1'
61
+ -
62
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 5.0) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/13.0.782.41 Safari/535.1 QQBrowser/6.10.11509.201'
63
+ result: { browser: { name: 'QQ Browser', family: { name: Chrome, version: 13 }, version: '6.10', type: browser }, engine: { name: Webkit, version: '535.1' }, os: { name: Windows, version: { value: '5.0', alias: '2000' } }, device: { type: desktop } }
64
+ readable: 'QQ Browser 6.10 on Windows 2000'
65
+ -
66
+ headers: 'User-Agent: Mozilla/4.0 (compatible; MSIE 4.0; Windows NT 5.1; Trident/6.0; SLCC2; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.3; .NET4.0C; .NET CLR 1.0.3705; .NET CLR 3.0.04320; .NET4.0E; QQBrowser/7.0.3698.400)'
67
+ result: { browser: { name: 'QQ Browser', version: '7.0', type: browser }, engine: { name: Trident, version: '6.0' }, os: { name: Windows, version: { value: '5.1', alias: XP } }, device: { type: desktop } }
68
+ readable: 'QQ Browser 7.0 on Windows XP'
includes/vendor/whichbrowser/parser/tests/data/desktop/browser-safari.yaml ADDED
@@ -0,0 +1,220 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ -
2
+ headers: 'User-Agent: Apple-PubSub/65.28'
3
+ result: { browser: { name: 'Safari RSS', type: 'app:feedreader' }, os: { name: 'OS X' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
4
+ readable: 'Safari RSS on OS X'
5
+ -
6
+ headers: 'User-Agent: AppleSyndication/56.1'
7
+ result: { browser: { name: 'Safari RSS', type: 'app:feedreader' }, os: { name: 'OS X' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
8
+ readable: 'Safari RSS on OS X'
9
+ -
10
+ headers: 'User-Agent: CFNetwork/0.0.0 Darwin/0.0.0 (x86_64)'
11
+ result: { os: { name: 'OS X' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
12
+ readable: 'OS X'
13
+ -
14
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10) AppleWebKit/538.34.43 (KHTML, like Gecko) Version/8.0 Safari/538.35.3'
15
+ result: { browser: { name: Safari, version: '8.0', type: browser }, engine: { name: Webkit, version: 538.34.43 }, os: { name: 'OS X', version: { value: '10.10', nickname: Yosemite } }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
16
+ readable: 'Safari 8.0 on OS X Yosemite 10.10'
17
+ -
18
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/601.1.11+ (KHTML, like Gecko) Version/8.0.2 Safari/600.2.5'
19
+ result: { browser: { name: 'WebKit Nightly Build', type: browser }, engine: { name: Webkit, version: 601.1.11 }, os: { name: 'OS X', version: { value: '10.10', nickname: Yosemite } }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
20
+ readable: 'WebKit Nightly Build on OS X Yosemite 10.10'
21
+ -
22
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_2) AppleWebKit/600.3.13 (KHTML, like Gecko) Version/8.0.3 Safari/600.3.13'
23
+ result: { browser: { name: Safari, version: 8.0.3, type: browser }, engine: { name: Webkit, version: 600.3.13 }, os: { name: 'OS X', version: { value: '10.10', nickname: Yosemite } }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
24
+ readable: 'Safari 8.0.3 on OS X Yosemite 10.10'
25
+ -
26
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_3) AppleWebKit/600.7.9 (KHTML, like Gecko) Version/8.0.7 Safari/600.7.9'
27
+ result: { browser: { name: Safari, version: 8.0.7, type: browser }, engine: { name: Webkit, version: 600.7.9 }, os: { name: 'OS X', version: { value: '10.10', nickname: Yosemite } }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
28
+ readable: 'Safari 8.0.7 on OS X Yosemite 10.10'
29
+ -
30
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11) AppleWebKit/601.1.34 (KHTML, like Gecko) Version/9.0 Safari/601.1.34'
31
+ result: { browser: { name: Safari, version: '9.0', type: browser }, engine: { name: Webkit, version: 601.1.34 }, os: { name: 'OS X', version: { value: '10.11', nickname: 'El Capitan' } }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
32
+ readable: 'Safari 9.0 on OS X El Capitan 10.11'
33
+ -
34
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_0) AppleWebKit/601.2.7 (KHTML, like Gecko) Version/9.0.1 Safari/601.2.7'
35
+ result: { browser: { name: Safari, version: 9.0.1, type: browser }, engine: { name: Webkit, version: 601.2.7 }, os: { name: 'OS X', version: { value: '10.11', nickname: 'El Capitan' } }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
36
+ readable: 'Safari 9.0.1 on OS X El Capitan 10.11'
37
+ -
38
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_2) AppleWebKit/602.1.12+ (KHTML, like Gecko) Version/9.0.2 Safari/601.3.6'
39
+ result: { browser: { name: 'WebKit Nightly Build', type: browser }, engine: { name: Webkit, version: 602.1.12 }, os: { name: 'OS X', version: { value: '10.11', nickname: 'El Capitan' } }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
40
+ readable: 'WebKit Nightly Build on OS X El Capitan 10.11'
41
+ -
42
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_5_8) AppleWebKit/524.26.2 (KHTML, like Gecko) Version/5.0.3 Safari/533.19.4'
43
+ result: { browser: { name: Safari, version: 5.0.3, type: browser }, engine: { name: Webkit, version: 524.26.2 }, os: { name: 'OS X', alias: 'Mac OS X', version: '10.5' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
44
+ readable: 'Safari 5.0.3 on Mac OS X 10.5'
45
+ -
46
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_5_8) AppleWebKit/524.50.2 (KHTML, like Gecko) Version/4.0.5 Safari/531.22.7'
47
+ result: { browser: { name: Safari, version: 4.0.5, type: browser }, engine: { name: Webkit, version: 524.50.2 }, os: { name: 'OS X', alias: 'Mac OS X', version: '10.5' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
48
+ readable: 'Safari 4.0.5 on Mac OS X 10.5'
49
+ -
50
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_5_8) AppleWebKit/535.4+ (KHTML, like Gecko) Version/5.0.6 Safari/533.22.3'
51
+ result: { browser: { name: 'WebKit Nightly Build', type: browser }, engine: { name: Webkit, version: '535.4' }, os: { name: 'OS X', alias: 'Mac OS X', version: '10.5' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
52
+ readable: 'WebKit Nightly Build on Mac OS X 10.5'
53
+ -
54
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_2; xx) AppleWebKit/533.16 (KHTML, like Gecko) Version/5.0.3 Safari/533.16'
55
+ result: { browser: { name: Safari, version: 5.0.3, type: browser }, engine: { name: Webkit, version: '533.16' }, os: { name: 'OS X', alias: 'Mac OS X', version: '10.6' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
56
+ readable: 'Safari 5.0.3 on Mac OS X 10.6'
57
+ -
58
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_4) AppleWebKit/537.73.11 (KHTML, like Gecko) Version/6.1 Safari/537.73.11'
59
+ result: { browser: { name: Safari, version: '6.1', type: browser }, engine: { name: Webkit, version: 537.73.11 }, os: { name: 'OS X', alias: 'Mac OS X', version: '10.6' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
60
+ readable: 'Safari 6.1 on Mac OS X 10.6'
61
+ -
62
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_7) AppleWebKit/535.14 (KHTML, like Gecko) Version/5.0.5 Safari/533.21.1'
63
+ result: { browser: { name: Safari, version: 5.0.5, type: browser }, engine: { name: Webkit, version: '535.14' }, os: { name: 'OS X', alias: 'Mac OS X', version: '10.6' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
64
+ readable: 'Safari 5.0.5 on Mac OS X 10.6'
65
+ -
66
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_7) AppleWebKit/535.22+ (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27'
67
+ result: { browser: { name: 'WebKit Nightly Build', type: browser }, engine: { name: Webkit, version: '535.22' }, os: { name: 'OS X', alias: 'Mac OS X', version: '10.6' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
68
+ readable: 'WebKit Nightly Build on Mac OS X 10.6'
69
+ -
70
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/534.55.3 (KHTML, like Gecko) Version/5.1.5 Safari/534.55.3'
71
+ result: { browser: { name: Safari, version: 5.1.5, type: browser }, engine: { name: Webkit, version: 534.55.3 }, os: { name: 'OS X', alias: 'Mac OS X', version: '10.6' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
72
+ readable: 'Safari 5.1.5 on Mac OS X 10.6'
73
+ -
74
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/536.3+ (KHTML, like Gecko) Version/5.1.5 Safari/534.55.3'
75
+ result: { browser: { name: 'WebKit Nightly Build', type: browser }, engine: { name: Webkit, version: '536.3' }, os: { name: 'OS X', alias: 'Mac OS X', version: '10.6' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
76
+ readable: 'WebKit Nightly Build on Mac OS X 10.6'
77
+ -
78
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7) AppleWebKit/534.48.3 (KHTML, like Gecko) Version/5.1.7 Safari/534.57.7'
79
+ result: { browser: { name: Safari, version: 5.1.7, type: browser }, engine: { name: Webkit, version: 534.48.3 }, os: { name: 'OS X', version: { value: '10.7', nickname: Lion } }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
80
+ readable: 'Safari 5.1.7 on OS X Lion 10.7'
81
+ -
82
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_2) AppleWebKit/534.52.7 (KHTML, like Gecko) Version/5.1.1 Safari/534.51.22'
83
+ result: { browser: { name: Safari, version: 5.1.1, type: browser }, engine: { name: Webkit, version: 534.52.7 }, os: { name: 'OS X', version: { value: '10.7', nickname: Lion } }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
84
+ readable: 'Safari 5.1.1 on OS X Lion 10.7'
85
+ -
86
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/534.53.11 (KHTML, like Gecko) Version/5.1.3 Safari/534.53.10'
87
+ result: { browser: { name: Safari, version: 5.1.3, type: browser }, engine: { name: Webkit, version: 534.53.11 }, os: { name: 'OS X', version: { value: '10.7', nickname: Lion } }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
88
+ readable: 'Safari 5.1.3 on OS X Lion 10.7'
89
+ -
90
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/534.57.7 (KHTML, like Gecko) Version/5.0.3 Safari/533.19.4'
91
+ result: { browser: { name: Safari, version: 5.0.3, type: browser }, engine: { name: Webkit, version: 534.57.7 }, os: { name: 'OS X', version: { value: '10.7', nickname: Lion } }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
92
+ readable: 'Safari 5.0.3 on OS X Lion 10.7'
93
+ -
94
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/538.2+ (KHTML, like Gecko) Version/6.0.5 Safari/536.30.1'
95
+ result: { browser: { name: 'WebKit Nightly Build', type: browser }, engine: { name: Webkit, version: '538.2' }, os: { name: 'OS X', version: { value: '10.7', nickname: Lion } }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
96
+ readable: 'WebKit Nightly Build on OS X Lion 10.7'
97
+ -
98
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8) AppleWebKit/537.19+ (KHTML, like Gecko) Version/6.0 Safari/536.25'
99
+ result: { browser: { name: 'WebKit Nightly Build', type: browser }, engine: { name: Webkit, version: '537.19' }, os: { name: 'OS X', version: { value: '10.8', nickname: 'Mountain Lion' } }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
100
+ readable: 'WebKit Nightly Build on OS X Mountain Lion 10.8'
101
+ -
102
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8) AppleWebKit/537.19.1 (KHTML, like Gecko) Version/6.1 Safari/537.19.1'
103
+ result: { browser: { name: Safari, version: '6.1', type: browser }, engine: { name: Webkit, version: 537.19.1 }, os: { name: 'OS X', version: { value: '10.8', nickname: 'Mountain Lion' } }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
104
+ readable: 'Safari 6.1 on OS X Mountain Lion 10.8'
105
+ -
106
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/536.26.14 (KHTML, like Gecko) Version/5.1.7 Safari/534.57.2'
107
+ result: { browser: { name: Safari, version: 5.1.7, type: browser }, engine: { name: Webkit, version: 536.26.14 }, os: { name: 'OS X', version: { value: '10.8', nickname: 'Mountain Lion' } }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
108
+ readable: 'Safari 5.1.7 on OS X Mountain Lion 10.8'
109
+ -
110
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.47+ (KHTML, like Gecko) Version/6.0.2 Safari/536.26.17'
111
+ result: { browser: { name: 'WebKit Nightly Build', type: browser }, engine: { name: Webkit, version: '537.47' }, os: { name: 'OS X', version: { value: '10.8', nickname: 'Mountain Lion' } }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
112
+ readable: 'WebKit Nightly Build on OS X Mountain Lion 10.8'
113
+ -
114
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_3) AppleWebKit/536.28.6 (KHTML, like Gecko) Version/6.0.3 Safari/536.28.6'
115
+ result: { browser: { name: Safari, version: 6.0.3, type: browser }, engine: { name: Webkit, version: 536.28.6 }, os: { name: 'OS X', version: { value: '10.8', nickname: 'Mountain Lion' } }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
116
+ readable: 'Safari 6.0.3 on OS X Mountain Lion 10.8'
117
+ -
118
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9) AppleWebKit/537.26.4 (KHTML, like Gecko) Version/6.1 Safari/537.26.4'
119
+ result: { browser: { name: Safari, version: '6.1', type: browser }, engine: { name: Webkit, version: 537.26.4 }, os: { name: 'OS X', version: { value: '10.9', nickname: Mavericks } }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
120
+ readable: 'Safari 6.1 on OS X Mavericks 10.9'
121
+ -
122
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9) AppleWebKit/537.46.5 (KHTML, like Gecko) Version/7.0 Safari/537.46.5'
123
+ result: { browser: { name: Safari, version: '7.0', type: browser }, engine: { name: Webkit, version: 537.46.5 }, os: { name: 'OS X', version: { value: '10.9', nickname: Mavericks } }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
124
+ readable: 'Safari 7.0 on OS X Mavericks 10.9'
125
+ -
126
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_0) AppleWebKit/600.1.17 (KHTML, like Gecko) Version/7.1 Safari/537.85.10'
127
+ result: { browser: { name: Safari, version: '7.1', type: browser }, engine: { name: Webkit, version: 600.1.17 }, os: { name: 'OS X', version: { value: '10.9', nickname: Mavericks } }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
128
+ readable: 'Safari 7.1 on OS X Mavericks 10.9'
129
+ -
130
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/538.5+ (KHTML, like Gecko) Version/7.0.3 Safari/537.75.14'
131
+ result: { browser: { name: 'WebKit Nightly Build', type: browser }, engine: { name: Webkit, version: '538.5' }, os: { name: 'OS X', version: { value: '10.9', nickname: Mavericks } }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
132
+ readable: 'WebKit Nightly Build on OS X Mavericks 10.9'
133
+ -
134
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/600.1.17 (KHTML, like Gecko) Version/7.1 Safari/537.36'
135
+ result: { browser: { name: Safari, version: '7.1', type: browser }, engine: { name: Webkit, version: 600.1.17 }, os: { name: 'OS X', version: { value: '10.9', nickname: Mavericks } }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
136
+ readable: 'Safari 7.1 on OS X Mavericks 10.9'
137
+ -
138
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; PPC Mac OS X 10_5_8) AppleWebKit/535.1 (KHTML, like Gecko) Version/5.0.6 Safari/533.22.2'
139
+ result: { browser: { name: Safari, version: 5.0.6, type: browser }, engine: { name: Webkit, version: '535.1' }, os: { name: 'OS X', alias: 'Mac OS X', version: '10.5' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
140
+ readable: 'Safari 5.0.6 on Mac OS X 10.5'
141
+ -
142
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; PPC Mac OS X 10_7_3) AppleWebKit/534.55.3 (KHTML, like Gecko) Version/5.1.3 Safari/534.53.10'
143
+ result: { browser: { name: Safari, version: 5.1.3, type: browser }, engine: { name: Webkit, version: 534.55.3 }, os: { name: 'OS X', version: { value: '10.7', nickname: Lion } }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
144
+ readable: 'Safari 5.1.3 on OS X Lion 10.7'
145
+ -
146
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; PPC Mac OS X 10_7_3) AppleWebKit/600.55.3 (KHTML, like Gecko) Version/6.1.3 Safari/600.53.10'
147
+ result: { browser: { name: Safari, version: 6.1.3, type: browser }, engine: { name: Webkit, version: 600.55.3 }, os: { name: 'OS X', version: { value: '10.7', nickname: Lion } }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
148
+ readable: 'Safari 6.1.3 on OS X Lion 10.7'
149
+ -
150
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; PPC Mac OS X 10_7_5) AppleWebKit/536.29.13 (KHTML, like Gecko) Version/6.0.4 Safari/536.29.13'
151
+ result: { browser: { name: Safari, version: 6.0.4, type: browser }, engine: { name: Webkit, version: 536.29.13 }, os: { name: 'OS X', version: { value: '10.7', nickname: Lion } }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
152
+ readable: 'Safari 6.0.4 on OS X Lion 10.7'
153
+ -
154
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_4_11; xx) AppleWebKit/525.13 (KHTML, like Gecko) Version/3.1 Safari/525.13'
155
+ result: { browser: { name: Safari, version: '3.1', type: browser }, engine: { name: Webkit, version: '525.13' }, os: { name: 'OS X', alias: 'Mac OS X', version: '10.4' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
156
+ readable: 'Safari 3.1 on Mac OS X 10.4'
157
+ -
158
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_4_11; xx) AppleWebKit/525.18 (KHTML, like Gecko) Version/3.1.2 Safari/525.22'
159
+ result: { browser: { name: Safari, version: 3.1.2, type: browser }, engine: { name: Webkit, version: '525.18' }, os: { name: 'OS X', alias: 'Mac OS X', version: '10.4' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
160
+ readable: 'Safari 3.1.2 on Mac OS X 10.4'
161
+ -
162
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_4_11; xx) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Safari/530.17'
163
+ result: { browser: { name: Safari, version: '4.0', type: browser }, engine: { name: Webkit, version: '530.17' }, os: { name: 'OS X', alias: 'Mac OS X', version: '10.4' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
164
+ readable: 'Safari 4.0 on Mac OS X 10.4'
165
+ -
166
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_4_11; xx) AppleWebKit/533.16 (KHTML, like Gecko) Version/4.1 Safari/533.16'
167
+ result: { browser: { name: Safari, version: '4.1', type: browser }, engine: { name: Webkit, version: '533.16' }, os: { name: 'OS X', alias: 'Mac OS X', version: '10.4' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
168
+ readable: 'Safari 4.1 on Mac OS X 10.4'
169
+ -
170
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10_4_11; xx) AppleWebKit/525.18 (KHTML, like Gecko) Version/3.1.1 Safari/525.18'
171
+ result: { browser: { name: Safari, version: 3.1.1, type: browser }, engine: { name: Webkit, version: '525.18' }, os: { name: 'OS X', alias: 'Mac OS X', version: '10.4' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
172
+ readable: 'Safari 3.1.1 on Mac OS X 10.4'
173
+ -
174
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10_4_11; xx) AppleWebKit/525.18 (KHTML, like Gecko) Version/3.1.2 Safari/525.22'
175
+ result: { browser: { name: Safari, version: 3.1.2, type: browser }, engine: { name: Webkit, version: '525.18' }, os: { name: 'OS X', alias: 'Mac OS X', version: '10.4' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
176
+ readable: 'Safari 3.1.2 on Mac OS X 10.4'
177
+ -
178
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10_4_11; xx) AppleWebKit/525.27.1 (KHTML, like Gecko) Version/3.2.3 Safari/525.28.3'
179
+ result: { browser: { name: Safari, version: 3.2.3, type: browser }, engine: { name: Webkit, version: 525.27.1 }, os: { name: 'OS X', alias: 'Mac OS X', version: '10.4' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
180
+ readable: 'Safari 3.2.3 on Mac OS X 10.4'
181
+ -
182
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10_4_11; xx) AppleWebKit/533.21.1+ (KHTML, like Gecko) Version/4.1.3 Safari/533.21.1'
183
+ result: { browser: { name: 'WebKit Nightly Build', type: browser }, engine: { name: Webkit, version: 533.21.1 }, os: { name: 'OS X', alias: 'Mac OS X', version: '10.4' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
184
+ readable: 'WebKit Nightly Build on Mac OS X 10.4'
185
+ -
186
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10_5_8; xx) AppleWebKit/532.0+ (KHTML, like Gecko) Version/4.0.3 Safari/531.9'
187
+ result: { browser: { name: 'WebKit Nightly Build', type: browser }, engine: { name: Webkit, version: '532.0' }, os: { name: 'OS X', alias: 'Mac OS X', version: '10.5' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
188
+ readable: 'WebKit Nightly Build on Mac OS X 10.5'
189
+ -
190
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 6.1; WKC) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50'
191
+ result: { browser: { name: Safari, version: '5.1', type: browser }, engine: { name: Webkit, version: '534.50' }, os: { name: Windows, version: { value: '6.1', alias: '7' } }, device: { type: desktop } }
192
+ readable: 'Safari 5.1 on Windows 7'
193
+ -
194
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 6.1; WKC) AppleWebKit/534.52.7 (KHTML, like Gecko) Version/5.1.2 Safari/534.52.7'
195
+ result: { browser: { name: Safari, version: 5.1.2, type: browser }, engine: { name: Webkit, version: 534.52.7 }, os: { name: Windows, version: { value: '6.1', alias: '7' } }, device: { type: desktop } }
196
+ readable: 'Safari 5.1.2 on Windows 7'
197
+ -
198
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50'
199
+ result: { browser: { name: Safari, version: '5.1', type: browser }, engine: { name: Webkit, version: '534.50' }, os: { name: Windows, version: { value: '6.1', alias: '7' } }, device: { type: desktop } }
200
+ readable: 'Safari 5.1 on Windows 7'
201
+ -
202
+ headers: 'User-Agent: Safari/10600.2.5 CFNetwork/720.1.1 Darwin/14.0.0 (x86_64)'
203
+ result: { browser: { name: Safari, type: browser }, os: { name: 'OS X', version: { value: 10.10.1, nickname: Yosemite } }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
204
+ readable: 'Safari on OS X Yosemite 10.10.1'
205
+ -
206
+ headers: 'User-Agent: Safari/9537.73.11 CFNetwork/673.0.3 Darwin/13.0.0 (x86_64) (MacBookAir6%2C2)'
207
+ result: { browser: { name: Safari, type: browser }, os: { name: 'OS X', version: { value: '10.9', nickname: Mavericks } }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
208
+ readable: 'Safari on OS X Mavericks 10.9'
209
+ -
210
+ headers: 'User-Agent: com.apple.WebKit.WebContent/10600.1.25 CFNetwork/720.0.9 Darwin/14.0.0 (x86_64)'
211
+ result: { os: { name: 'OS X', version: { value: '10.10', nickname: Yosemite } }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
212
+ readable: 'OS X Yosemite 10.10'
213
+ -
214
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12) AppleWebKit/602.1.32 (KHTML, like Gecko) Version/10.0 Safari/602.1.32'
215
+ readable: 'Safari 10.0 on macOS Sierra 10.12'
216
+ result: { browser: { name: Safari, version: '10.0', type: browser }, engine: { name: Webkit, version: 602.1.32 }, os: { name: 'OS X', alias: macOS, version: { value: '10.12', nickname: Sierra } }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
217
+ -
218
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13) AppleWebKit/603.1.13 (KHTML, like Gecko) Version/10.1 Safari/603.1.13'
219
+ readable: 'Safari 10.1 on macOS High Sierra 10.13'
220
+ result: { browser: { name: Safari, version: '10.1', type: browser }, engine: { name: Webkit, version: 603.1.13 }, os: { name: 'OS X', alias: macOS, version: { value: '10.13', nickname: 'High Sierra' } }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
includes/vendor/whichbrowser/parser/tests/data/desktop/browser-seamonkey.yaml ADDED
@@ -0,0 +1,88 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ -
2
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:18.0) Gecko/20100101 Firefox/18.0 SeaMonkey/2.15.2'
3
+ result: { browser: { name: SeaMonkey, family: { name: Firefox, version: '18.0' }, version: 2.15.2, type: browser }, engine: { name: Gecko, version: '18.0' }, os: { name: 'OS X', alias: 'Mac OS X', version: '10.6' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
4
+ readable: 'SeaMonkey 2.15.2 on Mac OS X 10.6'
5
+ -
6
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:19.0) Gecko/19.0 SeaMonkey/2.16a1'
7
+ result: { browser: { name: SeaMonkey, version: 2.16a1, type: browser }, engine: { name: Gecko, version: '19.0' }, os: { name: 'OS X', alias: 'Mac OS X', version: '10.6' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
8
+ readable: 'SeaMonkey 2.16a1 on Mac OS X 10.6'
9
+ -
10
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:2.0.1) Gecko/20110608 Firefox/4.0.1 SeaMonkey/2.1'
11
+ result: { browser: { name: SeaMonkey, family: { name: Firefox, version: 4.0.1 }, version: '2.1', type: browser }, engine: { name: Gecko, version: 2.0.1 }, os: { name: 'OS X', alias: 'Mac OS X', version: '10.6' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
12
+ readable: 'SeaMonkey 2.1 on Mac OS X 10.6'
13
+ -
14
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; PPC Mac OS X 10.5; rv:16.0) Gecko/20121012 SeaMonkey/2.13'
15
+ result: { browser: { name: SeaMonkey, version: '2.13', type: browser }, engine: { name: Gecko, version: '16.0' }, os: { name: 'OS X', alias: 'Mac OS X', version: '10.5' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
16
+ readable: 'SeaMonkey 2.13 on Mac OS X 10.5'
17
+ -
18
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X; xx; rv:1.8.1.17) Gecko/20080829 SeaMonkey/1.1.12'
19
+ result: { browser: { name: SeaMonkey, version: 1.1.12, type: browser }, engine: { name: Gecko, version: 1.8.1 }, os: { name: 'OS X' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
20
+ readable: 'SeaMonkey 1.1.12 on OS X'
21
+ -
22
+ headers: 'User-Agent: Mozilla/5.0 (OS/2; U; Warp 4.5; de; rv:1.8.1.11) Gecko/20071129 PmWFx/2.0.0.11'
23
+ result: { browser: { name: SeaMonkey, version: 2.0.0.11, type: browser }, engine: { name: Gecko, version: 1.8.1 }, os: { name: OS/2, version: { value: '4.5', nickname: Warp } }, device: { type: desktop } }
24
+ readable: 'SeaMonkey 2.0.0.11 on OS/2 Warp 4.5'
25
+ -
26
+ headers: 'User-Agent: Mozilla/5.0 (OS/2; Warp 4.5; rv:10.0.12) Gecko/20130108 Firefox/10.0.12 SeaMonkey/2.7.2'
27
+ result: { browser: { name: SeaMonkey, family: { name: Firefox, version: 10.0.12 }, version: 2.7.2, type: browser }, engine: { name: Gecko, version: 10.0.12 }, os: { name: OS/2, version: { value: '4.5', nickname: Warp } }, device: { type: desktop } }
28
+ readable: 'SeaMonkey 2.7.2 on OS/2 Warp 4.5'
29
+ -
30
+ headers: 'User-Agent: Mozilla/5.0 (OS/2; Warp 4.5; rv:17.0) Gecko/20140621 Firefox/17.0 SeaMonkey/2.14'
31
+ result: { browser: { name: SeaMonkey, family: { name: Firefox, version: '17.0' }, version: '2.14', type: browser }, engine: { name: Gecko, version: '17.0' }, os: { name: OS/2, version: { value: '4.5', nickname: Warp } }, device: { type: desktop } }
32
+ readable: 'SeaMonkey 2.14 on OS/2 Warp 4.5'
33
+ -
34
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:12.0) Gecko/20120422 SeaMonkey/2.9'
35
+ result: { browser: { name: SeaMonkey, version: '2.9', type: browser }, engine: { name: Gecko, version: '12.0' }, os: { name: Windows, version: { value: '5.1', alias: XP } }, device: { type: desktop } }
36
+ readable: 'SeaMonkey 2.9 on Windows XP'
37
+ -
38
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:19.0) Gecko/20100101 Firefox/19.0 SeaMonkey/2.16'
39
+ result: { browser: { name: SeaMonkey, family: { name: Firefox, version: '19.0' }, version: '2.16', type: browser }, engine: { name: Gecko, version: '19.0' }, os: { name: Windows, version: { value: '5.1', alias: XP } }, device: { type: desktop } }
40
+ readable: 'SeaMonkey 2.16 on Windows XP'
41
+ -
42
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:20.0) Gecko/20.0 SeaMonkey/2.17a1'
43
+ result: { browser: { name: SeaMonkey, version: 2.17a1, type: browser }, engine: { name: Gecko, version: '20.0' }, os: { name: Windows, version: { value: '5.1', alias: XP } }, device: { type: desktop } }
44
+ readable: 'SeaMonkey 2.17a1 on Windows XP'
45
+ -
46
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:28.0) Gecko/20100101 SeaMonkey/2.25'
47
+ result: { browser: { name: SeaMonkey, version: '2.25', type: browser }, engine: { name: Gecko, version: '28.0' }, os: { name: Windows, version: { value: '5.1', alias: XP } }, device: { type: desktop } }
48
+ readable: 'SeaMonkey 2.25 on Windows XP'
49
+ -
50
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:10.0) Gecko/20120125 SeaMonkey/2.7'
51
+ result: { browser: { name: SeaMonkey, version: '2.7', type: browser }, engine: { name: Gecko, version: '10.0' }, os: { name: Windows, version: { value: '6.1', alias: '7' } }, device: { type: desktop } }
52
+ readable: 'SeaMonkey 2.7 on Windows 7'
53
+ -
54
+ headers: 'User-Agent: Mozilla/5.0 (X11; FreeBSD amd64; rv:26.0) Gecko/20100101 Firefox/26.0 SeaMonkey/2.23'
55
+ result: { browser: { name: SeaMonkey, family: { name: Firefox, version: '26.0' }, version: '2.23', type: browser }, engine: { name: Gecko, version: '26.0' }, os: { name: FreeBSD, family: BSD }, device: { type: desktop } }
56
+ readable: 'SeaMonkey 2.23 on FreeBSD'
57
+ -
58
+ headers: 'User-Agent: Mozilla/5.0 (X11; Linux i686; rv:17.0) Gecko/20100101 SeaMonkey/2.14.1'
59
+ result: { browser: { name: SeaMonkey, version: 2.14.1, type: browser }, engine: { name: Gecko, version: '17.0' }, os: { name: Linux }, device: { type: desktop } }
60
+ readable: 'SeaMonkey 2.14.1 on Linux'
61
+ -
62
+ headers: 'User-Agent: Mozilla/5.0 (X11; Linux i686; rv:19.0) Gecko/19.0 Firefox/19.0 SeaMonkey/2.16a1'
63
+ result: { browser: { name: SeaMonkey, family: { name: Firefox, version: '19.0' }, version: 2.16a1, type: browser }, engine: { name: Gecko, version: '19.0' }, os: { name: Linux }, device: { type: desktop } }
64
+ readable: 'SeaMonkey 2.16a1 on Linux'
65
+ -
66
+ headers: 'User-Agent: Mozilla/5.0 (X11; Linux i686; rv:7.0) Gecko/20110922 Firefox/7.0 SeaMonkey/2.4'
67
+ result: { browser: { name: SeaMonkey, family: { name: Firefox, version: '7.0' }, version: '2.4', type: browser }, engine: { name: Gecko, version: '7.0' }, os: { name: Linux }, device: { type: desktop } }
68
+ readable: 'SeaMonkey 2.4 on Linux'
69
+ -
70
+ headers: 'User-Agent: Mozilla/5.0 (X11; OpenBSD amd64; rv:33.0) Gecko/20100101 Firefox/33.0 SeaMonkey/2.30'
71
+ result: { browser: { name: SeaMonkey, family: { name: Firefox, version: '33.0' }, version: '2.30', type: browser }, engine: { name: Gecko, version: '33.0' }, os: { name: OpenBSD, family: BSD }, device: { type: desktop } }
72
+ readable: 'SeaMonkey 2.30 on OpenBSD'
73
+ -
74
+ headers: 'User-Agent: Mozilla/5.0 (X11; U; IRIX64 IP35; xx; rv:1.8.1.25pre) Gecko/20121113 SeaMonkey/1.1.20pre'
75
+ result: { browser: { name: SeaMonkey, version: 1.1.20, type: browser }, engine: { name: Gecko, version: 1.8.1 }, os: { name: IRIX, family: UNIX }, device: { type: desktop } }
76
+ readable: 'SeaMonkey 1.1.20 on IRIX'
77
+ -
78
+ headers: 'User-Agent: Mozilla/5.0 (X11; U; Linux i686; xx; rv:1.8.0.12) Gecko/20070531 CentOS/1.0.9-0.1.el3.centos3 SeaMonkey/1.0.9'
79
+ result: { browser: { name: SeaMonkey, version: 1.0.9, type: browser }, engine: { name: Gecko, version: 1.8.0 }, os: { name: CentOS, version: '3' }, device: { type: desktop } }
80
+ readable: 'SeaMonkey 1.0.9 on CentOS 3'
81
+ -
82
+ headers: 'User-Agent: Mozilla/5.0 (X11; U; Linux i686; xx; rv:1.8.1.21) Gecko/20090303 SeaMonkey/1.1.15 (Ubuntu-1.1.15+nobinonly-0ubuntu2)'
83
+ result: { browser: { name: SeaMonkey, version: 1.1.15, type: browser }, engine: { name: Gecko, version: 1.8.1 }, os: { name: Ubuntu }, device: { type: desktop } }
84
+ readable: 'SeaMonkey 1.1.15 on Ubuntu'
85
+ -
86
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; U; PPC; ja-JP; rv:1.8.1.2pre) Gecko/20070111 SeaMonkey/1.1'
87
+ result: { browser: { name: SeaMonkey, version: '1.1', type: browser }, engine: { name: Gecko, version: 1.8.1 }, os: { name: 'Mac OS' }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
88
+ readable: 'SeaMonkey 1.1 on Mac OS'
includes/vendor/whichbrowser/parser/tests/data/desktop/browser-text.yaml ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ -
2
+ headers: 'User-Agent: ELinks (0.11.3; Linux 2.6.23-gentoo-r5 i686; 209x77)'
3
+ result: { browser: { name: ELinks, version: 0.11.3, type: 'browser:text' }, os: { name: Linux }, device: { type: desktop } }
4
+ readable: 'ELinks 0.11.3 on Linux'
5
+ -
6
+ headers: 'User-Agent: Elinks (0.3.2; Linux 2.4.21 i686)'
7
+ result: { browser: { name: ELinks, version: 0.3.2, type: 'browser:text' }, os: { name: Linux }, device: { type: desktop } }
8
+ readable: 'ELinks 0.3.2 on Linux'
9
+ -
10
+ headers: 'User-Agent: Elinks (0.3; FreeBSD 4.3-RELEASE i386)'
11
+ result: { browser: { name: ELinks, version: '0.3', type: 'browser:text' }, os: { name: FreeBSD, family: BSD, version: '4.3' }, device: { type: desktop } }
12
+ readable: 'ELinks 0.3 on FreeBSD 4.3'
13
+ -
14
+ headers: 'User-Agent: ELinks (0.4.3rc2; Linux 2.4.22 i686; 110x40)'
15
+ result: { browser: { name: ELinks, version: 0.4.3, type: 'browser:text' }, os: { name: Linux }, device: { type: desktop } }
16
+ readable: 'ELinks 0.4.3 on Linux'
17
+ -
18
+ headers: 'User-Agent: ELinks/0.10.4-7-debian (textmode; Linux 2.6.14 i686; 110x48-2)'
19
+ result: { browser: { name: ELinks, version: 0.10.4, type: 'browser:text' }, os: { name: Linux }, device: { type: desktop } }
20
+ readable: 'ELinks 0.10.4 on Linux'
21
+ -
22
+ headers: 'User-Agent: ELinks/0.9.1 (textmode; Linux; 127x48)'
23
+ result: { browser: { name: ELinks, version: 0.9.1, type: 'browser:text' }, os: { name: Linux }, device: { type: desktop } }
24
+ readable: 'ELinks 0.9.1 on Linux'
25
+ -
26
+ headers: 'User-Agent: Emacs-w3m/1.3.3 w3m/0.3.1'
27
+ result: { browser: { name: w3m, version: 1.3.3, type: 'browser:text' } }
28
+ readable: 'w3m 1.3.3'
29
+ -
30
+ headers: 'User-Agent: Emacs-w3m/1.4.4 w3m/0.5.1'
31
+ result: { browser: { name: w3m, version: 1.4.4, type: 'browser:text' } }
32
+ readable: 'w3m 1.4.4'
33
+ -
34
+ headers: 'User-Agent: Emacs-w3m/1.4.77 w3m/0.5'
35
+ result: { browser: { name: w3m, version: 1.4.77, type: 'browser:text' } }
36
+ readable: 'w3m 1.4.77'
37
+ -
38
+ headers: 'User-Agent: CERN-LineMode/2.12'
39
+ result: { browser: { name: 'CERN LineMode', version: '2.12', type: 'browser:text' } }
40
+ readable: 'CERN LineMode 2.12'
41
+ -
42
+ headers: 'User-Agent: CERN-LineMode/2.14'
43
+ result: { browser: { name: 'CERN LineMode', version: '2.14', type: 'browser:text' } }
44
+ readable: 'CERN LineMode 2.14'
45
+ -
46
+ headers: 'User-Agent: CERN-LineMode/3.0'
47
+ result: { browser: { name: 'CERN LineMode', version: '3.0', type: 'browser:text' } }
48
+ readable: 'CERN LineMode 3.0'
includes/vendor/whichbrowser/parser/tests/data/desktop/browser-uc.yaml ADDED
@@ -0,0 +1,101 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ -
2
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.157 Safari/537.36'
3
+ useragent: 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.157 UBrowser/5.5.9936.1231 Safari/537.36'
4
+ result: { browser: { name: 'UC Browser', version: '5.5', type: browser }, engine: { name: Blink }, os: { name: Windows, version: { value: '10.0', alias: '10' } }, device: { type: desktop } }
5
+ readable: 'UC Browser 5.5 on Windows 10'
6
+ -
7
+ headers: 'User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; Sicent; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; UBrowser/3.0.1806.0)'
8
+ result: { browser: { name: 'UC Browser', version: '3.0', type: browser }, engine: { name: Trident, version: '4.0' }, os: { name: Windows, version: { value: '5.1', alias: XP } }, device: { type: desktop } }
9
+ readable: 'UC Browser 3.0 on Windows XP'
10
+ -
11
+ headers: 'User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET4.0C; .NET4.0E; InfoPath.3 UBrowser/1.0.226.1028)'
12
+ result: { browser: { name: 'UC Browser', version: '1.0', type: browser }, engine: { name: Trident, version: '4.0' }, os: { name: Windows, version: { value: '6.1', alias: '7' } }, device: { type: desktop } }
13
+ readable: 'UC Browser 1.0 on Windows 7'
14
+ -
15
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 6.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 UBrowser/2.0.1144.0 Safari/537.36'
16
+ result: { browser: { name: 'UC Browser', family: { name: Chrome, version: 35 }, version: '2.0', type: browser }, engine: { name: Blink }, os: { name: Windows, version: { value: '6.0', alias: Vista } }, device: { type: desktop } }
17
+ readable: 'UC Browser 2.0 on Windows Vista'
18
+ -
19
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 6.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.155 UBrowser/5.4.4237.1032 Safari/537.36'
20
+ result: { browser: { name: 'UC Browser', family: { name: Chrome, version: 44 }, version: '5.4', type: browser }, engine: { name: Blink }, os: { name: Windows, version: { value: '6.0', alias: Vista } }, device: { type: desktop } }
21
+ readable: 'UC Browser 5.4 on Windows Vista'
22
+ -
23
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 6.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.157 UBrowser/5.5.7045.1004 Safari/537.36'
24
+ result: { browser: { name: 'UC Browser', family: { name: Chrome, version: 44 }, version: '5.5', type: browser }, engine: { name: Blink }, os: { name: Windows, version: { value: '6.0', alias: Vista } }, device: { type: desktop } }
25
+ readable: 'UC Browser 5.5 on Windows Vista'
26
+ -
27
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 6.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.122 UBrowser/4.0.4627.3 Safari/537.36'
28
+ result: { browser: { name: 'UC Browser', family: { name: Chrome, version: 38 }, version: '4.0', type: browser }, engine: { name: Blink }, os: { name: Windows, version: { value: '6.0', alias: Vista } }, device: { type: desktop } }
29
+ readable: 'UC Browser 4.0 on Windows Vista'
30
+ -
31
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 UBrowser/5.0.389.22 Safari/537.36'
32
+ result: { browser: { name: 'UC Browser', family: { name: Chrome, version: 41 }, version: '5.0', type: browser }, engine: { name: Blink }, os: { name: Windows, version: { value: '6.1', alias: '7' } }, device: { type: desktop } }
33
+ readable: 'UC Browser 5.0 on Windows 7'
34
+ -
35
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 6.1; Trident/7.0; rv:11.0 UBrowser/1.0.342.1224) like Gecko'
36
+ result: { browser: { name: 'UC Browser', version: '1.0', type: browser }, engine: { name: Trident, version: '7.0' }, os: { name: Windows, version: { value: '6.1', alias: '7' } }, device: { type: desktop } }
37
+ readable: 'UC Browser 1.0 on Windows 7'
38
+ -
39
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 6.1; Trident/7.0; rv:11.0; UBrowser/2.0.754.0) like Gecko'
40
+ result: { browser: { name: 'UC Browser', version: '2.0', type: browser }, engine: { name: Trident, version: '7.0' }, os: { name: Windows, version: { value: '6.1', alias: '7' } }, device: { type: desktop } }
41
+ readable: 'UC Browser 2.0 on Windows 7'
42
+ -
43
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 6.1; Trident/7.0; rv:11.0; UBrowser/3.0.947.1) like Gecko'
44
+ result: { browser: { name: 'UC Browser', version: '3.0', type: browser }, engine: { name: Trident, version: '7.0' }, os: { name: Windows, version: { value: '6.1', alias: '7' } }, device: { type: desktop } }
45
+ readable: 'UC Browser 3.0 on Windows 7'
46
+ -
47
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 6.1; Trident/7.0; rv:11.0; UBrowser/5.1.2238.18) like Gecko'
48
+ result: { browser: { name: 'UC Browser', version: '5.1', type: browser }, engine: { name: Trident, version: '7.0' }, os: { name: Windows, version: { value: '6.1', alias: '7' } }, device: { type: desktop } }
49
+ readable: 'UC Browser 5.1 on Windows 7'
50
+ -
51
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.107 UBrowser/1.0.898.0 Safari/537.36'
52
+ result: { browser: { name: 'UC Browser', family: { name: Chrome, version: 32 }, version: '1.0', type: browser }, engine: { name: Blink }, os: { name: Windows, version: { value: '6.1', alias: '7' } }, device: { type: desktop } }
53
+ readable: 'UC Browser 1.0 on Windows 7'
54
+ -
55
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.30 UBrowser/5.2.3129.0 Safari/537.36'
56
+ result: { browser: { name: 'UC Browser', family: { name: Chrome, version: 44 }, version: '5.2', type: browser }, engine: { name: Blink }, os: { name: Windows, version: { value: '6.1', alias: '7' } }, device: { type: desktop } }
57
+ readable: 'UC Browser 5.2 on Windows 7'
58
+ -
59
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 UBrowser/3.1.1644.34 Safari/537.36'
60
+ result: { browser: { name: 'UC Browser', family: { name: Chrome, version: 35 }, version: '3.1', type: browser }, engine: { name: Blink }, os: { name: Windows, version: { value: '6.2', alias: '8' } }, device: { type: desktop } }
61
+ readable: 'UC Browser 3.1 on Windows 8'
62
+ -
63
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 6.3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.122 UBrowser/4.1.4627.19 Safari/537.36'
64
+ result: { browser: { name: 'UC Browser', family: { name: Chrome, version: 38 }, version: '4.1', type: browser }, engine: { name: Blink }, os: { name: Windows, version: { value: '6.3', alias: '8.1' } }, device: { type: desktop } }
65
+ readable: 'UC Browser 4.1 on Windows 8.1'
66
+ -
67
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0; UBrowser/5.0.966.1045) like Gecko'
68
+ result: { browser: { name: 'UC Browser', version: '5.0', type: browser }, engine: { name: Trident, version: '7.0' }, os: { name: Windows, version: { value: '6.3', alias: '8.1' } }, device: { type: desktop } }
69
+ readable: 'UC Browser 5.0 on Windows 8.1'
70
+ -
71
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0; UBrowser/5.4.4799.303) like Gecko'
72
+ result: { browser: { name: 'UC Browser', version: '5.4', type: browser }, engine: { name: Trident, version: '7.0' }, os: { name: Windows, version: { value: '6.3', alias: '8.1' } }, device: { type: desktop } }
73
+ readable: 'UC Browser 5.4 on Windows 8.1'
74
+ -
75
+ headers: 'User-Agent: Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0; UBrowser/3.2.2937.4)'
76
+ result: { browser: { name: 'UC Browser', version: '3.2', type: browser }, engine: { name: Trident, version: '6.0' }, os: { name: Windows, version: { value: '6.2', alias: '8' } }, device: { type: desktop } }
77
+ readable: 'UC Browser 3.2 on Windows 8'
78
+ -
79
+ headers: 'User-Agent: Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.3; WOW64; Trident/8.0; UBrowser/5.0.389.27)'
80
+ result: { browser: { name: 'UC Browser', version: '5.0', type: browser }, engine: { name: Trident, version: '8.0' }, os: { name: Windows, version: { value: '6.3', alias: '8.1' } }, device: { type: desktop } }
81
+ readable: 'UC Browser 5.0 on Windows 8.1'
82
+ -
83
+ headers: 'User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0 UBrowser/1.0.370.1388)'
84
+ result: { browser: { name: 'UC Browser', version: '1.0', type: browser }, engine: { name: Trident, version: '5.0' }, os: { name: Windows, version: { value: '6.1', alias: '7' } }, device: { type: desktop } }
85
+ readable: 'UC Browser 1.0 on Windows 7'
86
+ -
87
+ headers: 'User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0) UBrowser/1.0.44.100'
88
+ result: { browser: { name: 'UC Browser', version: '1.0', type: browser }, engine: { name: Trident, version: '5.0' }, os: { name: Windows, version: { value: '6.1', alias: '7' } }, device: { type: desktop } }
89
+ readable: 'UC Browser 1.0 on Windows 7'
90
+ -
91
+ headers: 'User-Agent: UCWEB/8.8 (iPhone; CPU OS_6; en-US)AppleWebKit/534.1 U3/3.0.0 Mobile'
92
+ result: { browser: { name: 'UC Browser', version: '8.8', type: browser }, engine: { name: Webkit, version: '534.1' }, os: { name: iOS, version: '6' }, device: { type: mobile, subtype: smart, manufacturer: Apple, model: iPhone } }
93
+ readable: 'UC Browser 8.8 on an Apple iPhone running iOS 6'
94
+ -
95
+ headers: 'User-Agent: UCWEB/2.0 (Linux; U; Adr 2.2.2; zh-CN; HTC HD7 LTE 4G+ For AT&T) U2/1.0.0 UCBrowser/9.5.1.381 U2/1.0.0 Mobile'
96
+ result: { browser: { name: 'UC Browser', version: '9.5', type: browser }, engine: { name: Gecko }, os: { name: Android, version: 2.2.2 }, device: { type: mobile, subtype: smart, manufacturer: HTC, model: HD7 } }
97
+ readable: 'UC Browser 9.5 on a HTC HD7 running Android 2.2.2'
98
+ -
99
+ headers: 'User-Agent: UCWEB/2.0 (Linux; U; Adr 2.1-update1; xx; E15a) U2/1.0.0 UCBrowser/9.3.1.344 U2/1.0.0 Mobile'
100
+ result: { browser: { name: 'UC Browser', version: '9.3', type: browser }, engine: { name: Gecko }, os: { name: Android, version: '2.1' }, device: { type: mobile, subtype: smart, manufacturer: 'Sony Ericsson', model: 'Xperia X8' } }
101
+ readable: 'UC Browser 9.3 on a Sony Ericsson Xperia X8 running Android 2.1'
includes/vendor/whichbrowser/parser/tests/data/desktop/engine-goanna.yaml ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ -
2
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:38.9) Gecko/20100101 Goanna/2.0 Firefox/38.9 PaleMoon/26.0.0b4'
3
+ result: { browser: { name: 'Pale Moon', family: { name: Firefox, version: '38.9' }, version: 26.0.0, type: browser }, engine: { name: Goanna, version: '2.0' }, os: { name: Windows, version: { value: '6.1', alias: '7' } }, device: { type: desktop } }
4
+ readable: 'Pale Moon 26.0.0 on Windows 7'
5
+ -
6
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:2.0) Gecko/20100101 Goanna/20151214 PaleMoon/26.0.0b4'
7
+ result: { browser: { name: 'Pale Moon', version: 26.0.0, type: browser }, engine: { name: Goanna, version: '2.0' }, os: { name: Windows, version: { value: '6.1', alias: '7' } }, device: { type: desktop } }
8
+ readable: 'Pale Moon 26.0.0 on Windows 7'
9
+ -
10
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:1.0) Goanna/20150828 Gecko/20100101 PaleMoon/26.0.0b2'
11
+ result: { browser: { name: 'Pale Moon', version: 26.0.0, type: browser }, engine: { name: Goanna, version: '1.0' }, os: { name: Windows, version: { value: '6.3', alias: '8.1' } }, device: { type: desktop } }
12
+ readable: 'Pale Moon 26.0.0 on Windows 8.1'
13
+ -
14
+ headers: 'User-Agent: Mozilla/5.0 (X11; Linux i686; rv:1.0) Goanna/20150819 Gecko/20100101 Firefox/31.9 PaleMoon/26.0.0b1'
15
+ result: { browser: { name: 'Pale Moon', family: { name: Firefox, version: '31.9' }, version: 26.0.0, type: browser }, engine: { name: Goanna, version: '1.0' }, os: { name: Linux }, device: { type: desktop } }
16
+ readable: 'Pale Moon 26.0.0 on Linux'
17
+ -
18
+ headers: 'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:1.0) Goanna/20150804 Firefox/31.9 PaleMoon/26.0.0b1'
19
+ result: { browser: { name: 'Pale Moon', family: { name: Firefox, version: '31.9' }, version: 26.0.0, type: browser }, engine: { name: Goanna, version: '1.0' }, os: { name: Linux }, device: { type: desktop } }
20
+ readable: 'Pale Moon 26.0.0 on Linux'
21
+ -
22
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:38.9) Gecko/20100101 Goanna/2.0 Firefox/38.9 PaleMoon/26.0.0'
23
+ result: { browser: { name: 'Pale Moon', family: { name: Firefox, version: '38.9' }, version: 26.0.0, type: browser }, engine: { name: Goanna, version: '2.0' }, os: { name: Windows, version: { value: '6.1', alias: '7' } }, device: { type: desktop } }
24
+ readable: 'Pale Moon 26.0.0 on Windows 7'
25
+ -
26
+ headers: 'User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64; rv:2.0) Goanna/20160105 PaleMoon/26.0.0'
27
+ result: { browser: { name: 'Pale Moon', version: 26.0.0, type: browser }, engine: { name: Goanna, version: '2.0' }, os: { name: Windows, version: { value: '6.3', alias: '8.1' } }, device: { type: desktop } }
28
+ readable: 'Pale Moon 26.0.0 on Windows 8.1'
includes/vendor/whichbrowser/parser/tests/data/desktop/engine-servo.yaml ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ -
2
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:37.0) Servo/1.0 Firefox/37.0'
3
+ result: { browser: { name: 'Servo Nightly Build', type: browser }, engine: { name: Servo, version: '1.0' }, os: { name: 'OS X', version: { value: '10.10', nickname: Yosemite } }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
4
+ readable: 'Servo Nightly Build on OS X Yosemite 10.10'
5
+ -
6
+ headers: 'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:37.0) Servo/1.0 Firefox/37.0'
7
+ readable: 'Servo Nightly Build on Linux'
8
+ result: { browser: { name: 'Servo Nightly Build', type: browser }, engine: { name: Servo, version: '1.0' }, os: { name: Linux }, device: { type: desktop } }
9
+ -
10
+ headers: 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:55.0) Servo/1.0 Firefox/55.0'
11
+ readable: 'Servo Nightly Build on OS X Yosemite 10.10'
12
+ result: { browser: { name: 'Servo Nightly Build', type: browser }, engine: { name: Servo, version: '1.0' }, os: { name: 'OS X', version: { value: '10.10', nickname: Yosemite } }, device: { type: desktop, manufacturer: Apple, model: Macintosh } }
includes/vendor/whichbrowser/parser/tests/data/desktop/os-amigaos.yaml ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ -
2
+ headers: 'User-Agent: IBrowse/2.4 (AmigaOS 3.9; 68K)'
3
+ result: { browser: { name: IBrowse, version: '2.4', type: browser }, os: { name: AmigaOS, version: '3.9' }, device: { type: desktop } }
4
+ readable: 'IBrowse 2.4 on AmigaOS 3.9'
5
+ -
6
+ headers: 'User-Agent: IBrowse/2.4 (AmigaOS V53; PPC; 68K build)'
7
+ result: { browser: { name: IBrowse, version: '2.4', type: browser }, os: { name: AmigaOS }, device: { type: desktop } }
8
+ readable: 'IBrowse 2.4 on AmigaOS'
9
+ -
10
+ headers: 'User-Agent: IBrowse/2.4oem (AmigaOS V53; PPC; 68K build)'
11
+ result: { browser: { name: IBrowse, version: '2.4', type: browser }, os: { name: AmigaOS }, device: { type: desktop } }
12
+ readable: 'IBrowse 2.4 on AmigaOS'
13
+ -
14
+ headers: 'User-Agent: IBrowse/2.5beta (AmigaOS 4.1; PPC)'
15
+ result: { browser: { name: IBrowse, version: '2.5', type: browser }, os: { name: AmigaOS, version: '4.1' }, device: { type: desktop } }
16
+ readable: 'IBrowse 2.5 on AmigaOS 4.1'
17
+ -
18
+ headers: 'User-Agent: Mozilla/5.0 (Am