Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
93.68% covered (success)
93.68%
178 / 190
60.00% covered (warning)
60.00%
9 / 15
CRAP
0.00% covered (danger)
0.00%
0 / 1
Password_Checker
93.68% covered (success)
93.68%
178 / 190
60.00% covered (warning)
60.00%
9 / 15
58.85
0.00% covered (danger)
0.00%
0 / 1
 __construct
63.64% covered (warning)
63.64%
7 / 11
0.00% covered (danger)
0.00%
0 / 1
6.20
 test
100.00% covered (success)
100.00%
19 / 19
100.00% covered (success)
100.00%
1 / 1
4
 run_tests
100.00% covered (success)
100.00%
18 / 18
100.00% covered (success)
100.00%
1 / 1
7
 get_tests
100.00% covered (success)
100.00%
50 / 50
100.00% covered (success)
100.00%
1 / 1
2
 test_preg_match
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 test_compare_to_list
90.91% covered (success)
90.91%
10 / 11
0.00% covered (danger)
0.00%
0 / 1
3.01
 get_common_passwords
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 get_other_user_data
90.91% covered (success)
90.91%
20 / 22
0.00% covered (danger)
0.00%
0 / 1
9.06
 test_not_same_as_other_user_data
91.67% covered (success)
91.67%
11 / 12
0.00% covered (danger)
0.00%
0 / 1
7.03
 negative_in_array
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 add_user_strings_to_test
86.67% covered (warning)
86.67%
13 / 15
0.00% covered (danger)
0.00%
0 / 1
5.06
 get_user_strings_to_test
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 get_charset_size
85.71% covered (warning)
85.71%
12 / 14
0.00% covered (danger)
0.00%
0 / 1
7.14
 get_char_index
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
3
 calculate_entropy_bits
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2/**
3 * Password Checker package.
4 *
5 * @package  automattic/jetpack-password-checker
6 */
7
8namespace Automattic\Jetpack;
9
10/**
11 * Checks passwords strength.
12 */
13class Password_Checker {
14    /**
15     * Minimum entropy bits a password should contain. 36 bits of entropy is considered
16     * to be a reasonable password, 28 stands for a weak one.
17     *
18     * @var int
19     */
20    public $minimum_entropy_bits = 28;
21
22    /**
23     * Test results array.
24     *
25     * @var array
26     */
27    public $test_results = array();
28
29    /**
30     * Current password score.
31     *
32     * @var int
33     */
34    public $score = 0;
35
36    /**
37     * Current multiplier affecting the score.
38     *
39     * @var int
40     */
41    public $multiplier = 4;
42
43    /**
44     * A common password disallow list, which on match will immediately disqualify the password.
45     *
46     * @var array
47     */
48    public $common_passwords = array();
49
50    /**
51     * Minimum password length setting.
52     *
53     * @var int
54     */
55    public $minimum_password_length = 6;
56
57    /**
58     * User defined strings that passwords need to be tested for a match against.
59     *
60     * @var array
61     */
62    private $user_strings_to_test = array();
63
64    /**
65     * The user object for whom the password is being tested.
66     *
67     * @var mixed
68     */
69    protected $user = null;
70
71    /**
72     * The user identifier for whom the password is being tested, used if there's no user object.
73     *
74     * @var mixed
75     */
76    protected $user_id = null;
77
78    /**
79     * Creates an instance of the password checker class for the specified user, or
80     * defaults to the currently logged in user.
81     *
82     * @param mixed $user can be an integer ID, or a WP_User object.
83     */
84    public function __construct( $user = null ) {
85        if ( $user === null ) {
86            $this->user_id = get_current_user_id();
87        } elseif ( is_object( $user ) && isset( $user->ID ) ) {
88            // Existing user, using their ID.
89            $this->user_id = $user->ID;
90        } elseif ( is_object( $user ) ) {
91            // Newly created user, using existing data.
92            $this->user    = $user;
93            $this->user_id = 'new_user';
94        } else {
95            $this->user_id = $user;
96        }
97
98        /**
99         * Filters the password strength enforcement settings.
100         *
101         * You can supply your own passwords that should not be used for authenticating in addition to weak and easy
102         * to guess strings for each user. For example, you can add passwords from known password databases to avoid
103         * compromised password usage.
104         *
105         * @param array $common_passwords strings that are forbidden for use as passwords.
106         */
107        $this->common_passwords = apply_filters( 'password_checker_common_passwords', $this->common_passwords );
108
109        /**
110         * Filters the password strength enforcement settings.
111         *
112         * You can modify the minimum password length using this filter.
113         *
114         * @param int $minimum_password_length minimum password length.
115         */
116        $this->minimum_password_length = apply_filters( 'password_checker_minimum_password_length', $this->minimum_password_length );
117
118        /**
119         * Filters the password strength enforcement settings.
120         *
121         * You can modify the minimum entropy bits requirement using this filter.
122         *
123         * @param int $minimum_entropy_bits minimum entropy bits requirement.
124         */
125        $this->minimum_entropy_bits = apply_filters( 'password_checker_minimum_entropy_bits', $this->minimum_entropy_bits );
126    }
127
128    /**
129     * Run tests against a password.
130     *
131     * @param string $password      the password.
132     * @param bool   $required_only only test against required conditions, defaults to false.
133     *
134     * @return array an array containing failed and passed test results.
135     */
136    public function test( $password, $required_only = false ) {
137        // Run the tests.
138        $results = $this->run_tests( $password, $this->get_tests(), $required_only );
139
140        // If we've failed on the required tests, return now.
141        if ( ! empty( $results['failed'] ) ) {
142            return array(
143                'passed'       => false,
144                'test_results' => $results,
145            );
146        }
147
148        $entropy_bits = $this->calculate_entropy_bits( $password );
149
150        if ( $entropy_bits < $this->minimum_entropy_bits ) {
151            $results['failed'][] = array(
152                'test_name'   => 'entropy_bits',
153                'explanation' => __( 'This password is too easy to guess: you can improve it by making it longer.', 'jetpack-password-checker' ),
154            );
155
156            // Suggest improvements from the regex rules the first pass skipped; without $required_only they already ran.
157            if ( $required_only ) {
158                $suggestions       = $this->run_tests( $password, $this->get_tests( 'preg_match' ) );
159                $results['failed'] = array_merge( $results['failed'], $suggestions['failed'] );
160            }
161        }
162
163        return ( array(
164            'passed'       => empty( $results['failed'] ),
165            'test_results' => $results,
166        ) );
167    }
168
169    /**
170     * Run the tests using the currently set up object values.
171     *
172     * @param string $password      the password.
173     * @param array  $tests         tests to run.
174     * @param bool   $required_only whether to run only required tests.
175     *
176     * @return array test results.
177     */
178    public function run_tests( $password, $tests, $required_only = false ) {
179        $results = array(
180            'passed' => array(),
181            'failed' => array(),
182        );
183
184        foreach ( $tests as $test_type => $section_tests ) {
185            foreach ( $section_tests as $test_name => $test_data ) {
186                // Skip non-required tests if required_only param is set.
187                if ( $required_only && ! $test_data['required'] ) {
188                    continue;
189                }
190
191                $result = call_user_func_array( array( $this, 'test_' . $test_type ), array( $password, $test_data ) );
192                if ( $result ) {
193                    $results['passed'][] = array( 'test_name' => $test_name );
194                } else {
195                    $results['failed'][] = array(
196                        'test_name'   => $test_name,
197                        'explanation' => $test_data['error'],
198                    );
199
200                    if ( isset( $test_data['fail_immediately'] ) ) {
201                        return $results;
202                    }
203                }
204            }
205        }
206
207        return $results;
208    }
209
210    /**
211     * Returns an array of tests that need to be run on password strings.
212     *
213     * @param array $sections only return specific sections with the passed keys, defaults to all.
214     *
215     * @return array test descriptions.
216     */
217    public function get_tests( $sections = false ) {
218        // Note: these should be in order of priority.
219        $tests = array(
220            'preg_match'      => array(
221                'no_backslashes'   => array(
222                    'pattern'          => '/^[^\\\\]*$/u',
223                    'error'            => __( 'Passwords may not contain the character "\".', 'jetpack-password-checker' ),
224                    'required'         => true,
225                    'fail_immediately' => true,
226                ),
227                'minimum_length'   => array(
228                    'pattern'          => '/^.{' . $this->minimum_password_length . ',}/u',
229                    /* translators: %d is a number of characters in the password. */
230                    'error'            => sprintf( __( 'Password must be at least %d characters.', 'jetpack-password-checker' ), $this->minimum_password_length ),
231                    'required'         => true,
232                    'fail_immediately' => true,
233                ),
234                'has_mixed_case'   => array(
235                    'pattern'  => '/([a-z].*?[A-Z]|[A-Z].*?[a-z])/u',
236                    'error'    => __( 'This password is too easy to guess: you can improve it by adding additional uppercase letters, lowercase letters, or numbers.', 'jetpack-password-checker' ),
237                    'required' => false,
238                ),
239                'has_digit'        => array(
240                    'pattern'  => '/\d/u',
241                    'error'    => __( 'This password is too easy to guess: you can improve it by mixing both letters and numbers.', 'jetpack-password-checker' ),
242                    'required' => false,
243                ),
244                'has_special_char' => array(
245                    'pattern'  => '/[^a-zA-Z\d]/u',
246                    'error'    => __( 'This password is too easy to guess: you can improve it by including special characters such as !#=?*&.', 'jetpack-password-checker' ),
247                    'required' => false,
248                ),
249            ),
250            'compare_to_list' => array(
251                'not_a_common_password'       => array(
252                    'list_callback'    => 'get_common_passwords',
253                    'compare_callback' => 'negative_in_array',
254                    'error'            => __( 'This is a very common password. Choose something that will be harder for others to guess.', 'jetpack-password-checker' ),
255                    'required'         => true,
256                ),
257                'not_same_as_other_user_data' => array(
258                    'list_callback'    => 'get_other_user_data',
259                    'compare_callback' => 'test_not_same_as_other_user_data',
260                    'error'            => __( 'Your password is too weak: Looks like you are including easy to guess information about yourself. Try something a little more unique.', 'jetpack-password-checker' ),
261                    'required'         => true,
262                ),
263            ),
264        );
265
266        /**
267         * Filters the password strength enforcement settings.
268         *
269         * You can determine the tests run and their order based on whatever criteria you wish to specify.
270         *
271         * @param array $tests tests to run.
272         */
273        $tests = apply_filters( 'password_checker_tests', $tests );
274
275        if ( ! $sections ) {
276            return $tests;
277        }
278
279        $sections = (array) $sections;
280
281        return array_intersect_key( $tests, array_flip( $sections ) );
282    }
283
284    /**
285     * Provides the regular expression tester functionality.
286     *
287     * @param string $password  the password.
288     * @param array  $test_data the current test data.
289     *
290     * @return bool does the test pass?
291     */
292    protected function test_preg_match( $password, $test_data ) {
293        return preg_match( $test_data['pattern'], $password );
294    }
295
296    /**
297     * Provides the comparison tester functionality.
298     *
299     * @param string $password  the password.
300     * @param array  $test_data the current test data.
301     *
302     * @return bool does the test pass?
303     */
304    protected function test_compare_to_list( $password, $test_data ) {
305        if (
306            ! is_callable( array( $this, $test_data['list_callback'] ) )
307            || ! is_callable( array( $this, $test_data['compare_callback'] ) )
308        ) {
309            return false;
310        }
311
312        return call_user_func(
313            array(
314                $this,
315                $test_data['compare_callback'],
316            ),
317            $password,
318            call_user_func( array( $this, $test_data['list_callback'] ) )
319        );
320    }
321
322    /**
323     * Getter for the common password list.
324     *
325     * @return array common passwords.
326     */
327    protected function get_common_passwords() {
328        return $this->common_passwords;
329    }
330
331    /**
332     * Returns the widely known user data that cannot be used in the password to avoid
333     * predictable strings.
334     *
335     * @return array user data.
336     */
337    protected function get_other_user_data() {
338        if ( empty( $this->user_id ) ) {
339            return array();
340        }
341
342        $user_data = get_userdata( $this->user_id );
343        if ( ! $user_data ) {
344            return array();
345        }
346
347        if ( isset( $user_data->ID ) ) {
348            $this->add_user_strings_to_test( get_user_meta( $user_data->ID, 'first_name', true ) );
349            $this->add_user_strings_to_test( get_user_meta( $user_data->ID, 'last_name', true ) );
350            $this->add_user_strings_to_test( get_user_meta( $user_data->ID, 'nickname', true ) );
351        }
352
353        if ( isset( $user_data->user_nicename ) ) {
354            $this->add_user_strings_to_test( $user_data->user_nicename );
355        }
356
357        if ( isset( $user_data->display_name ) ) {
358            $this->add_user_strings_to_test( $user_data->display_name );
359        }
360
361        if ( isset( $user_data->first_name ) ) {
362            $this->add_user_strings_to_test( $user_data->first_name );
363        }
364
365        if ( isset( $user_data->last_name ) ) {
366            $this->add_user_strings_to_test( $user_data->last_name );
367        }
368
369        if ( isset( $user_data->user_email ) ) {
370            $email_username = substr( $user_data->user_email, 0, strpos( $user_data->user_email, '@' ) );
371            $this->add_user_strings_to_test( $email_username, '.' );
372            $this->add_user_strings_to_test( $user_data->user_email );
373        }
374
375        return $this->get_user_strings_to_test();
376    }
377
378    /**
379     * Compare the password for matches with known user data.
380     *
381     * @param string $password        the password.
382     * @param array  $strings_to_test known user data.
383     *
384     * @return bool does the test pass?
385     */
386    protected function test_not_same_as_other_user_data( $password, $strings_to_test ) {
387        if ( empty( $strings_to_test ) ) {
388            return false;
389        }
390
391        $password_lowercase = strtolower( $password );
392
393        foreach ( $strings_to_test as $string ) {
394            $string          = strtolower( $string );
395            $string_reversed = strrev( $string );
396
397            if ( $password_lowercase === $string || $password_lowercase === $string_reversed ) {
398                return false;
399            }
400
401            // Also check for the string or reversed string with any numbers just stuck to the end to catch things like bob123 as passwords.
402            if (
403                preg_match( '/^' . preg_quote( $string, '/' ) . '\d+$/', $password_lowercase )
404                || preg_match( '/^' . preg_quote( $string_reversed, '/' ) . '\d+$/', $password_lowercase )
405            ) {
406                return false;
407            }
408        }
409
410        return true;
411    }
412
413    /**
414     * A shorthand for the not in array construct.
415     *
416     * @param mixed $needle   the needle.
417     * @param array $haystack the haystack.
418     *
419     * @return bool is the needle not in the haystack?
420     */
421    protected function negative_in_array( $needle, $haystack ) {
422        return ! in_array( $needle, $haystack, true );
423    }
424
425    /**
426     * A helper function used to break a single string into its constituents so
427     * that both the full string and its constituents and any variants thereof
428     * can be tested against the password.
429     *
430     * @param string $string            the string to be broken down.
431     * @param string $explode_delimiter delimiter.
432     *
433     * @return bool
434     */
435    protected function add_user_strings_to_test( $string, $explode_delimiter = ' ' ) {
436        // Don't check against empty strings.
437        if ( empty( $string ) ) {
438            return false;
439        }
440
441        $strings = explode( $explode_delimiter, $string );
442
443        // Remove any non alpha numeric characters from the strings to check against.
444        foreach ( $strings as $key => $_string ) {
445            $_string = trim( preg_replace( '/[^a-zA-Z0-9]/', '', $_string ) );
446            if ( empty( $_string ) ) {
447                continue;
448            }
449
450            $strings[ $key ] = $_string;
451        }
452
453        // Check the original too.
454        $strings[] = trim( $string );
455
456        // Check the original minus non alpha numeric characters.
457        $strings[] = trim( preg_replace( '/[^a-zA-Z0-9]/', '', $string ) );
458
459        // Remove any empty strings.
460        // Note: This will also filter out '0'.
461        $strings = array_filter( $strings );
462        if ( empty( $strings ) ) {
463            return false;
464        }
465
466        $this->user_strings_to_test = array_unique( array_merge( $this->user_strings_to_test, $strings ) );
467
468        return true;
469    }
470
471    /**
472     * Getter for the user strings array.
473     *
474     * @return array user strings.
475     */
476    protected function get_user_strings_to_test() {
477        return $this->user_strings_to_test;
478    }
479
480    /**
481     * Return a character set size that is used in the string.
482     *
483     * @param string $password the password.
484     *
485     * @return int number of different character sets in use.
486     */
487    protected function get_charset_size( $password ) {
488        $size = 0;
489
490        // Lowercase a-z.
491        if ( preg_match( '/[a-z]/', $password ) ) {
492            $size += 26;
493        }
494
495        // Uppercase A-Z.
496        if ( preg_match( '/[A-Z]/', substr( $password, 1, - 1 ) ) ) {
497            $size += 26;
498        }
499
500        // Digits.
501        if ( preg_match( '/\d/', substr( $password, 1, - 1 ) ) ) {
502            $size += 10;
503        }
504
505        // Over digits symbols.
506        if ( preg_match( '/[!|@|#|$|%|^|&|*|(|)]/', $password ) ) {
507            $size += 10;
508        }
509
510        // Other symbols.
511        if ( preg_match( '#[`|~|-|_|=|+|\[|{|\]|}|\\|\|;:\'",<\.>/\?]#', $password ) ) {
512            $size += 20;
513        }
514
515        // Spaces.
516        if ( strpos( $password, ' ' ) ) {
517            ++$size;
518        }
519
520        return $size;
521    }
522
523    /**
524     * Shorthand for getting a character index.
525     *
526     * @param string $char character.
527     *
528     * @return int the character code.
529     */
530    protected function get_char_index( $char ) {
531        $char = strtolower( $char[0] );
532        if ( $char < 'a' || $char > 'z' ) {
533            return 0;
534        } else {
535            return ord( $char[0] ) - ord( 'a' ) + 1;
536        }
537    }
538
539    /**
540     * This is the password strength calculation algorithm, based on the formula H = L(logN/log2).
541     *
542     * H = Entropy
543     * L = String length (the for iterator)
544     * N = Our charset size, via get_charset_size()
545     *
546     * @see https://en.wikipedia.org/wiki/Password_strength#Random_passwords
547     *
548     * On top of the base formula, we're also multiplying the bits of entropy for every char
549     * by 1 - (the probabily of it following the previous char)
550     * i.e.: the probablity of U following Q is ~0.84. If our password contains this pair of characters,
551     * the u char will only add ( 0.16^2 * charset_score ) to our total of entropy bits.
552     *
553     * @param string $password the password.
554     *
555     * @return float|int
556     */
557    protected function calculate_entropy_bits( $password ) {
558        $bits = 0;
559        // Calculate the score.
560        $charset_score = log( $this->get_charset_size( $password ) ) / log( 2 );
561
562        $aidx   = $this->get_char_index( $password[0] );
563        $length = strlen( $password );
564
565        for ( $b = 1; $b < $length; $b++ ) {
566            $bidx = $this->get_char_index( $password[ $b ] );
567
568            // 27 = number of chars in the index (a-z,' ').
569            $c = 1.0 - $this->frequency_table[ $aidx * 27 + $bidx ];
570
571            // Increment the bits.
572            $bits += $charset_score * $c * $c;
573
574            // Move on to next pair.
575            $aidx = $bidx;
576        }
577
578        return $bits;
579    }
580
581    /**
582     * A frequency table of character pairs, starting with  '  ' then  ' a', ' b' [...] , 'a ', 'aa' etc.
583     *
584     * @see http://rumkin.com/tools/password/passchk.php
585     *
586     * @var array
587     */
588    public $frequency_table = array(
589        0.23653710453418866,
590        0.04577693541332556,
591        0.03449832337075375,
592        0.042918209651552706,
593        0.037390873305146524,
594        0.028509112115468728,
595        0.02350896632162123,
596        0.022188657238664526,
597        0.028429800262428927,
598        0.04357019973757107,
599        0.00913602565971716,
600        0.03223093745443942,
601        0.02235311269864412,
602        0.04438081352966905,
603        0.04512377897652719,
604        0.020055401662049863,
605        0.055903192885260244,
606        0.0024388394809739026,
607        0.035207464644991984,
608        0.07355941099285611,
609        0.036905671380667734,
610        0.026134421927394666,
611        0.023787724158040528,
612        0.011352092141711621,
613        0.0032354570637119114,
614        0.005986878553725033,
615        0.008861933226417843,
616        0.11511532293337222,
617        0.027556203528211108,
618        0.024331243621519172,
619        0.039266365359381834,
620        0.031599941682461,
621        0.014403265782183991,
622        0.015480973902901297,
623        0.027770812071730572,
624        0.00942761335471643,
625        0.039872867764980315,
626        0.0078122175244204695,
627        0.02808456043154979,
628        0.08429100451960927,
629        0.04688963405744277,
630        0.13831170724595424,
631        0.002540311998833649,
632        0.025211838460416972,
633        0.001543082081936142,
634        0.09519638431258201,
635        0.061845750109345385,
636        0.08907071001603732,
637        0.02137571074500656,
638        0.027093162268552268,
639        0.005521504592506197,
640        0.003023181221752442,
641        0.007086747339262283,
642        0.010262720513194342,
643        0.08785070710016038,
644        0.14617757690625455,
645        0.03417291150313457,
646        0.0059635515381250915,
647        0.006146668610584633,
648        0.195202799241872,
649        0.002774748505613063,
650        0.004715556203528212,
651        0.0044776206444088066,
652        0.11205481848665985,
653        0.005654468581425864,
654        0.0028820527773727946,
655        0.07383000437381543,
656        0.005516839189386207,
657        0.006496573844583759,
658        0.09843067502551392,
659        0.0027140982650532145,
660        0.0006893133109782768,
661        0.08425368129464937,
662        0.021325557661466685,
663        0.006493074792243767,
664        0.07023414491908442,
665        0.002077270739174807,
666        0.0024633328473538415,
667        0.0007744569179180639,
668        0.015413325557661468,
669        0.0011990086018370024,
670        0.13162851727657093,
671        0.10115993585070711,
672        0.0026989357049132527,
673        0.03319317684793702,
674        0.002946202070272634,
675        0.0783216212275842,
676        0.0018358361277154103,
677        0.00258813238081353,
678        0.2141688292754046,
679        0.09853681294649366,
680        0.0032482869222918796,
681        0.04359352675317102,
682        0.01993526753171016,
683        0.0036880011663507797,
684        0.008011663507799971,
685        0.12014696019827964,
686        0.0029846916460125384,
687        0.0017553579238956116,
688        0.029470185158186325,
689        0.010413179763813967,
690        0.030699518880303252,
691        0.03508499781309229,
692        0.002021285901734947,
693        0.0010613792097973467,
694        0.0005295232541186761,
695        0.009677212421635807,
696        0.010585799679253535,
697        0.17101734946785244,
698        0.07968625164018078,
699        0.007839043592360402,
700        0.005438693687126403,
701        0.0183606939787141,
702        0.2732701559994168,
703        0.004953491762647616,
704        0.007259367254701851,
705        0.008104971570199739,
706        0.13274588132380813,
707        0.004210526315789474,
708        0.004997813092287506,
709        0.017006560723137484,
710        0.007442484327161393,
711        0.016789619478058026,
712        0.08477737279486806,
713        0.005106283714827234,
714        0.0005026971861787433,
715        0.04040355736987899,
716        0.037535500801866156,
717        0.00885960052485785,
718        0.0336410555474559,
719        0.007066919376002332,
720        0.005344219273946639,
721        0.0006333284735384167,
722        0.010684939495553289,
723        0.0063064586674442345,
724        0.15386849394955532,
725        0.015049424114302375,
726        0.012162705933809595,
727        0.020425134859308938,
728        0.037366379938766583,
729        0.02157165767604607,
730        0.009373961218836564,
731        0.0173214754337367,
732        0.009616562181075958,
733        0.029522670943286193,
734        0.010154249890654615,
735        0.018600962239393497,
736        0.06362210234728094,
737        0.03157078291296107,
738        0.151603440734801,
739        0.0062329785683044175,
740        0.014775331681003062,
741        0.0020854351946347867,
742        0.1826342032366234,
743        0.0878017203674005,
744        0.054190989940224525,
745        0.010329202507654177,
746        0.012763376585508092,
747        0.0064872430383437815,
748        0.006381105117364048,
749        0.005388540603586529,
750        0.0090800408222773,
751        0.09611196967487973,
752        0.09940691062837148,
753        0.01033969966467415,
754        0.004034407348009914,
755        0.008826942703017933,
756        0.11474675608689314,
757        0.07132584924916169,
758        0.012388977985129028,
759        0.005435194634786413,
760        0.1417174515235457,
761        0.0037066627788307337,
762        0.0045802595130485495,
763        0.060800699810468,
764        0.005341886572386646,
765        0.005683627350925791,
766        0.12434932205860913,
767        0.004596588423968508,
768        0.0007534626038781163,
769        0.07107041842834232,
770        0.022361277154104096,
771        0.04784720804782038,
772        0.06277533168100306,
773        0.003441901151771395,
774        0.005828254847645429,
775        0.0009669047966175828,
776        0.009470768333576322,
777        0.002077270739174807,
778        0.12797667298440007,
779        0.08797783933518005,
780        0.005388540603586529,
781        0.0024913252660737715,
782        0.007550954949701123,
783        0.2786866890217233,
784        0.002509986878553725,
785        0.029002478495407494,
786        0.0303204548768042,
787        0.07576614666861058,
788        0.00246799825047383,
789        0.00592389561160519,
790        0.039574281965301064,
791        0.00706808572678233,
792        0.03304505029887739,
793        0.05474150750838315,
794        0.0028633911648928414,
795        0.0005073625892987316,
796        0.07293541332555767,
797        0.053528502697186175,
798        0.022566554891383584,
799        0.038151334013704616,
800        0.002716430966613209,
801        0.005049132526607377,
802        0.0009902318122175246,
803        0.008997229916897508,
804        0.0011861787432570347,
805        0.1666377022889634,
806        0.14414462749671964,
807        0.003374252806531564,
808        0.005169266656947077,
809        0.008468873013558828,
810        0.16337541915731155,
811        0.002873888321912815,
812        0.004305000728969237,
813        0.0031141565825922144,
814        0.1241172182533897,
815        0.0052800699810468,
816        0.008969237498177577,
817        0.024094474413179766,
818        0.017029887738737422,
819        0.01722700102055693,
820        0.10618457501093455,
821        0.006147834961364631,
822        0.0008269427030179326,
823        0.03303571949263741,
824        0.024188948826359528,
825        0.05213937891820965,
826        0.04505846333284735,
827        0.0035270447587111824,
828        0.006799825047383001,
829        0.0008199445983379502,
830        0.02206735675754483,
831        0.001010059775477475,
832        0.11971191135734072,
833        0.04656538854060359,
834        0.011243621519171892,
835        0.06513019390581717,
836        0.032375564951159064,
837        0.06347047674588133,
838        0.013678961947805804,
839        0.03309870243475726,
840        0.006982942119842543,
841        0.009726199154395685,
842        0.010121592068814697,
843        0.032514360693978714,
844        0.04986032949409535,
845        0.039734072022160664,
846        0.15690683773144773,
847        0.03949963551538125,
848        0.014790494241143023,
849        0.002722262720513194,
850        0.02614375273363464,
851        0.10753637556495116,
852        0.06764834523983088,
853        0.006221315060504448,
854        0.021317393206006705,
855        0.0030826651115322934,
856        0.002399183554454002,
857        0.0019069835252952323,
858        0.015595276279341012,
859        0.0925126111678087,
860        0.18437906400349907,
861        0.006538562472663654,
862        0.008719638431258201,
863        0.02116693395538708,
864        0.18241376293920394,
865        0.007290858725761773,
866        0.005976381396705059,
867        0.005629975215045925,
868        0.09721300481119698,
869        0.004810030616707975,
870        0.024303251202799244,
871        0.012954658113427612,
872        0.011057005394372358,
873        0.02733459688001166,
874        0.10135121737862662,
875        0.012016912086309959,
876        0.001055547455897361,
877        0.009027555037177431,
878        0.07162326869806095,
879        0.01007143898527482,
880        0.07297623560285756,
881        0.006741507508383147,
882        0.0036891675171307776,
883        0.0008409389123778977,
884        0.011272780288671819,
885        0.007020265344802449,
886        0.1030389269572824,
887        0.15350809155853623,
888        0.004232686980609419,
889        0.004353987461729115,
890        0.0023385333138941536,
891        0.14450386353695874,
892        0.002546143752733635,
893        0.0024470039364338824,
894        0.01200758128006998,
895        0.0981227584195947,
896        0.003161976964572095,
897        0.040695145064878264,
898        0.03460446129173349,
899        0.003908441463770229,
900        0.01598483743986004,
901        0.13107216795451232,
902        0.003129319142732177,
903        0.00032307916605919226,
904        0.04050386353695874,
905        0.05452689896486368,
906        0.03589677795597026,
907        0.07087097244496282,
908        0.006143169558244642,
909        0.008684647907858289,
910        0.0004607085580988482,
911        0.022010205569324977,
912        0.0009097536083977258,
913        0.07328765126111678,
914        0.14751421490013122,
915        0.008015162560139961,
916        0.006601545414783497,
917        0.025279486805656802,
918        0.1682449336637994,
919        0.008313748359819215,
920        0.007010934538562473,
921        0.005886572386645284,
922        0.16889575739903775,
923        0.004123050007289692,
924        0.011925936725470185,
925        0.10007289692374982,
926        0.013380376148126549,
927        0.009021723283277445,
928        0.08650823735238372,
929        0.007756232686980609,
930        0.0007243038343781893,
931        0.0026791077416533026,
932        0.02797492345823006,
933        0.032384895757399036,
934        0.04187432570345531,
935        0.00882461000145794,
936        0.0032401224668318998,
937        0.00033357632307916605,
938        0.027878116343490307,
939        0.0022277299897944304,
940        0.14333518005540166,
941        0.1725534334451086,
942        0.02781629975215046,
943        0.006909462020702727,
944        0.005264907420906838,
945        0.16661437527336345,
946        0.004325995043009185,
947        0.003334596880011664,
948        0.005312727802886718,
949        0.14024668318996938,
950        0.0013261408368566844,
951        0.003504884093891238,
952        0.006375273363464061,
953        0.04964922000291588,
954        0.008290421344219274,
955        0.09536783787724158,
956        0.05394372357486515,
957        0.005505175681586237,
958        0.005339553870826651,
959        0.01782067356757545,
960        0.006710016037323225,
961        0.05105933809593235,
962        0.002983525295232541,
963        0.002940370316372649,
964        0.0004548768041988629,
965        0.01208456043154979,
966        0.000915585362297711,
967        0.20146260387811635,
968        0.067196967487972,
969        0.006158332118384605,
970        0.025438110511736407,
971        0.07753783350342616,
972        0.1273876658405015,
973        0.009337804344656656,
974        0.07683452398308792,
975        0.0070412596588423975,
976        0.08747164309666132,
977        0.0038827817466102928,
978        0.018116926665694706,
979        0.005017641055547455,
980        0.004567429654468581,
981        0.028277008310249308,
982        0.05271555620352821,
983        0.004394809739029013,
984        0.0013343052923166642,
985        0.00411605190260971,
986        0.059621519171890944,
987        0.09073859163143316,
988        0.01446858142586383,
989        0.006770666277883074,
990        0.003425572240851436,
991        0.0004455459979588861,
992        0.010401516256013998,
993        0.005825922146085436,
994        0.10833882490158916,
995        0.007584779122321038,
996        0.016903921854497742,
997        0.02719580113719201,
998        0.0304814112844438,
999        0.02206385770520484,
1000        0.013064295086747339,
1001        0.02696369733197259,
1002        0.009581571657676046,
1003        0.026761918647033093,
1004        0.006510570053943724,
1005        0.021941390873305145,
1006        0.07042659279778393,
1007        0.05437410701268406,
1008        0.1425175681586237,
1009        0.027802303542790494,
1010        0.037690625455605774,
1011        0.0019606356611750987,
1012        0.1095623268698061,
1013        0.06157748942994606,
1014        0.044618749088788455,
1015        0.04955124653739612,
1016        0.03608689313310978,
1017        0.018381688292754043,
1018        0.003404577926811489,
1019        0.015036594255722409,
1020        0.009600233270156,
1021        0.10794693103951014,
1022        0.12447528794284882,
1023        0.0031981338387520046,
1024        0.0074716430966613205,
1025        0.003202799241871993,
1026        0.13437643971424407,
1027        0.006655197550663361,
1028        0.0036693395538708266,
1029        0.049338970695436656,
1030        0.09486863974340283,
1031        0.0015990669193760023,
1032        0.0026604461291733486,
1033        0.051775477474850555,
1034        0.0041347135150896636,
1035        0.005450357194926374,
1036        0.12030325120279925,
1037        0.04581309228750547,
1038        0.0004537104534188657,
1039        0.12425601399620935,
1040        0.025981629975215047,
1041        0.023926519900860182,
1042        0.04423385333138941,
1043        0.0017950138504155123,
1044        0.002661612479953346,
1045        0.0006333284735384167,
1046        0.008449045050298877,
1047        0.000653156436798367,
1048        0.04816678816153958,
1049        0.008625164018078437,
1050        0.0039037760606502403,
1051        0.005228750546726928,
1052        0.004531272780288672,
1053        0.0056672984400058316,
1054        0.00359585945473101,
1055        0.0032179618020119548,
1056        0.0038093016474704767,
1057        0.011452398308791368,
1058        0.002519317684793702,
1059        0.00280390727511299,
1060        0.005572824026826068,
1061        0.004554599795888614,
1062        0.004531272780288672,
1063        0.0035841959469310393,
1064        0.004400641492928998,
1065        0.0036670068523108326,
1066        0.004839189386207902,
1067        0.006258638285464354,
1068        0.004897506925207757,
1069        0.840776789619478,
1070        0.004968654322787578,
1071        0.002886718180492783,
1072        0.0019757982213150604,
1073        0.0018568304417553576,
1074        0.001691208630995772,
1075        0.09009243329931477,
1076        0.14030150167662925,
1077        0.013242746756086894,
1078        0.013746610293045632,
1079        0.027342761335471644,
1080        0.16938912377897652,
1081        0.006607377168683481,
1082        0.01661933226417845,
1083        0.008173786266219566,
1084        0.13297448607668758,
1085        0.0034675608689313307,
1086        0.016641492928998396,
1087        0.011722991689750693,
1088        0.021493512173786266,
1089        0.03430820819361423,
1090        0.10099548039072752,
1091        0.00873596734217816,
1092        0.0018323370753754193,
1093        0.020103222044029742,
1094        0.047197550663362,
1095        0.040833940807697915,
1096        0.03361189677795597,
1097        0.010844729552412887,
1098        0.005544831608106138,
1099        0.0007522962530981193,
1100        0.01525120279924187,
1101        0.00815512465373961,
1102        0.2109648636827526,
1103        0.058258055110074355,
1104        0.007181221752442048,
1105        0.043560868931331105,
1106        0.004058900714389853,
1107        0.10618107595859454,
1108        0.0062399766729844,
1109        0.004835690333867911,
1110        0.02679224376731302,
1111        0.08414637702288964,
1112        0.0030698352529523252,
1113        0.03637498177576906,
1114        0.01592885260242018,
1115        0.017413617145356466,
1116        0.008430383437818923,
1117        0.037231083248286924,
1118        0.03290275550371775,
1119        0.007538125091121154,
1120        0.004500947660008748,
1121        0.05932409972299169,
1122        0.16006764834523984,
1123        0.03309636973319726,
1124        0.007766729844000583,
1125        0.005225251494386936,
1126        0.0006321621227584196,
1127        0.012989648636827526,
1128        0.005274238227146815,
1129        0.1254503571949264,
1130        0.12852719055255868,
1131        0.0035433736696311416,
1132        0.005203090829566993,
1133        0.0019314768916751715,
1134        0.20520775623268697,
1135        0.002509986878553725,
1136        0.00343606939787141,
1137        0.027138649948972155,
1138        0.13926578218399185,
1139        0.004565096952908587,
1140        0.005614812654905963,
1141        0.00874413179763814,
1142        0.004109053797929727,
1143        0.008300918501239247,
1144        0.08270943286193323,
1145        0.002912377897652719,
1146        0.0037066627788307337,
1147        0.06909578655780726,
1148        0.03242805073625893,
1149        0.05237614812654906,
1150        0.04723487388832191,
1151        0.0038991106575302524,
1152        0.006299460562764251,
1153        0.00043388249015891526,
1154        0.020029741944889927,
1155        0.005311561452106721,
1156        0.09334072022160665,
1157        0.022940953491762648,
1158        0.024658988190698353,
1159        0.02901297565242747,
1160        0.03531593526753171,
1161        0.0758023035427905,
1162        0.013711619769645722,
1163        0.021597317393206007,
1164        0.009670214316955824,
1165        0.044728386062108175,
1166        0.010596296836273509,
1167        0.03264382563055839,
1168        0.0604822860475288,
1169        0.05489546581134276,
1170        0.11501851581863246,
1171        0.01837585653885406,
1172        0.026237060796034405,
1173        0.0011255285026971862,
1174        0.08704125965884241,
1175        0.10156349322058608,
1176        0.06660562764251349,
1177        0.023434319871701415,
1178        0.010777081207173057,
1179        0.005409534917626476,
1180        0.003123487388832191,
1181        0.0028762210234728096,
1182        0.0089995626184575,
1183        0.07518297127861205,
1184        0.2314868056568013,
1185        0.002226563639014434,
1186        0.003285610147251786,
1187        0.0027455897361131363,
1188        0.2724537104534189,
1189        0.0016655489138358362,
1190        0.0019209797346551977,
1191        0.0022137337804344656,
1192        0.17690392185449774,
1193        0.0014532730718763668,
1194        0.0024994897215337513,
1195        0.015302522233561744,
1196        0.003441901151771395,
1197        0.015303688584341741,
1198        0.09314593964134713,
1199        0.0017833503426155418,
1200        0.0005108616416387229,
1201        0.017828838023035427,
1202        0.010385187345094037,
1203        0.003168975069252078,
1204        0.01902901297565243,
1205        0.005525003644846187,
1206        0.0010088934246974776,
1207        0.0009272488700976819,
1208        0.036282840064149294,
1209        0.0022977110365942554,
1210        0.0766805656801283,
1211        0.22270418428342326,
1212        0.005283569033386791,
1213        0.007155562035282111,
1214        0.01173582154833066,
1215        0.1715620352821111,
1216        0.003925936725470185,
1217        0.004425134859308937,
1218        0.020040239101909902,
1219        0.14243242455168392,
1220        0.0016737133692958156,
1221        0.0066808572678232975,
1222        0.011980755212130047,
1223        0.012638577052048404,
1224        0.07206065024055984,
1225        0.08115701997375711,
1226        0.00710424260096224,
1227        0.0007278028867181805,
1228        0.02347630849978131,
1229        0.04595538708266512,
1230        0.01481965301064295,
1231        0.013925061962385188,
1232        0.0018125091121154687,
1233        0.00529173348884677,
1234        0.0016340574427759146,
1235        0.03072401224668319,
1236        0.0023746901880740633,
1237        0.25174165330223064,
1238        0.06673392622831317,
1239        0.00878378772415804,
1240        0.03956261845750109,
1241        0.010077270739174807,
1242        0.0844787869951888,
1243        0.00985216503863537,
1244        0.004973319725907567,
1245        0.01893220586091267,
1246        0.11200583175389998,
1247        0.0028715556203528212,
1248        0.004095057588569762,
1249        0.01202391019098994,
1250        0.01756757544831608,
1251        0.014825484764542934,
1252        0.05312961073042717,
1253        0.06746872721971132,
1254        0.003845458521650386,
1255        0.0210806239976673,
1256        0.019443067502551394,
1257        0.08017028721387957,
1258        0.01825572240851436,
1259        0.005365213587986587,
1260        0.01959702580551101,
1261        0.026184575010934536,
1262        0.02474879720075813,
1263        0.002171745152354571,
1264        0.25827321767021433,
1265        0.048050153083539875,
1266        0.01043184137629392,
1267        0.03930485493512174,
1268        0.027640180784370902,
1269        0.03294007872867765,
1270        0.006474413179763814,
1271        0.018314039947514214,
1272        0.015119405161102202,
1273        0.014706516984983233,
1274        0.005494678524566263,
1275        0.03309870243475726,
1276        0.043864120134130345,
1277        0.058996355153812505,
1278        0.06265986295378335,
1279        0.04633328473538417,
1280        0.03790756670068523,
1281        0.0004642076104388394,
1282        0.037849249161685375,
1283        0.08369966467415076,
1284        0.04999679253535501,
1285        0.02392768625164018,
1286        0.010998687855372504,
1287        0.009881323808135296,
1288        0.003867619186470331,
1289        0.012434465665548913,
1290        0.007253535500801866,
1291        0.11106225397288234,
1292        0.17624726636535937,
1293        0.008209943140399476,
1294        0.008390727511299025,
1295        0.012682898381688294,
1296        0.1825653885406036,
1297        0.001538416678816154,
1298        0.004590756670068524,
1299        0.008710307625018223,
1300        0.1299513048549351,
1301        0.002677941390873305,
1302        0.012309666132089225,
1303        0.014087184720804781,
1304        0.01199941682461,
1305        0.031246537396121883,
1306        0.07206648199445984,
1307        0.008254264470039366,
1308        0.0007033095203382417,
1309        0.007034261554162415,
1310        0.006599212713223502,
1311        0.013906400349905234,
1312        0.050098265053214755,
1313        0.007133401370462167,
1314        0.017750692520775622,
1315        0.0008257763522379356,
1316        0.03918821985712203,
1317        0.06015454147834961,
1318    );
1319}