├── .babelrc ├── .eslintrc ├── .gitignore ├── .npmignore ├── .travis.yml ├── LICENSE ├── README.md ├── benchmark ├── benchmark.js └── test-data-1.js ├── package.json ├── src ├── abp-filter-parser.js ├── badFingerprints.js └── extractInfo.js └── test ├── data └── easylist.txt ├── helpers.js ├── options-test.js ├── parser-test.js └── rule-types-test.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["es2015", "stage-2"] 3 | } 4 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "babel-eslint", 3 | "env": { 4 | "es6": true, 5 | "jasmine": false, 6 | "mocha": true, 7 | "node": true, 8 | "browser": false, 9 | "builtin": true, 10 | "jquery": false 11 | }, 12 | "globals": { 13 | // Setting flase disallows writing 14 | "marionetteScriptFinished": false, 15 | "marionette": false, 16 | "test": false, 17 | "setup": false 18 | }, 19 | "rules": { 20 | "comma-dangle": 0, 21 | "block-scoped-var": 2, 22 | "camelcase": [2, {"properties": "always"}], 23 | "curly": [ 24 | 2, 25 | "all" 26 | ], 27 | "dot-notation": [ 28 | 2, 29 | { 30 | "allowKeywords": true 31 | } 32 | ], 33 | "eqeqeq": [ 34 | 2, 35 | "allow-null" 36 | ], 37 | "guard-for-in": 0, 38 | "max-len": [ 39 | 2, 40 | 200, 41 | 2 42 | ], 43 | "new-cap": 2, 44 | "no-bitwise": 0, 45 | "no-caller": 2, 46 | "no-cond-assign": [ 47 | 2, 48 | "except-parens" 49 | ], 50 | "keyword-spacing": 2, 51 | "no-debugger": 2, 52 | "no-empty": 2, 53 | "no-eval": 2, 54 | "no-extend-native": 2, 55 | "no-extra-parens": 2, 56 | "no-irregular-whitespace": 2, 57 | "no-trailing-spaces": 2, 58 | "no-iterator": 2, 59 | "no-loop-func": 2, 60 | "no-multi-str": 2, 61 | "no-new": 2, 62 | "no-plusplus": 0, 63 | "no-proto": 2, 64 | "no-script-url": 2, 65 | "no-sequences": 2, 66 | "no-shadow": 2, 67 | "no-undef": 2, 68 | "no-unused-vars": 2, 69 | "no-use-before-define": [ 70 | 2, 71 | "nofunc" 72 | ], 73 | "no-with": 2, 74 | "quotes": [ 75 | 2, 76 | "single" 77 | ], 78 | "semi": [ 79 | 2, 80 | "always" 81 | ], 82 | "strict": 0, 83 | "valid-typeof": 2, 84 | "wrap-iife": [ 85 | 2, 86 | "inside" 87 | ], 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | 5 | # Runtime data 6 | pids 7 | *.pid 8 | *.seed 9 | 10 | # Directory for instrumented libs generated by jscoverage/JSCover 11 | lib-cov 12 | 13 | # Coverage directory used by tools like istanbul 14 | coverage 15 | 16 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 17 | .grunt 18 | 19 | # node-waf configuration 20 | .lock-wscript 21 | 22 | # Compiled binary addons (http://nodejs.org/api/addons.html) 23 | build/Release 24 | 25 | # Dependency directory 26 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git 27 | node_modules 28 | 29 | # No need to include dist with npm prepublish 30 | dist 31 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | 5 | # Runtime data 6 | pids 7 | *.pid 8 | *.seed 9 | 10 | # Directory for instrumented libs generated by jscoverage/JSCover 11 | lib-cov 12 | 13 | # Coverage directory used by tools like istanbul 14 | coverage 15 | 16 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 17 | .grunt 18 | 19 | # node-waf configuration 20 | .lock-wscript 21 | 22 | # Compiled binary addons (http://nodejs.org/api/addons.html) 23 | build/Release 24 | 25 | # Dependency directory 26 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git 27 | node_modules 28 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "5.0" 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Mozilla Public License, version 2.0 2 | 3 | 1. Definitions 4 | 5 | 1.1. "Contributor" 6 | 7 | means each individual or legal entity that creates, contributes to the 8 | creation of, or owns Covered Software. 9 | 10 | 1.2. "Contributor Version" 11 | 12 | means the combination of the Contributions of others (if any) used by a 13 | Contributor and that particular Contributor's Contribution. 14 | 15 | 1.3. "Contribution" 16 | 17 | means Covered Software of a particular Contributor. 18 | 19 | 1.4. "Covered Software" 20 | 21 | means Source Code Form to which the initial Contributor has attached the 22 | notice in Exhibit A, the Executable Form of such Source Code Form, and 23 | Modifications of such Source Code Form, in each case including portions 24 | thereof. 25 | 26 | 1.5. "Incompatible With Secondary Licenses" 27 | means 28 | 29 | a. that the initial Contributor has attached the notice described in 30 | Exhibit B to the Covered Software; or 31 | 32 | b. that the Covered Software was made available under the terms of 33 | version 1.1 or earlier of the License, but not also under the terms of 34 | a Secondary License. 35 | 36 | 1.6. "Executable Form" 37 | 38 | means any form of the work other than Source Code Form. 39 | 40 | 1.7. "Larger Work" 41 | 42 | means a work that combines Covered Software with other material, in a 43 | separate file or files, that is not Covered Software. 44 | 45 | 1.8. "License" 46 | 47 | means this document. 48 | 49 | 1.9. "Licensable" 50 | 51 | means having the right to grant, to the maximum extent possible, whether 52 | at the time of the initial grant or subsequently, any and all of the 53 | rights conveyed by this License. 54 | 55 | 1.10. "Modifications" 56 | 57 | means any of the following: 58 | 59 | a. any file in Source Code Form that results from an addition to, 60 | deletion from, or modification of the contents of Covered Software; or 61 | 62 | b. any new file in Source Code Form that contains any Covered Software. 63 | 64 | 1.11. "Patent Claims" of a Contributor 65 | 66 | means any patent claim(s), including without limitation, method, 67 | process, and apparatus claims, in any patent Licensable by such 68 | Contributor that would be infringed, but for the grant of the License, 69 | by the making, using, selling, offering for sale, having made, import, 70 | or transfer of either its Contributions or its Contributor Version. 71 | 72 | 1.12. "Secondary License" 73 | 74 | means either the GNU General Public License, Version 2.0, the GNU Lesser 75 | General Public License, Version 2.1, the GNU Affero General Public 76 | License, Version 3.0, or any later versions of those licenses. 77 | 78 | 1.13. "Source Code Form" 79 | 80 | means the form of the work preferred for making modifications. 81 | 82 | 1.14. "You" (or "Your") 83 | 84 | means an individual or a legal entity exercising rights under this 85 | License. For legal entities, "You" includes any entity that controls, is 86 | controlled by, or is under common control with You. For purposes of this 87 | definition, "control" means (a) the power, direct or indirect, to cause 88 | the direction or management of such entity, whether by contract or 89 | otherwise, or (b) ownership of more than fifty percent (50%) of the 90 | outstanding shares or beneficial ownership of such entity. 91 | 92 | 93 | 2. License Grants and Conditions 94 | 95 | 2.1. Grants 96 | 97 | Each Contributor hereby grants You a world-wide, royalty-free, 98 | non-exclusive license: 99 | 100 | a. under intellectual property rights (other than patent or trademark) 101 | Licensable by such Contributor to use, reproduce, make available, 102 | modify, display, perform, distribute, and otherwise exploit its 103 | Contributions, either on an unmodified basis, with Modifications, or 104 | as part of a Larger Work; and 105 | 106 | b. under Patent Claims of such Contributor to make, use, sell, offer for 107 | sale, have made, import, and otherwise transfer either its 108 | Contributions or its Contributor Version. 109 | 110 | 2.2. Effective Date 111 | 112 | The licenses granted in Section 2.1 with respect to any Contribution 113 | become effective for each Contribution on the date the Contributor first 114 | distributes such Contribution. 115 | 116 | 2.3. Limitations on Grant Scope 117 | 118 | The licenses granted in this Section 2 are the only rights granted under 119 | this License. No additional rights or licenses will be implied from the 120 | distribution or licensing of Covered Software under this License. 121 | Notwithstanding Section 2.1(b) above, no patent license is granted by a 122 | Contributor: 123 | 124 | a. for any code that a Contributor has removed from Covered Software; or 125 | 126 | b. for infringements caused by: (i) Your and any other third party's 127 | modifications of Covered Software, or (ii) the combination of its 128 | Contributions with other software (except as part of its Contributor 129 | Version); or 130 | 131 | c. under Patent Claims infringed by Covered Software in the absence of 132 | its Contributions. 133 | 134 | This License does not grant any rights in the trademarks, service marks, 135 | or logos of any Contributor (except as may be necessary to comply with 136 | the notice requirements in Section 3.4). 137 | 138 | 2.4. Subsequent Licenses 139 | 140 | No Contributor makes additional grants as a result of Your choice to 141 | distribute the Covered Software under a subsequent version of this 142 | License (see Section 10.2) or under the terms of a Secondary License (if 143 | permitted under the terms of Section 3.3). 144 | 145 | 2.5. Representation 146 | 147 | Each Contributor represents that the Contributor believes its 148 | Contributions are its original creation(s) or it has sufficient rights to 149 | grant the rights to its Contributions conveyed by this License. 150 | 151 | 2.6. Fair Use 152 | 153 | This License is not intended to limit any rights You have under 154 | applicable copyright doctrines of fair use, fair dealing, or other 155 | equivalents. 156 | 157 | 2.7. Conditions 158 | 159 | Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in 160 | Section 2.1. 161 | 162 | 163 | 3. Responsibilities 164 | 165 | 3.1. Distribution of Source Form 166 | 167 | All distribution of Covered Software in Source Code Form, including any 168 | Modifications that You create or to which You contribute, must be under 169 | the terms of this License. You must inform recipients that the Source 170 | Code Form of the Covered Software is governed by the terms of this 171 | License, and how they can obtain a copy of this License. You may not 172 | attempt to alter or restrict the recipients' rights in the Source Code 173 | Form. 174 | 175 | 3.2. Distribution of Executable Form 176 | 177 | If You distribute Covered Software in Executable Form then: 178 | 179 | a. such Covered Software must also be made available in Source Code Form, 180 | as described in Section 3.1, and You must inform recipients of the 181 | Executable Form how they can obtain a copy of such Source Code Form by 182 | reasonable means in a timely manner, at a charge no more than the cost 183 | of distribution to the recipient; and 184 | 185 | b. You may distribute such Executable Form under the terms of this 186 | License, or sublicense it under different terms, provided that the 187 | license for the Executable Form does not attempt to limit or alter the 188 | recipients' rights in the Source Code Form under this License. 189 | 190 | 3.3. Distribution of a Larger Work 191 | 192 | You may create and distribute a Larger Work under terms of Your choice, 193 | provided that You also comply with the requirements of this License for 194 | the Covered Software. If the Larger Work is a combination of Covered 195 | Software with a work governed by one or more Secondary Licenses, and the 196 | Covered Software is not Incompatible With Secondary Licenses, this 197 | License permits You to additionally distribute such Covered Software 198 | under the terms of such Secondary License(s), so that the recipient of 199 | the Larger Work may, at their option, further distribute the Covered 200 | Software under the terms of either this License or such Secondary 201 | License(s). 202 | 203 | 3.4. Notices 204 | 205 | You may not remove or alter the substance of any license notices 206 | (including copyright notices, patent notices, disclaimers of warranty, or 207 | limitations of liability) contained within the Source Code Form of the 208 | Covered Software, except that You may alter any license notices to the 209 | extent required to remedy known factual inaccuracies. 210 | 211 | 3.5. Application of Additional Terms 212 | 213 | You may choose to offer, and to charge a fee for, warranty, support, 214 | indemnity or liability obligations to one or more recipients of Covered 215 | Software. However, You may do so only on Your own behalf, and not on 216 | behalf of any Contributor. You must make it absolutely clear that any 217 | such warranty, support, indemnity, or liability obligation is offered by 218 | You alone, and You hereby agree to indemnify every Contributor for any 219 | liability incurred by such Contributor as a result of warranty, support, 220 | indemnity or liability terms You offer. You may include additional 221 | disclaimers of warranty and limitations of liability specific to any 222 | jurisdiction. 223 | 224 | 4. Inability to Comply Due to Statute or Regulation 225 | 226 | If it is impossible for You to comply with any of the terms of this License 227 | with respect to some or all of the Covered Software due to statute, 228 | judicial order, or regulation then You must: (a) comply with the terms of 229 | this License to the maximum extent possible; and (b) describe the 230 | limitations and the code they affect. Such description must be placed in a 231 | text file included with all distributions of the Covered Software under 232 | this License. Except to the extent prohibited by statute or regulation, 233 | such description must be sufficiently detailed for a recipient of ordinary 234 | skill to be able to understand it. 235 | 236 | 5. Termination 237 | 238 | 5.1. The rights granted under this License will terminate automatically if You 239 | fail to comply with any of its terms. However, if You become compliant, 240 | then the rights granted under this License from a particular Contributor 241 | are reinstated (a) provisionally, unless and until such Contributor 242 | explicitly and finally terminates Your grants, and (b) on an ongoing 243 | basis, if such Contributor fails to notify You of the non-compliance by 244 | some reasonable means prior to 60 days after You have come back into 245 | compliance. Moreover, Your grants from a particular Contributor are 246 | reinstated on an ongoing basis if such Contributor notifies You of the 247 | non-compliance by some reasonable means, this is the first time You have 248 | received notice of non-compliance with this License from such 249 | Contributor, and You become compliant prior to 30 days after Your receipt 250 | of the notice. 251 | 252 | 5.2. If You initiate litigation against any entity by asserting a patent 253 | infringement claim (excluding declaratory judgment actions, 254 | counter-claims, and cross-claims) alleging that a Contributor Version 255 | directly or indirectly infringes any patent, then the rights granted to 256 | You by any and all Contributors for the Covered Software under Section 257 | 2.1 of this License shall terminate. 258 | 259 | 5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user 260 | license agreements (excluding distributors and resellers) which have been 261 | validly granted by You or Your distributors under this License prior to 262 | termination shall survive termination. 263 | 264 | 6. Disclaimer of Warranty 265 | 266 | Covered Software is provided under this License on an "as is" basis, 267 | without warranty of any kind, either expressed, implied, or statutory, 268 | including, without limitation, warranties that the Covered Software is free 269 | of defects, merchantable, fit for a particular purpose or non-infringing. 270 | The entire risk as to the quality and performance of the Covered Software 271 | is with You. Should any Covered Software prove defective in any respect, 272 | You (not any Contributor) assume the cost of any necessary servicing, 273 | repair, or correction. This disclaimer of warranty constitutes an essential 274 | part of this License. No use of any Covered Software is authorized under 275 | this License except under this disclaimer. 276 | 277 | 7. Limitation of Liability 278 | 279 | Under no circumstances and under no legal theory, whether tort (including 280 | negligence), contract, or otherwise, shall any Contributor, or anyone who 281 | distributes Covered Software as permitted above, be liable to You for any 282 | direct, indirect, special, incidental, or consequential damages of any 283 | character including, without limitation, damages for lost profits, loss of 284 | goodwill, work stoppage, computer failure or malfunction, or any and all 285 | other commercial damages or losses, even if such party shall have been 286 | informed of the possibility of such damages. This limitation of liability 287 | shall not apply to liability for death or personal injury resulting from 288 | such party's negligence to the extent applicable law prohibits such 289 | limitation. Some jurisdictions do not allow the exclusion or limitation of 290 | incidental or consequential damages, so this exclusion and limitation may 291 | not apply to You. 292 | 293 | 8. Litigation 294 | 295 | Any litigation relating to this License may be brought only in the courts 296 | of a jurisdiction where the defendant maintains its principal place of 297 | business and such litigation shall be governed by laws of that 298 | jurisdiction, without reference to its conflict-of-law provisions. Nothing 299 | in this Section shall prevent a party's ability to bring cross-claims or 300 | counter-claims. 301 | 302 | 9. Miscellaneous 303 | 304 | This License represents the complete agreement concerning the subject 305 | matter hereof. If any provision of this License is held to be 306 | unenforceable, such provision shall be reformed only to the extent 307 | necessary to make it enforceable. Any law or regulation which provides that 308 | the language of a contract shall be construed against the drafter shall not 309 | be used to construe this License against a Contributor. 310 | 311 | 312 | 10. Versions of the License 313 | 314 | 10.1. New Versions 315 | 316 | Mozilla Foundation is the license steward. Except as provided in Section 317 | 10.3, no one other than the license steward has the right to modify or 318 | publish new versions of this License. Each version will be given a 319 | distinguishing version number. 320 | 321 | 10.2. Effect of New Versions 322 | 323 | You may distribute the Covered Software under the terms of the version 324 | of the License under which You originally received the Covered Software, 325 | or under the terms of any subsequent version published by the license 326 | steward. 327 | 328 | 10.3. Modified Versions 329 | 330 | If you create software not governed by this License, and you want to 331 | create a new license for such software, you may create and use a 332 | modified version of this License if you rename the license and remove 333 | any references to the name of the license steward (except to note that 334 | such modified license differs from this License). 335 | 336 | 10.4. Distributing Source Code Form that is Incompatible With Secondary 337 | Licenses If You choose to distribute Source Code Form that is 338 | Incompatible With Secondary Licenses under the terms of this version of 339 | the License, the notice described in Exhibit B of this License must be 340 | attached. 341 | 342 | Exhibit A - Source Code Form License Notice 343 | 344 | This Source Code Form is subject to the 345 | terms of the Mozilla Public License, v. 346 | 2.0. If a copy of the MPL was not 347 | distributed with this file, You can 348 | obtain one at 349 | http://mozilla.org/MPL/2.0/. 350 | 351 | If it is not possible or desirable to put the notice in a particular file, 352 | then You may include the notice in a location (such as a LICENSE file in a 353 | relevant directory) where a recipient would be likely to look for such a 354 | notice. 355 | 356 | You may add additional accurate notices of copyright ownership. 357 | 358 | Exhibit B - "Incompatible With Secondary Licenses" Notice 359 | 360 | This Source Code Form is "Incompatible 361 | With Secondary Licenses", as defined by 362 | the Mozilla Public License, v. 2.0. 363 | 364 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # abp-filter-parser 2 | 3 | For a faster more precise version of this library, see its [C++ gyp rewrite](https://github.com/bbondy/abp-filter-parser-cpp). 4 | 5 | JavaScript Adblock Plus filter parser for lists like EasyList 6 | 7 | [![Build Status](https://travis-ci.org/bbondy/abp-filter-parser.svg?branch=master)](https://travis-ci.org/bbondy/abp-filter-parser) 8 | 9 | Parses filter rules as per: 10 | - https://adblockplus.org/en/filters 11 | - https://adblockplus.org/en/filter-cheatsheet 12 | 13 | ## Usage 14 | 15 | Babel / ES6: 16 | 17 | ```javascript 18 | import * as ABPFilterParser from 'abp-filter-parser.js'; 19 | ``` 20 | 21 | Node: 22 | 23 | ```javascript 24 | let ABPFilterParser = require('abp-filter-parser'); 25 | ``` 26 | 27 | ## Primary API: 28 | 29 | ```javascript 30 | let ABPFilterParser = require('abp-filter-parser'); 31 | var fs = require('fs'); 32 | 33 | let easyListTxt = fs.readFileSync('./test/data/easylist.txt', 'utf-8'); 34 | let parsedFilterData = {}; 35 | let urlToCheck = 'http://static.tumblr.com/dhqhfum/WgAn39721/cfh_header_banner_v2.jpg'; 36 | 37 | // This is the site who's URLs are being checked, not the domain of the URL being checked. 38 | let currentPageDomain = 'slashdot.org'; 39 | 40 | ABPFilterParser.parse(easyListTxt, parsedFilterData); 41 | // ABPFilterParser.parse(someOtherListOfFilters, parsedFilterData); 42 | 43 | if (ABPFilterParser.matches(parsedFilterData, urlToCheck, { 44 | domain: currentPageDomain, 45 | elementTypeMaskMap: ABPFilterParser.elementTypes.SCRIPT, 46 | })) { 47 | console.log('You should block this URL!'); 48 | } else { 49 | console.log('You should NOT block this URL!'); 50 | } 51 | ``` 52 | 53 | ## Secondary APIs 54 | 55 | You probably won't need these directly, they are used by the primary API above. 56 | 57 | - parseDomains 58 | - parseOptions 59 | - parseHTMLFilter 60 | - parseFilter 61 | - matchesFilter 62 | -------------------------------------------------------------------------------- /benchmark/benchmark.js: -------------------------------------------------------------------------------- 1 | import testData from './test-data-1.js'; 2 | import {elementTypeMaskMap, parse, matches} from '../abp-filter-parser.js'; 3 | import fs from 'fs'; 4 | 5 | function getElementType(nsContentPolicyType) { 6 | if (!contentTypeMap.has(nsContentPolicyType)) { 7 | return 'other'; 8 | } 9 | return contentTypeMap.get(nsContentPolicyType); 10 | } 11 | 12 | var elapsed_time = function(start, note){ 13 | var precision = 3; // 3 decimal places 14 | var elapsed = process.hrtime(start)[1] / 1000000; // divide by a million to get nano to milli 15 | console.log(process.hrtime(start)[0] + " s, " + elapsed.toFixed(precision) + " ms - " + note); // print message + time 16 | start = process.hrtime(); // reset the timer 17 | } 18 | 19 | fs.readFile('./test/data/easylist.txt', 'utf8', function (err, data) { 20 | if (err) { 21 | return console.log(err); 22 | } 23 | let parserData = {}; 24 | let cachedInputData = {}; 25 | parse(data, parserData); 26 | // Num lines minus (num empty lines + num comment lines) 27 | var start = process.hrtime(); 28 | testData.forEach(([url, contentType, domain]) => { 29 | matches(parserData, url, { 30 | domain, 31 | elementTypeMask: elementTypeMaskMap.get(contentType), 32 | }, cachedInputData); 33 | }); 34 | elapsed_time(start, 'done'); 35 | }); 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /benchmark/test-data-1.js: -------------------------------------------------------------------------------- 1 | // URLs tested by navigating slashdot, runnersworld, and nbcnews 2 | export default [ 3 | ['http://a.fsdn.com/sd/classic.css?release_20150701c', 4, 'slashdot.org'], 4 | ['http://a.fsdn.com/sd/css/app.css?release_20150701c', 4, 'slashdot.org'], 5 | ['http://a.fsdn.com/sd/autorefresh-query.js?release_20150701c', 2, 'slashdot.org'], 6 | ['http://a.fsdn.com/sd/all-minified.js?release_20150701c', 2, 'slashdot.org'], 7 | ['http://player.ooyala.com/v3/85d52cbb9c924733934b1880e9cde580', 2, 'slashdot.org'], 8 | ['http://s.ntv.io/serve/load.js', 2, 'slashdot.org'], 9 | ['http://a.fsdn.com/sd/topics/transportation_64.png', 3, 'slashdot.org'], 10 | ['http://a.fsdn.com/sd/articles/15/07/01/1922241-1.jpg', 3, 'slashdot.org'], 11 | ['http://a.fsdn.com/sd/topics/education_64.png', 3, 'slashdot.org'], 12 | ['http://a.fsdn.com/sd/topics/google_64.png', 3, 'slashdot.org'], 13 | ['http://a.fsdn.com/sd/topics/programming_64.png', 3, 'slashdot.org'], 14 | ['http://a.fsdn.com/sd/classic.css?release_20150701c', 4, 'slashdot.org'], 15 | ['http://a.fsdn.com/sd/css/app.css?release_20150701c', 4, 'slashdot.org'], 16 | ['http://a.fsdn.com/sd/autorefresh-query.js?release_20150701c', 2, 'slashdot.org'], 17 | ['http://a.fsdn.com/sd/articles/15/07/01/141208-1-thumblg.jpg', 3, 'slashdot.org'], 18 | ['http://a.fsdn.com/sd/articles/15/06/30/141210-1-thumblg.jpg', 3, 'slashdot.org'], 19 | ['http://a.fsdn.com/sd/articles/15/06/19/141210-1-thumblg.jpg', 3, 'slashdot.org'], 20 | ['http://a.fsdn.com/sd/articles/15/06/11/141208-1-thumblg.jpg', 3, 'slashdot.org'], 21 | ['http://a.fsdn.com/sd/articles/15/06/18/141208-1-thumblg.jpg', 3, 'slashdot.org'], 22 | ['http://a.fsdn.com/sd/articles/15/06/09/141206-1-thumblg.jpg', 3, 'slashdot.org'], 23 | ['http://a.fsdn.com/sd/articles/15/06/18/141209-1-thumblg.jpg', 3, 'slashdot.org'], 24 | ['http://a.fsdn.com/sd/articles/15/06/18/141210-1-thumblg.jpg', 3, 'slashdot.org'], 25 | ['http://a.fsdn.com/sd/articles/15/06/23/141208-1-thumblg.jpg', 3, 'slashdot.org'], 26 | ['http://a.fsdn.com/sd/articles/15/06/06/141208-1-thumblg.jpg', 3, 'slashdot.org'], 27 | ['http://a.fsdn.com/sd/articles/15/06/12/141209-1-thumblg.jpg', 3, 'slashdot.org'], 28 | ['http://a.fsdn.com/sd/articles/15/06/26/141208-1-thumblg.jpg', 3, 'slashdot.org'], 29 | ['http://a.fsdn.com/sd/articles/15/06/20/141208-1-thumblg.jpg', 3, 'slashdot.org'], 30 | ['http://a.fsdn.com/sd/articles/15/06/29/141209-1-thumblg.jpg', 3, 'slashdot.org'], 31 | ['http://a.fsdn.com/sd/articles/15/06/27/141208-1-thumblg.jpg', 3, 'slashdot.org'], 32 | ['http://a.fsdn.com/sd/topics/classicgames_64.png', 3, 'slashdot.org'], 33 | ['http://a.fsdn.com/sd/topics/java_64.png', 3, 'slashdot.org'], 34 | ['http://a.fsdn.com/sd/topics/nasa_64.png', 3, 'slashdot.org'], 35 | ['http://a.fsdn.com/sd/topics/storage_64.png', 3, 'slashdot.org'], 36 | ['http://a.fsdn.com/sd/topics/money_64.png', 3, 'slashdot.org'], 37 | ['http://a.fsdn.com/sd/topics/os_64.png', 3, 'slashdot.org'], 38 | ['http://a.fsdn.com/sd/topics/security_64.png', 3, 'slashdot.org'], 39 | ['http://a.fsdn.com/sd/topics/verizon_64.png', 3, 'slashdot.org'], 40 | ['http://a.fsdn.com/sd/topics/encryption_64.png', 3, 'slashdot.org'], 41 | ['http://a.fsdn.com/sd/dice_logo.png', 3, 'slashdot.org'], 42 | ['http://www.googleadservices.com/pagead/conversion.js', 2, 'slashdot.org'], 43 | ['http://a.fsdn.com/sd/all-minified.js?release_20150701c', 2, 'slashdot.org'], 44 | ['http://widget-cdn.rpxnow.com/js/lib/login.slashdot.org/engage.js', 2, 'slashdot.org'], 45 | ['http://widget-cdn.rpxnow.com/js/lib/login.slashdot.org/widget.js', 2, 'slashdot.org'], 46 | ['http://cdn.taboola.com/libtrc/slashdot/loader.js', 2, 'slashdot.org'], 47 | ['http://player.ooyala.com/v3/85d52cbb9c924733934b1880e9cde580', 2, 'slashdot.org'], 48 | ['http://s.ntv.io/serve/load.js', 2, 'slashdot.org'], 49 | ['http://www.googletagservices.com/tag/js/gpt.js', 2, 'slashdot.org'], 50 | ['http://www.google-analytics.com/ga.js', 2, 'slashdot.org'], 51 | ['http://a.fsdn.com/sd/topics/transportation_64.png', 3, 'slashdot.org'], 52 | ['http://a.fsdn.com/sd/logo_w_l.png', 3, 'slashdot.org'], 53 | ['https://s3-us-west-2.amazonaws.com/s.cdpn.io/33124/slashdot_favicon_white.png', 3, 'slashdot.org'], 54 | ['http://a.fsdn.com/sd/classic/img/glyphish-icons-16.png', 3, 'slashdot.org'], 55 | ['http://a.fsdn.com/sd/font/sdicon.woff?release_20150630', 14, 'slashdot.org'], 56 | ['http://a.fsdn.com/sd/topics/transportation_64.png', 3, 'slashdot.org'], 57 | ['http://a.fsdn.com/sd/articles/15/07/01/1922241-1.jpg', 3, 'slashdot.org'], 58 | ['http://a.fsdn.com/sd/articles/15/07/01/1922241-1.jpg', 3, 'slashdot.org'], 59 | ['http://a.fsdn.com/sd/topics/education_64.png', 3, 'slashdot.org'], 60 | ['http://a.fsdn.com/sd/topics/education_64.png', 3, 'slashdot.org'], 61 | ['http://a.fsdn.com/sd/topics/google_64.png', 3, 'slashdot.org'], 62 | ['http://a.fsdn.com/sd/topics/google_64.png', 3, 'slashdot.org'], 63 | ['http://a.fsdn.com/sd/topics/education_64.png', 3, 'slashdot.org'], 64 | ['http://a.fsdn.com/sd/topics/education_64.png', 3, 'slashdot.org'], 65 | ['http://a.fsdn.com/sd/topics/programming_64.png', 3, 'slashdot.org'], 66 | ['http://a.fsdn.com/sd/topics/programming_64.png', 3, 'slashdot.org'], 67 | ['http://a.fsdn.com/sd/articles/15/07/01/141208-1-thumblg.jpg', 3, 'slashdot.org'], 68 | ['http://a.fsdn.com/sd/articles/15/07/01/141208-1-thumblg.jpg', 3, 'slashdot.org'], 69 | ['http://a.fsdn.com/sd/articles/15/06/30/141210-1-thumblg.jpg', 3, 'slashdot.org'], 70 | ['http://a.fsdn.com/sd/articles/15/06/30/141210-1-thumblg.jpg', 3, 'slashdot.org'], 71 | ['http://a.fsdn.com/sd/articles/15/06/19/141210-1-thumblg.jpg', 3, 'slashdot.org'], 72 | ['http://a.fsdn.com/sd/articles/15/06/19/141210-1-thumblg.jpg', 3, 'slashdot.org'], 73 | ['http://a.fsdn.com/sd/articles/15/06/11/141208-1-thumblg.jpg', 3, 'slashdot.org'], 74 | ['http://a.fsdn.com/sd/articles/15/06/11/141208-1-thumblg.jpg', 3, 'slashdot.org'], 75 | ['http://a.fsdn.com/sd/articles/15/06/18/141208-1-thumblg.jpg', 3, 'slashdot.org'], 76 | ['http://a.fsdn.com/sd/articles/15/06/18/141208-1-thumblg.jpg', 3, 'slashdot.org'], 77 | ['http://a.fsdn.com/sd/articles/15/06/09/141206-1-thumblg.jpg', 3, 'slashdot.org'], 78 | ['http://a.fsdn.com/sd/articles/15/06/09/141206-1-thumblg.jpg', 3, 'slashdot.org'], 79 | ['http://a.fsdn.com/sd/articles/15/06/18/141209-1-thumblg.jpg', 3, 'slashdot.org'], 80 | ['http://a.fsdn.com/sd/articles/15/06/18/141209-1-thumblg.jpg', 3, 'slashdot.org'], 81 | ['http://a.fsdn.com/sd/articles/15/06/18/141210-1-thumblg.jpg', 3, 'slashdot.org'], 82 | ['http://a.fsdn.com/sd/articles/15/06/18/141210-1-thumblg.jpg', 3, 'slashdot.org'], 83 | ['http://a.fsdn.com/sd/articles/15/06/23/141208-1-thumblg.jpg', 3, 'slashdot.org'], 84 | ['http://a.fsdn.com/sd/articles/15/06/23/141208-1-thumblg.jpg', 3, 'slashdot.org'], 85 | ['http://a.fsdn.com/sd/articles/15/06/06/141208-1-thumblg.jpg', 3, 'slashdot.org'], 86 | ['http://a.fsdn.com/sd/articles/15/06/06/141208-1-thumblg.jpg', 3, 'slashdot.org'], 87 | ['http://a.fsdn.com/sd/articles/15/06/12/141209-1-thumblg.jpg', 3, 'slashdot.org'], 88 | ['http://a.fsdn.com/sd/articles/15/06/12/141209-1-thumblg.jpg', 3, 'slashdot.org'], 89 | ['http://a.fsdn.com/sd/articles/15/06/26/141208-1-thumblg.jpg', 3, 'slashdot.org'], 90 | ['http://a.fsdn.com/sd/articles/15/06/26/141208-1-thumblg.jpg', 3, 'slashdot.org'], 91 | ['http://a.fsdn.com/sd/articles/15/06/20/141208-1-thumblg.jpg', 3, 'slashdot.org'], 92 | ['http://a.fsdn.com/sd/articles/15/06/20/141208-1-thumblg.jpg', 3, 'slashdot.org'], 93 | ['http://a.fsdn.com/sd/articles/15/06/29/141209-1-thumblg.jpg', 3, 'slashdot.org'], 94 | ['http://a.fsdn.com/sd/articles/15/06/29/141209-1-thumblg.jpg', 3, 'slashdot.org'], 95 | ['http://a.fsdn.com/sd/articles/15/06/27/141208-1-thumblg.jpg', 3, 'slashdot.org'], 96 | ['http://a.fsdn.com/sd/articles/15/06/27/141208-1-thumblg.jpg', 3, 'slashdot.org'], 97 | ['http://a.fsdn.com/sd/topics/classicgames_64.png', 3, 'slashdot.org'], 98 | ['http://a.fsdn.com/sd/topics/classicgames_64.png', 3, 'slashdot.org'], 99 | ['http://a.fsdn.com/sd/topics/java_64.png', 3, 'slashdot.org'], 100 | ['http://a.fsdn.com/sd/topics/java_64.png', 3, 'slashdot.org'], 101 | ['http://a.fsdn.com/sd/topics/nasa_64.png', 3, 'slashdot.org'], 102 | ['http://a.fsdn.com/sd/topics/nasa_64.png', 3, 'slashdot.org'], 103 | ['http://a.fsdn.com/sd/topics/storage_64.png', 3, 'slashdot.org'], 104 | ['http://a.fsdn.com/sd/topics/storage_64.png', 3, 'slashdot.org'], 105 | ['http://a.fsdn.com/sd/topics/money_64.png', 3, 'slashdot.org'], 106 | ['http://a.fsdn.com/sd/topics/money_64.png', 3, 'slashdot.org'], 107 | ['http://a.fsdn.com/sd/topics/education_64.png', 3, 'slashdot.org'], 108 | ['http://a.fsdn.com/sd/topics/education_64.png', 3, 'slashdot.org'], 109 | ['http://a.fsdn.com/sd/topics/os_64.png', 3, 'slashdot.org'], 110 | ['http://a.fsdn.com/sd/topics/os_64.png', 3, 'slashdot.org'], 111 | ['http://a.fsdn.com/sd/topics/security_64.png', 3, 'slashdot.org'], 112 | ['http://a.fsdn.com/sd/topics/security_64.png', 3, 'slashdot.org'], 113 | ['http://a.fsdn.com/sd/topics/verizon_64.png', 3, 'slashdot.org'], 114 | ['http://a.fsdn.com/sd/topics/verizon_64.png', 3, 'slashdot.org'], 115 | ['http://a.fsdn.com/sd/topics/encryption_64.png', 3, 'slashdot.org'], 116 | ['http://a.fsdn.com/sd/topics/encryption_64.png', 3, 'slashdot.org'], 117 | ['http://a.fsdn.com/sd/dice_logo.png', 3, 'slashdot.org'], 118 | ['http://a.fsdn.com/sd/dice_logo.png', 3, 'slashdot.org'], 119 | ['http://stats.dice.com/b/ss/diceprod/1/display/7928896839733065?mtp=oslsc&mtss=2592000&ns=diceinc&v70=SDWDG&ce=UTF-8', 3, 'slashdot.org'], 120 | ['http://b.scorecardresearch.com/b?c1=2&c2=6035546&rn=0.962229247708866&c7=http%3A%2F%2Fslashdot.org%2F&c3=&c4=&c5=&c6=&c10=&c15=&c16=&c8=Slashdot%20(16)&c9=&cv=1.7', 3, 'slashdot.org'], 121 | ['http://www.googleadservices.com/pagead/conversion.js', 2, 'slashdot.org'], 122 | ['http://a.fsdn.com/sd/logo_w_l.png', 3, 'slashdot.org'], 123 | ['http://a.fsdn.com/sd/logo_w_l.png', 3, 'slashdot.org'], 124 | ['http://a.fsdn.com/sd/sf-logo.png', 3, 'slashdot.org'], 125 | ['http://googleads.g.doubleclick.net/pagead/viewthroughconversion/1002083962/?random=1435784789308&cv=7&fst=1435784789308&num=1&fmt=1&label=G_uGCOaBlAQQ-qzq3QM&guid=ON&u_h=1050&u_w=1680&u_ah=982&u_aw=1680&u_cd=24&u_his=1&u_tz=-240&u_java=false&u_nplug=0&u_nmime=0&frm=0&url=http%3A//slashdot.org/&vis=1', 7, 'slashdot.org'], 126 | ['http://slashdot.org/images/js.gif?221', 3, 'slashdot.org'], 127 | ['http://adserve.postrelease.com/serve/trigger/1435784789687.js?prx_url=http%3A%2F%2Fslashdot.org%2F', 2, 'slashdot.org'], 128 | ['http://a.fsdn.com/sd/articles/15/07/01/1922241-1-thumblg.jpg', 3, 'slashdot.org'], 129 | ['http://a.fsdn.com/sd/articles/15/06/30/1928230-1-thumblg.jpg', 3, 'slashdot.org'], 130 | ['http://a.fsdn.com/sd/articles/15/06/25/1920234-1-thumblg.jpg', 3, 'slashdot.org'], 131 | ['http://a.fsdn.com/sd/articles/15/06/22/1736206-1-thumblg.jpg', 3, 'slashdot.org'], 132 | ['http://a.fsdn.com/sd/images/SDvideoicon28x28.png', 3, 'slashdot.org'], 133 | ['http://player.ooyala.com/ooyala_storage.html', 7, 'slashdot.org'], 134 | ['http://widget-cdn.rpxnow.com/translations/share/en', 2, 'slashdot.org'], 135 | ['http://widget.perfectmarket.com/slashdot/load.js', 2, 'slashdot.org'], 136 | ['http://cdn.taboola.com/libtrc/impl.161-RELEASE.js', 2, 'slashdot.org'], 137 | ['http://netstorage.taboola.com/libtrc/common/cross-check.js', 2, 'slashdot.org'], 138 | ['http://b.scorecardresearch.com/beacon.js', 2, 'slashdot.org'], 139 | ['http://www.google-analytics.com/__utm.gif?utmwv=5.6.4&utms=3&utmn=83445640&utmhn=slashdot.org&utme=8(User%20Type*Page)9(Anon*index2)&utmcs=UTF-8&utmsr=1680x1050&utmvp=1058x515&utmsc=24-bit&utmul=en-us&utmje=0&utmfl=-&utmdt=Slashdot%20(16)&utmhid=1672007837&utmr=-&utmp=%2F&utmht=1435784792133&utmac=UA-36136016-1&utmcc=__utma%3D57409013.2025875018.1435695346.1435781980.1435784658.5%3B%2B__utmz%3D57409013.1435695346.1.1.utmcsr%3D(direct)%7Cutmccn%3D(direct)%7Cutmcmd%3D(none)%3B&utmjid=&utmmt=1&utmu=qRAgACAAAAAAAAAAAAAAAAAE~', 3, 'slashdot.org'], 140 | ['http://www.google-analytics.com/__utm.gif?utmwv=5.6.4&utms=4&utmn=515570410&utmhn=slashdot.org&utme=8(User%20Type*Page)9(Anon*index2)&utmcs=UTF-8&utmsr=1680x1050&utmvp=1058x515&utmsc=24-bit&utmul=en-us&utmje=0&utmfl=-&utmdt=Slashdot%20(16)&utmhid=1672007837&utmr=-&utmp=%2F&utmht=1435784792360&utmac=UA-32013-5&utmcc=__utma%3D57409013.2025875018.1435695346.1435781980.1435784658.5%3B%2B__utmz%3D57409013.1435695346.1.1.utmcsr%3D(direct)%7Cutmccn%3D(direct)%7Cutmcmd%3D(none)%3B&utmjid=&utmmt=1&utmu=qRAgACAAAAAAAAAAAAAAAAAE~', 3, 'slashdot.org'], 141 | ['http://partner.googleadservices.com/gpt/pubads_impl_65.js', 2, 'slashdot.org'], 142 | ['http://tpc.googlesyndication.com/safeframe/1-0-2/html/container.html', 7, 'slashdot.org'], 143 | ['http://www.googletagservices.com/tag/js/check_359604.js', 2, 'slashdot.org'], 144 | ['http://widget-cdn.rpxnow.com/manifest/login:share?version=1.105.0_widgets_465', 2, 'slashdot.org'], 145 | ['http://widget.perfectmarket.com/slashdot/pmk-201516004.8.js', 2, 'slashdot.org'], 146 | ['http://b.scorecardresearch.com/b?c1=7&c2=13739933&c3=20121515121&ns__t=1435784793507&ns_c=UTF-8&c8=Slashdot%20(16)&c7=http%3A%2F%2Fslashdot.org%2F&c9=', 3, 'slashdot.org'], 147 | ['http://cdn.quilt.janrain.com/2.2.19/providers.css', 4, 'slashdot.org'], 148 | ['http://cdn.rpxnow.com/rel/img/17c96fc4b9c8464d1c95cd785dd3120b.png', 3, 'slashdot.org'], 149 | ['http://widget.perfectmarket.com/slashdot/get/?v=201516004.8&vp=20000&ib=false&pu=http%3A%2F%2Fslashdot.org&ph=Slashdot%20(16)&pr=&t=%7B%22n%22%3A%22home02_opt%22%2C%22v%22%3A1%7D', 2, 'slashdot.org'], 150 | ['http://widget.perfectmarket.com/slashdot/pmk-201516004.8.js', 2, 'slashdot.org'], 151 | ['http://www.google-analytics.com/analytics.js', 2, 'slashdot.org'], 152 | ['http://b.scorecardresearch.com/beacon.js', 2, 'slashdot.org'], 153 | ['http://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js', 2, 'slashdot.org'], 154 | ['http://widget.perfectmarket.com/slashdot/view/871535eb9d61b8fdd1abbe15a09cf598?pu=http%3A%2F%2Fslashdot.org&ph=Slashdot%20(16)&ib=false&t=%7B%22n%22%3A%22home02_opt%22%2C%22v%22%3A1%7D&ov=%7B%7D&sr=1&v=201516004.8&vp=20000', 3, 'slashdot.org'], 155 | ['http://www.google-analytics.com/collect?v=1&_v=j37&a=1672007837&t=pageview&_s=1&dl=http%3A%2F%2Fslashdot.org&ul=en-us&de=UTF-8&dt=Slashdot%20(16)&sd=24-bit&sr=1680x1050&vp=1058x515&je=0&_utma=57409013.2025875018.1435695346.1435781980.1435784658.5&_utmz=57409013.1435695346.1.1.utmcsr%3D(direct)%7Cutmccn%3D(direct)%7Cutmcmd%3D(none)&_utmht=1435784795545&_u=QACCAEABI~&jid=&cid=2025875018.1435695346&tid=UA-45624874-26&cd1=Template-ad-home02_opt&cd2=other&z=814120879', 3, 'slashdot.org'], 156 | ['http://www.google-analytics.com/collect?v=1&_v=j37&a=1672007837&t=event&_s=2&dl=http%3A%2F%2Fslashdot.org%2F&ul=en-us&de=UTF-8&dt=Slashdot%20(16)&sd=24-bit&sr=1680x1050&vp=1058x515&je=0&ec=home02_opt&ea=pageRefreshed&el=http%3A%2F%2Fslashdot.org&_utma=57409013.2025875018.1435695346.1435781980.1435784658.5&_utmz=57409013.1435695346.1.1.utmcsr%3D(direct)%7Cutmccn%3D(direct)%7Cutmcmd%3D(none)&_utmht=1435784795730&_u=QACCAEABI~&jid=&cid=2025875018.1435695346&tid=UA-45624874-26&cd1=Template-ad-home02_opt&cd2=other&z=1080821549', 3, 'slashdot.org'], 157 | ['http://www.google-analytics.com/collect?v=1&_v=j37&a=1672007837&t=event&_s=3&dl=http%3A%2F%2Fslashdot.org%2F&ul=en-us&de=UTF-8&dt=Slashdot%20(16)&sd=24-bit&sr=1680x1050&vp=1058x515&je=0&ec=home02_opt&ea=pageviewWithAds&el=http%3A%2F%2Fslashdot.org&_utma=57409013.2025875018.1435695346.1435781980.1435784658.5&_utmz=57409013.1435695346.1.1.utmcsr%3D(direct)%7Cutmccn%3D(direct)%7Cutmcmd%3D(none)&_utmht=1435784795952&_u=QACCAEABI~&jid=&cid=2025875018.1435695346&tid=UA-45624874-26&cd1=Template-ad-home02_opt&cd2=other&z=2028306543', 3, 'slashdot.org'], 158 | ['http://www.nbcnews.com/', 6, 'slashdot.org'], 159 | ['http://nodeassets.nbcnews.com/styles/fc21d61b.main.css', 4, 'www.nbcnews.com'], 160 | ['http://nodeassets.nbcnews.com/styles/fc21d61b.main.css', 4, 'www.nbcnews.com'], 161 | ['http://sslnodeassets.nbcnews.com/images/non-rev/nbcnews-logo.svg', 3, 'www.nbcnews.com'], 162 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 163 | ['http://nodeassets.nbcnews.com/images/022272a4.nightly-news-logo-mark.png', 3, 'www.nbcnews.com'], 164 | ['http://nodeassets.nbcnews.com/scripts/vendor/e13156bf.modernizr.js', 2, 'www.nbcnews.com'], 165 | ['http://nodeassets.nbcnews.com/scripts/6f1cab75.vendor.js', 2, 'www.nbcnews.com'], 166 | ['http://assets.adobedtm.com/cd771b0aa897f931a306d7ab6af0d448836b5fd1/satelliteLib-d7647ef38f862ffb17587d65d0a95182256c1765.js', 2, 'www.nbcnews.com'], 167 | ['http://nvcdn.nbcnews.com/_elliott/jenga?widgets=newsletter,zinger2', 2, 'www.nbcnews.com'], 168 | ['http://nodeassets.nbcnews.com/scripts/f2bfebfe.main.js', 2, 'www.nbcnews.com'], 169 | ['http://nodeassets.nbcnews.com/styles/658e3d49.fonts.css', 4, 'www.nbcnews.com'], 170 | ['http://nodeassets.nbcnews.com/styles/658e3d49.fonts.css', 4, 'www.nbcnews.com'], 171 | ['http://netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.min.css', 4, 'www.nbcnews.com'], 172 | ['http://netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.min.css', 4, 'www.nbcnews.com'], 173 | ['http://sslnodeassets.nbcnews.com/images/non-rev/nbcnews-logo.svg', 3, 'www.nbcnews.com'], 174 | ['http://sslnodeassets.nbcnews.com/images/non-rev/nbcnews-logo.svg', 3, 'www.nbcnews.com'], 175 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 176 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 177 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 178 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 179 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 180 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 181 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 182 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 183 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 184 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 185 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 186 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 187 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 188 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 189 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 190 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 191 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 192 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 193 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 194 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 195 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 196 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 197 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 198 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 199 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 200 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 201 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 202 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 203 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 204 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 205 | ['http://www.runnersworld.com/gear-check/ask-the-gear-guy-how-to-avoid-soggy-summer-runs', 6, ''], 206 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 207 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 208 | ['https://d7v0k4dt27zlp.cloudfront.net/assets/capture_client.js', 2, 'www.runnersworld.com'], 209 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 210 | ['https://d7v0k4dt27zlp.cloudfront.net/assets/capture_client.js', 2, 'www.runnersworld.com'], 211 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 212 | ['http://www.runnersworld.com/sites/runnersworld.com/files/css/css_lQaZfjVpwP_oGNqdtWCSpJT1EMqXdMiU84ekLLxQnc4.css', 4, 'www.runnersworld.com'], 213 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 214 | ['http://www.runnersworld.com/sites/runnersworld.com/files/css/css_8zNaO6tqngFaqjcQnVuHUYbjsm62joTz_t9s8nsUaQ0.css', 4, 'www.runnersworld.com'], 215 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 216 | ['http://www.runnersworld.com/sites/runnersworld.com/files/css/css_91Ppbbz0JIET0gxqOY12ot_cPgxIqTSz9H7aG4K1Mw0.css', 4, 'www.runnersworld.com'], 217 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 218 | ['http://www.runnersworld.com/sites/runnersworld.com/files/css/css_hbwIh0axB8EBHtnHQ0ukM0vagQ6L3s65Cu7-H4oORZI.css', 4, 'www.runnersworld.com'], 219 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 220 | ['http://fonts.googleapis.com/css?family=Source+Sans+Pro:400,700,400italic,600italic&nqi1vf', 4, 'www.runnersworld.com'], 221 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 222 | ['http://fonts.googleapis.com/css?family=Merriweather:400italic&nqi1vf', 4, 'www.runnersworld.com'], 223 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 224 | ['http://www.runnersworld.com/sites/runnersworld.com/files/css/css_wW2ox2QW-Z8lguzUz6Two9KFGe-1s2Ave5QpF9EIn-w.css', 4, 'www.runnersworld.com'], 225 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 226 | ['http://www.runnersworld.com/sites/all/modules/custom/zeus_slideshow/css/style.css', 4, 'www.runnersworld.com'], 227 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 228 | ['http://www.runnersworld.com/sites/runnersworld.com/files/css/css_qnyob65zexTxI8TLm3zfT8dqcyxeeJOFalCUvDJFtK8.css', 4, 'www.runnersworld.com'], 229 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 230 | ['http://www.runnersworld.com/sites/all/modules/custom/zeus_load_more/css/styles.css', 4, 'www.runnersworld.com'], 231 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 232 | ['http://www.runnersworld.com/sites/runnersworld.com/files/js/js_2_3IrLddJ-vKJcG4GVxriipYfgaHndp7dEFTpEsNpME.js', 2, 'www.runnersworld.com'], 233 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 234 | ['http://www.googletagservices.com/tag/js/gpt.js', 2, 'www.runnersworld.com'], 235 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 236 | ['http://www.runnersworld.com/sites/runnersworld.com/files/js/js_VrPOApmBCYncxwBtQNEHn0sZmPxIABQL-bLuU_CLx2E.js', 2, 'www.runnersworld.com'], 237 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 238 | ['http://www.runnersworld.com/sites/all/modules/custom/zeus_slideshow/js/jquery.bxslider.min.js', 2, 'www.runnersworld.com'], 239 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 240 | ['http://www.runnersworld.com/sites/runnersworld.com/files/js/js_85YDWK3ydw1gXnxzx3Opz_l1e2roWDAUMQpeAPbRzBw.js', 2, 'www.runnersworld.com'], 241 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 242 | ['http://www.runnersworld.com/sites/runnersworld.com/files/js/js_iSM2u2hnJi9_aoaRQFqHE4h9kZiOUpIS8KY_U_U_BGc.js', 2, 'www.runnersworld.com'], 243 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 244 | ['http://www.runnersworld.com/sites/runnersworld.com/files/js/js_wiyc3l31Z1Ek--sbWOwQzv49-MAAHo8zxJCtk1562uc.js', 2, 'www.runnersworld.com'], 245 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 246 | ['http://www.runnersworld.com/sites/all/modules/custom/janrain_capture/janrain_capture.js?nqi1vf', 2, 'www.runnersworld.com'], 247 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 248 | ['http://www.runnersworld.com/sites/runnersworld.com/files/js/js_rzOI-9lPPLHxFryA1qnnhpH6KB-HmpV6chQisjxakdI.js', 2, 'www.runnersworld.com'], 249 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 250 | ['http://www.runnersworld.com/sites/runnersworld.com/files/js/js_HCyecgCoUChOb3z2LNw1i2vx_HMurnjXjsWHm73h1HI.js', 2, 'www.runnersworld.com'], 251 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 252 | ['http://assets.adobedtm.com/6f743006a41bd9090cd6c6b7dfa16b2cbed9c289/satelliteLib-9ef46ccbdeecaf248ce80c4092b18144a304f95a.js', 2, 'www.runnersworld.com'], 253 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 254 | ['http://www.runnersworld.com/sites/runnersworld.com/files/js/js_D_f8RrrnYw-cmhibNuW2SMpsQD93ez4WEIIeDpGOq_0.js', 2, 'www.runnersworld.com'], 255 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 256 | ['http://admin.brightcove.com/js/BrightcoveExperiences.js', 2, 'www.runnersworld.com'], 257 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 258 | ['http://www.runnersworld.com/sites/runnersworld.com/files/js/js_LuwuSFEdYqw9yGG2dZ7wr8oNZxuelq-pJVr87qO-IHk.js', 2, 'www.runnersworld.com'], 259 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 260 | ['http://www.runnersworld.com/sites/all/modules/custom/zeus_sharebar/zeus_sharebar_subscribe_miniform.js', 2, 'www.runnersworld.com'], 261 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 262 | ['http://www.runnersworld.com/sites/runnersworld.com/files/js/js_-rSlAbwhdSJE2178kj-0jsS6YhvycGsFDhzDTFvQTWU.js', 2, 'www.runnersworld.com'], 263 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 264 | ['http://www.runnersworld.com/sites/all/modules/custom/zeus_slideshow/js/scripts.js', 2, 'www.runnersworld.com'], 265 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 266 | ['http://www.runnersworld.com/sites/runnersworld.com/themes/runnersworld/logo.png', 3, 'www.runnersworld.com'], 267 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 268 | ['http://www.runnersworld.com/sites/all/modules/custom/lazyloader/image_placeholder.gif', 3, 'www.runnersworld.com'], 269 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 270 | ['http://fonts.googleapis.com/css?family=Montserrat:400,700', 4, 'www.runnersworld.com'], 271 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 272 | ['http://fonts.googleapis.com/css?family=Abril+Fatface', 4, 'www.runnersworld.com'], 273 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 274 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 275 | ['http://fonts.googleapis.com/css?family=Roboto+Condensed:700', 4, 'www.runnersworld.com'], 276 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 277 | ['http://fonts.googleapis.com/css?family=Roboto:400,700', 4, 'www.runnersworld.com'], 278 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 279 | ['http://fonts.googleapis.com/css?family=Montserrat', 4, 'www.runnersworld.com'], 280 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 281 | ['http://rpxnow.com/load/login.runnersworld.com', 2, 'www.runnersworld.com'], 282 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 283 | ['http://www.runnersworld.com/sites/runnersworld.com/files/css/css_lQaZfjVpwP_oGNqdtWCSpJT1EMqXdMiU84ekLLxQnc4.css', 4, 'www.runnersworld.com'], 284 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 285 | ['http://www.runnersworld.com/sites/runnersworld.com/files/css/css_8zNaO6tqngFaqjcQnVuHUYbjsm62joTz_t9s8nsUaQ0.css', 4, 'www.runnersworld.com'], 286 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 287 | ['http://www.runnersworld.com/sites/runnersworld.com/files/css/css_91Ppbbz0JIET0gxqOY12ot_cPgxIqTSz9H7aG4K1Mw0.css', 4, 'www.runnersworld.com'], 288 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 289 | ['http://www.runnersworld.com/sites/runnersworld.com/files/css/css_hbwIh0axB8EBHtnHQ0ukM0vagQ6L3s65Cu7-H4oORZI.css', 4, 'www.runnersworld.com'], 290 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 291 | ['http://fonts.googleapis.com/css?family=Source+Sans+Pro:400,700,400italic,600italic&nqi1vf', 4, 'www.runnersworld.com'], 292 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 293 | ['http://fonts.googleapis.com/css?family=Merriweather:400italic&nqi1vf', 4, 'www.runnersworld.com'], 294 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 295 | ['http://www.runnersworld.com/sites/runnersworld.com/files/css/css_wW2ox2QW-Z8lguzUz6Two9KFGe-1s2Ave5QpF9EIn-w.css', 4, 'www.runnersworld.com'], 296 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 297 | ['http://www.runnersworld.com/sites/all/modules/custom/zeus_slideshow/css/style.css', 4, 'www.runnersworld.com'], 298 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 299 | ['http://www.runnersworld.com/sites/runnersworld.com/files/css/css_qnyob65zexTxI8TLm3zfT8dqcyxeeJOFalCUvDJFtK8.css', 4, 'www.runnersworld.com'], 300 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 301 | ['http://www.runnersworld.com/sites/all/modules/custom/zeus_load_more/css/styles.css', 4, 'www.runnersworld.com'], 302 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 303 | ['http://widget-cdn.rpxnow.com/manifest/capture:login?version=1.105.0_widgets_465', 2, 'www.runnersworld.com'], 304 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 305 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 306 | ['http://www.runnersworld.com/sites/runnersworld.com/files/js/js_2_3IrLddJ-vKJcG4GVxriipYfgaHndp7dEFTpEsNpME.js', 2, 'www.runnersworld.com'], 307 | ['http://www.googletagservices.com/tag/js/gpt.js', 2, 'www.runnersworld.com'], 308 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 309 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 310 | ['http://tpc.googlesyndication.com/safeframe/1-0-2/html/container.html', 7, 'www.runnersworld.com'], 311 | ['http://www.googletagservices.com/tag/js/check_359604.js', 2, 'www.runnersworld.com'], 312 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 313 | ['http://cdn.yldbt.com/js/yieldbot.intent.js', 2, 'www.runnersworld.com'], 314 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 315 | ['http://www.runnersworld.com/sites/runnersworld.com/files/js/js_VrPOApmBCYncxwBtQNEHn0sZmPxIABQL-bLuU_CLx2E.js', 2, 'www.runnersworld.com'], 316 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 317 | ['http://cdn.quilt.janrain.com/2.2.19/providers.css', 4, 'www.runnersworld.com'], 318 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 319 | ['http://www.runnersworld.com/sites/all/modules/custom/zeus_slideshow/js/jquery.bxslider.min.js', 2, 'www.runnersworld.com'], 320 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 321 | ['http://www.runnersworld.com/sites/runnersworld.com/files/js/js_85YDWK3ydw1gXnxzx3Opz_l1e2roWDAUMQpeAPbRzBw.js', 2, 'www.runnersworld.com'], 322 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 323 | ['http://www.runnersworld.com/sites/runnersworld.com/files/js/js_iSM2u2hnJi9_aoaRQFqHE4h9kZiOUpIS8KY_U_U_BGc.js', 2, 'www.runnersworld.com'], 324 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 325 | ['http://www.runnersworld.com/sites/runnersworld.com/files/js/js_wiyc3l31Z1Ek--sbWOwQzv49-MAAHo8zxJCtk1562uc.js', 2, 'www.runnersworld.com'], 326 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 327 | ['http://www.runnersworld.com/sites/all/modules/custom/janrain_capture/janrain_capture.js?nqi1vf', 2, 'www.runnersworld.com'], 328 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 329 | ['http://www.runnersworld.com/sites/runnersworld.com/files/js/js_rzOI-9lPPLHxFryA1qnnhpH6KB-HmpV6chQisjxakdI.js', 2, 'www.runnersworld.com'], 330 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 331 | ['http://partner.googleadservices.com/gpt/pubads_impl_65.js', 2, 'www.runnersworld.com'], 332 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 333 | ['http://www.runnersworld.com/sites/runnersworld.com/files/js/js_HCyecgCoUChOb3z2LNw1i2vx_HMurnjXjsWHm73h1HI.js', 2, 'www.runnersworld.com'], 334 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 335 | ['http://assets.adobedtm.com/6f743006a41bd9090cd6c6b7dfa16b2cbed9c289/satelliteLib-9ef46ccbdeecaf248ce80c4092b18144a304f95a.js', 2, 'www.runnersworld.com'], 336 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 337 | ['http://cdn.optimizely.com/js/2227100773.js', 2, 'www.runnersworld.com'], 338 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 339 | ['http://assets.adobedtm.com/6f743006a41bd9090cd6c6b7dfa16b2cbed9c289/scripts/satellite-53e0f51c49e9ca0dfb000312.js', 2, 'www.runnersworld.com'], 340 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 341 | ['http://assets.adobedtm.com/6f743006a41bd9090cd6c6b7dfa16b2cbed9c289/scripts/satellite-5530145f333536624d8c0500.html', 7, 'www.runnersworld.com'], 342 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 343 | ['http://bounceexchange.com/tag/869/i.js', 2, 'www.runnersworld.com'], 344 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 345 | ['http://www.runnersworld.com/sites/runnersworld.com/files/js/js_D_f8RrrnYw-cmhibNuW2SMpsQD93ez4WEIIeDpGOq_0.js', 2, 'www.runnersworld.com'], 346 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 347 | ['http://admin.brightcove.com/js/BrightcoveExperiences.js', 2, 'www.runnersworld.com'], 348 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 349 | ['http://www.runnersworld.com/sites/runnersworld.com/files/js/js_LuwuSFEdYqw9yGG2dZ7wr8oNZxuelq-pJVr87qO-IHk.js', 2, 'www.runnersworld.com'], 350 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 351 | ['http://www.runnersworld.com/sites/all/modules/custom/zeus_sharebar/zeus_sharebar_subscribe_miniform.js', 2, 'www.runnersworld.com'], 352 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 353 | ['http://www.runnersworld.com/sites/runnersworld.com/files/js/js_-rSlAbwhdSJE2178kj-0jsS6YhvycGsFDhzDTFvQTWU.js', 2, 'www.runnersworld.com'], 354 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 355 | ['http://www.runnersworld.com/sites/all/modules/custom/zeus_slideshow/js/scripts.js', 2, 'www.runnersworld.com'], 356 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 357 | ['http://www.runnersworld.com/sites/runnersworld.com/themes/runnersworld/logo.png', 3, 'www.runnersworld.com'], 358 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 359 | ['http://www.runnersworld.com/sites/runnersworld.com/themes/runnersworld/images/camera-icon.png', 3, 'www.runnersworld.com'], 360 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 361 | ['http://www.runnersworld.com/sites/runnersworld.com/themes/runnersworld/images/subscribe.png', 3, 'www.runnersworld.com'], 362 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 363 | ['http://fonts.gstatic.com/s/robotocondensed/v13/b9QBgL0iMZfDSpmcXcE8nPX2or14QGUHgbhSBV1Go0E.woff2', 14, 'www.runnersworld.com'], 364 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 365 | ['http://fonts.gstatic.com/s/abrilfatface/v8/X1g_KwGeBV3ajZIXQ9VnDgYWpCd0FFfjqwFBDnEN0bM.woff2', 14, 'www.runnersworld.com'], 366 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 367 | ['http://fonts.gstatic.com/s/roboto/v15/oMMgfZMQthOryQo9n22dcuvvDin1pK8aKteLpeZ5c0A.woff2', 14, 'www.runnersworld.com'], 368 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 369 | ['http://www.runnersworld.com/sites/runnersworld.com/themes/runnersworld/fonts/fontawesome-webfont.woff?v=4.2.0', 14, 'www.runnersworld.com'], 370 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 371 | ['http://www.runnersworld.com/sites/runnersworld.com/themes/runnersworld/logo.png', 3, 'www.runnersworld.com'], 372 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 373 | ['http://www.runnersworld.com/sites/all/modules/custom/lazyloader/image_placeholder.gif', 3, 'www.runnersworld.com'], 374 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 375 | ['http://www.runnersworld.com/sites/all/modules/custom/lazyloader/image_placeholder.gif', 3, 'www.runnersworld.com'], 376 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 377 | ['http://b.scorecardresearch.com/beacon.js', 2, 'www.runnersworld.com'], 378 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 379 | ['http://assets.adobedtm.com/6f743006a41bd9090cd6c6b7dfa16b2cbed9c289/scripts/satellite-5530fef93737350017ea0400.js', 2, 'www.runnersworld.com'], 380 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 381 | ['http://assets.adobedtm.com/6f743006a41bd9090cd6c6b7dfa16b2cbed9c289/scripts/satellite-557b47dc6235310014510100.html', 7, 'www.runnersworld.com'], 382 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 383 | ['http://www.runnersworld.com/sites/all/modules/custom/zeus_load_more/images/loading.gif', 3, 'www.runnersworld.com'], 384 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 385 | ['http://www.runnersworld.com/sites/runnersworld.com/themes/runnersworld/images/nl-border.png', 3, 'www.runnersworld.com'], 386 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 387 | ['http://www.runnersworld.com/sites/runnersworld.com/themes/runnersworld/images/email-circle.png', 3, 'www.runnersworld.com'], 388 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 389 | ['http://assets.adobedtm.com/6f743006a41bd9090cd6c6b7dfa16b2cbed9c289/s-code-contents-d9e2bb1a111ccd66d5ed3cd9f03a420f4489dcbd.js', 2, 'www.runnersworld.com'], 390 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 391 | ['http://static.criteo.net/js/ld/ld.js', 2, 'www.runnersworld.com'], 392 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 393 | ['http://cdn.viglink.com/api/vglnk.js', 2, 'www.runnersworld.com'], 394 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 395 | ['http://www.runnersworld.com/load-more-settings-content/ajax/181496', 11, 'www.runnersworld.com'], 396 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 397 | ['http://connect.facebook.net/en_US/all.js#xfbml=1&version=v2.3&appId=424005050993003', 2, 'www.runnersworld.com'], 398 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 399 | ['https://graph.facebook.com/v2.3/?fields=share{comment_count}&id=http://www.runnersworld.com/gear-check/ask-the-gear-guy-how-to-avoid-soggy-summer-runs', 11, 'www.runnersworld.com'], 400 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 401 | ['http://widgets.outbrain.com/outbrain.js?_=1435784832943', 2, 'www.runnersworld.com'], 402 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 403 | ['http://www.runnersworld.com/sites/all/themes/zeus_base/images/svg/menu-icon.svg', 11, 'www.runnersworld.com'], 404 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 405 | ['http://www.runnersworld.com/sites/all/themes/zeus_base/images/svg/search.svg', 11, 'www.runnersworld.com'], 406 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 407 | ['http://www.runnersworld.com/sites/runnersworld.com/files/styles/article_main_image_2200px/public/articles/2015/06/sweaty-runner.jpg?itok=OZNEo6IL', 3, 'www.runnersworld.com'], 408 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 409 | ['http://www.runnersworld.com/sites/all/themes/zeus_base/images/svg/menu-icon.svg', 3, 'www.runnersworld.com'], 410 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 411 | ['http://www.runnersworld.com/sites/all/themes/zeus_base/images/svg/search.svg', 3, 'www.runnersworld.com'], 412 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 413 | ['http://s.moatads.com/rodale450aOVh43/moatcontent.js', 2, 'www.runnersworld.com'], 414 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 415 | ['http://b.scorecardresearch.com/b?c1=2&c2=6034733&ns__t=1435784834346&ns_c=UTF-8&c8=Ask%20the%20Gear%20Guy%3A%20How%20to%20Avoid%20Soggy%20Summer%20Runs%20%7C%20Runner%27s%20World&c7=http%3A%2F%2Fwww.runnersworld.com%2Fgear-check%2Fask-the-gear-guy-how-to-avoid-soggy-summer-runs&c9=', 3, 'www.runnersworld.com'], 416 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 417 | ['http://rodale.d1.sc.omtrdc.net/b/ss/rdl.rwwebproduction/1/H.26.2-D56H/s31911451629593?AQB=1&ndh=1&t=1%2F6%2F2015%2017%3A7%3A14%203%20240&D=D%3D&fid=6C6610CC90CC4D73-18BCF83379A55D4A&ce=UTF-8&ns=rodale&pageName=RW%3Agear-check%3Aask-the-gear-guy-how-to-avoid-soggy-summer-runs&g=http%3A%2F%2Fwww.runnersworld.com%2Fgear-check%2Fask-the-gear-guy-how-to-avoid-soggy-summer-runs&cc=USD&ch=Running%20Shoes%20%26%20Gear&server=www.runnersworld.com&c4=3&c5=http%3A%2F%2Fwww.runnersworld.com%2Fgear-check%2Fask-the-gear-guy-how-to-avoid-soggy-summer-runs&v5=http%3A%2F%2Fwww.runnersworld.com%2Fgear-check%2Fask-the-gear-guy-how-to-avoid-soggy-summer-runs&c6=3&c14=5%3A00PM&v14=5%3A00PM&c15=Wednesday&v15=Wednesday&c17=Weekday&v17=Weekday&c18=Less%20than%201%20day&v18=Less%20than%201%20day&c19=Repeat&v19=Repeat&c49=article&v49=article&c51=Running%20Shoes%20%26%20Gear&v51=Running%20Shoes%20%26%20Gear&c52=Gear%20Check&v52=Gear%20Check&c55=Bryan%20Boyle&v55=Bryan%20Boyle&c56=Ask%20the%20Gear%20Guy%2C%20Columns%2C%20Socks%2C%20Plantar%20Fasciitis%2C%20Hydration%20%26%20Dehydration%2C%20Hot%20Weather%20Running&v56=Ask%20the%20Gear%20Guy%2C%20Columns%2C%20Socks%2C%20Plantar%20Fasciitis%2C%20Hydration%20%26%20Dehydration%2C%20Hot%20Weather%20Running&c57=23%2F06%2F2015&v57=23%2F06%2F2015&c58=None&v58=None&c59=Ask%20the%20Gear%20Guy%3A%20How%20to%20Avoid%20Soggy%20Summer%20Runs&v59=Ask%20the%20Gear%20Guy%3A%20How%20to%20Avoid%20Soggy%20Summer%20Runs&c62=Gear%20Check%20%7C%20Ask%20the%20Gear%20Guy%3A%20How%20to%20Avoid%20Soggy%20Summer%20Runs&v62=Gear%20Check%20%7C%20Ask%20the%20Gear%20Guy%3A%20How%20to%20Avoid%20Soggy%20Summer%20Runs&h1=Running%20Shoes%20%26%20Gear%2CGear%20Check%2CAsk%20the%20Gear%20Guy%3A%20How%20to%20Avoid%20Soggy%20Summer%20Runs%2C23%2F06%2F2015&s=1680x1050&c=24&j=1.8.5&v=N&k=Y&bw=1058&bh=515&AQE=1', 3, 'www.runnersworld.com'], 418 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 419 | ['http://cdn.quilt.janrain.com/2.2.19/widgets.css', 4, 'www.runnersworld.com'], 420 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 421 | ['http://www.runnersworld.com/sites/runnersworld.com/files/janrain_capture_screens/cache/stylesheets_styles.css', 4, 'www.runnersworld.com'], 422 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 423 | ['https://d1lqe9temigv1p.cloudfront.net/widget_data/flow.js:9yse88rrbg6gpqkr754ypggpes:en-US:HEAD:standard', 2, 'www.runnersworld.com'], 424 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 425 | ['http://cdn.viglink.com/images/pixel.gif?ch=1&rn=10.539565056926248', 3, 'www.runnersworld.com'], 426 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 427 | ['http://cdn.viglink.com/images/pixel.gif?ch=2&rn=10.539565056926248', 3, 'www.runnersworld.com'], 428 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 429 | ['http://fonts.gstatic.com/s/robotocondensed/v13/b9QBgL0iMZfDSpmcXcE8nPX2or14QGUHgbhSBV1Go0E.woff2', 14, 'www.runnersworld.com'], 430 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 431 | ['http://fonts.gstatic.com/s/abrilfatface/v8/X1g_KwGeBV3ajZIXQ9VnDgYWpCd0FFfjqwFBDnEN0bM.woff2', 14, 'www.runnersworld.com'], 432 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 433 | ['http://fonts.gstatic.com/s/roboto/v15/oMMgfZMQthOryQo9n22dcuvvDin1pK8aKteLpeZ5c0A.woff2', 14, 'www.runnersworld.com'], 434 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 435 | ['http://odb.outbrain.com/utils/get?url=http%3A%2F%2Fwww.runnersworld.com%2Fgear-check%2Fask-the-gear-guy-how-to-avoid-soggy-summer-runs&settings=true&recs=true&widgetJSId=SB_3&key=NANOWDGT01&idx=0&version=255335&ref=&apv=false&sig=VK59dvfC&format=html&rand=60621&lsd=ab076175-753d-4014-be15-9f40da8d75e9&winW=1058&winH=515', 2, 'www.runnersworld.com'], 436 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 437 | ['http://static.ak.facebook.com/connect/xd_arbiter/xRlIuTsSMoE.js?version=41#channel=f208c5224a630fe&origin=http%3A%2F%2Fwww.runnersworld.com', 7, 'www.runnersworld.com'], 438 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 439 | ['https://s-static.ak.facebook.com/connect/xd_arbiter/xRlIuTsSMoE.js?version=41#channel=f208c5224a630fe&origin=http%3A%2F%2Fwww.runnersworld.com', 7, 'www.runnersworld.com'], 440 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 441 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 442 | ['http://images.outbrain.com/imageserver/v2/s/KXgU/a/vmwF8/2bCy4/2vho/vmwF8-NR4-90x90.jpg', 3, 'www.runnersworld.com'], 443 | ['http://images.outbrain.com/imageserver/v2/s/3cEI/n/17L3xV/abc/13ASoI/17L3xV-NR4-90x90.jpg', 3, 'www.runnersworld.com'], 444 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 445 | ['http://images.outbrain.com/imageserver/v2/s/MYNj/a/16T4yB/2cWhi/39EI/16T4yB-NR4-90x90.jpg', 3, 'www.runnersworld.com'], 446 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 447 | ['http://images.outbrain.com/imageserver/v2/s/3cEI/n/z0ymM/abc/wpZrG/z0ymM-NR4-90x90.jpg', 3, 'www.runnersworld.com'], 448 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 449 | ['http://images.outbrain.com/imageserver/v2/s/MfEU/a/12p64q/2WrFV/4xkV/12p64q-NR4-90x90.jpg', 3, 'www.runnersworld.com'], 450 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 451 | ['http://images.outbrain.com/imageserver/v2/s/3cEI/n/16ecPC/abc/12ywzY/16ecPC-NR4-90x90.jpg', 3, 'www.runnersworld.com'], 452 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 453 | ['http://widgets.outbrain.com/images/widgetIcons/ob_logo_67x12.png', 3, 'www.runnersworld.com'], 454 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 455 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 456 | ['http://widgets.outbrain.com/nanoWidget/images/adImages/ads-check.gif', 3, 'www.runnersworld.com'], 457 | ['http://fonts.gstatic.com/s/robotocondensed/v13/b9QBgL0iMZfDSpmcXcE8nPX2or14QGUHgbhSBV1Go0E.woff2', 14, 'www.runnersworld.com'], 458 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 459 | ['http://fonts.gstatic.com/s/abrilfatface/v8/X1g_KwGeBV3ajZIXQ9VnDgYWpCd0FFfjqwFBDnEN0bM.woff2', 14, 'www.runnersworld.com'], 460 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 461 | ['http://fonts.gstatic.com/s/roboto/v15/oMMgfZMQthOryQo9n22dcuvvDin1pK8aKteLpeZ5c0A.woff2', 14, 'www.runnersworld.com'], 462 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 463 | ['http://widgets.outbrain.com/nanoWidget/3rd/comScore/comScore.htm', 7, 'www.runnersworld.com'], 464 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 465 | ['http://odb.outbrain.com/utils/get?url=http%3A%2F%2Fwww.runnersworld.com%2Fgear-check%2Fask-the-gear-guy-how-to-avoid-soggy-summer-runs&settings=true&recs=true&widgetJSId=AR_3&key=NANOWDGT01&idx=1&version=255335&ref=&apv=true&sig=VK59dvfC&format=html&rand=95323&lsd=ab076175-753d-4014-be15-9f40da8d75e9&t=MV8zYjZhYzZiOTY3NGQxNGJkYzhhMzU4N2VjMjBkNGI3NV8w&winW=1058&winH=515', 2, 'www.runnersworld.com'], 466 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 467 | ['http://api.viglink.com/api/ping', 11, 'www.runnersworld.com'], 468 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 469 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 470 | ['http://log.outbrain.com/loggerServices/widgetGlobalEvent?tm=2320&pid=4116&sid=861942&wId=147&wRV=255335&rId=3b6ac6b9674d14bdc8a3587ec20d4b75&eT=0&idx=0&eIdx=&pvId=3b6ac6b9674d14bdc8a3587ec20d4b75&org=3&pad=3&ab=false', 2, 'www.runnersworld.com'], 471 | ['http://log.outbrain.com/loggerServices/widgetGlobalEvent?tm=2938&pid=4116&sid=861942&wId=147&wRV=255335&rId=3b6ac6b9674d14bdc8a3587ec20d4b75&eT=3&idx=0&eIdx=0&pvId=3b6ac6b9674d14bdc8a3587ec20d4b75&org=3&pad=3&ab=false', 2, 'www.runnersworld.com'], 472 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 473 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 474 | ['http://b.scorecardresearch.com/beacon.js', 2, 'www.runnersworld.com'], 475 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 476 | ['http://images.outbrain.com/imageserver/v2/s/Mm1m/a/17MKDJ/2gPz1/3oBF/17MKDJ-thh-214x129.jpg', 3, 'www.runnersworld.com'], 477 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 478 | ['http://images.outbrain.com/imageserver/v2/s/MYNj/a/152H7I/2bcyz/31UI/152H7I-thh-214x129.jpg', 3, 'www.runnersworld.com'], 479 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 480 | ['http://images.outbrain.com/imageserver/v2/s/MJGO/n/160r7N/abc/13Olzm/160r7N-thh-214x129.jpg', 3, 'www.runnersworld.com'], 481 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 482 | ['http://images.outbrain.com/imageserver/v2/s/Mngf/a/17dRli/2iz4f/4NAa/17dRli-thh-214x129.jpg', 3, 'www.runnersworld.com'], 483 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 484 | ['http://images.outbrain.com/imageserver/v2/s/MXu8/a/168Trp/2b4xi/2uZV/168Trp-thh-214x129.jpg', 3, 'www.runnersworld.com'], 485 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 486 | ['http://images.outbrain.com/imageserver/v2/s/KXgU/a/mWNWS/2bCsf/2vdQ/mWNWS-thh-214x129.jpg', 3, 'www.runnersworld.com'], 487 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 488 | ['http://images.outbrain.com/imageserver/v2/s/Mhd8/a/15zpng/2aVqm/2qFA/15zpng-thh-214x129.jpg', 3, 'www.runnersworld.com'], 489 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 490 | ['http://images.outbrain.com/imageserver/v2/s/MnUq/a/17ULeD/2jSNm/4QDw/17ULeD-thh-214x129.jpg', 3, 'www.runnersworld.com'], 491 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 492 | ['http://log.outbrain.com/loggerServices/widgetGlobalEvent?tm=5918&pid=4116&sid=861942&wId=110&wRV=255335&rId=7dd103daa4369e1c6339e44007bbecc2&eT=0&idx=1&eIdx=&pvId=3b6ac6b9674d14bdc8a3587ec20d4b75&org=0&pad=8&ab=false', 2, 'www.runnersworld.com'], 493 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 494 | ['http://widgets.outbrain.com/images/widgetIcons/ob_logo_67x12.png', 3, 'www.runnersworld.com'], 495 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 496 | ['http://widgets.outbrain.com/images/widgetIcons/ob_logo_67x12.png', 3, 'www.runnersworld.com'], 497 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 498 | ['http://fonts.gstatic.com/s/robotocondensed/v13/b9QBgL0iMZfDSpmcXcE8nPX2or14QGUHgbhSBV1Go0E.woff2', 14, 'www.runnersworld.com'], 499 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 500 | ['http://fonts.gstatic.com/s/abrilfatface/v8/X1g_KwGeBV3ajZIXQ9VnDgYWpCd0FFfjqwFBDnEN0bM.woff2', 14, 'www.runnersworld.com'], 501 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 502 | ['http://fonts.gstatic.com/s/roboto/v15/oMMgfZMQthOryQo9n22dcuvvDin1pK8aKteLpeZ5c0A.woff2', 14, 'www.runnersworld.com'], 503 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 504 | ['http://widgets.outbrain.com/nanoWidget/255335/module/skyLander.js', 2, 'www.runnersworld.com'], 505 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 506 | ['http://api.viglink.com/api/batch', 11, 'www.runnersworld.com'], 507 | ['http://api.viglink.com/api/batch?key=d51168e121e8439611ea432821d32b71&libId=ibl9810201010tpc000DA1oil88gq0qrlp&batch=%7B%22domains%22%3A%7B%22key%22%3A%22d51168e121e8439611ea432821d32b71%22%2C%22libId%22%3A%22ibl9810201010tpc000DA1oil88gq0qrlp%22%2C%22domains%22%3A%22runnersworld.com%7Ccommunity.runnersworld.com%7Crw.runnersworld.com%7Crodalestore.com%7Cw1.buysub.com%7Crodaleinc.com%7Cpreferences.rodale.com%7Cinsidetrack.runnersworld.com%7Cfacebook.com%7Ctwitter.com%7Cinstagram.com%7Cplus.google.com%7Cpinterest.com%7C%7Csecure.rodale.com%7Cwoolx.com%7Csmartwool.com%7Cbrdsport.com%7Cultimatedirection.com%7Cboreburn.com%7Ctimetobreak.com%7Cbeautyjunkiez.com%7Crodale.com%22%7D%2C%22insert%22%3A%7B%22key%22%3A%22d51168e121e8439611ea432821d32b71%22%2C%22libId%22%3A%22ibl9810201010tpc000DA1oil88gq0qrlp%22%2C%22cat%22%3A%22sf%22%2C%22pt%22%3A%22full%22%2C%22u%22%3A%22http%3A%2F%2Fwww.runnersworld.com%2Fgear-check%2Fask-the-gear-guy-how-to-avoid-soggy-summer-runs%22%7D%7D', 2, 'www.runnersworld.com'], 508 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 509 | ['http://b.scorecardresearch.com/b?c1=7&c2=14320224&c3=000&ns__t=1435784844227&ns_c=windows-1252&c8=&c7=http%3A%2F%2Fwidgets.outbrain.com%2FnanoWidget%2F3rd%2FcomScore%2FcomScore.htm&c9=http%3A%2F%2Fwww.runnersworld.com%2Fgear-check%2Fask-the-gear-guy-how-to-avoid-soggy-summer-runs', 3, 'www.runnersworld.com'], 510 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 511 | ['http://static.chartbeat.com/js/chartbeat.js', 2, 'www.runnersworld.com'], 512 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 513 | ['http://api.bounceexchange.com/bounce/init1.js?tojQ=function&tzo=240&is_preview=false&website_id=869&resolution=1058x515&referrer=&calling_url=http%3A%2F%2Fwww.runnersworld.com%2Fgear-check%2Fask-the-gear-guy-how-to-avoid-soggy-summer-runs&visit_cookie=%7B%22lp%22%3A%22http%253A%252F%252Fwww.runnersworld.com%252Fgear-check%252Fask-the-gear-guy-how-to-avoid-soggy-summer-runs%22%2C%22r%22%3A%22%22%7D&cookie=%7B%22fvt%22%3A1435724258%2C%22vid%22%3A1435781969619960%2C%22ao%22%3A1%2C%22as%22%3A0%2C%22vpv%22%3A1%2C%22d%22%3A%22d%22%2C%22lp%22%3A%22http%253A%252F%252Fwww.runnersworld.com%252Fgear-check%252Fask-the-gear-guy-how-to-avoid-soggy-summer-runs%22%2C%22r%22%3A%22%22%2C%22cvt%22%3A1435781969%2C%22gcr%22%3A95%2C%22m%22%3A0%2C%22sid%22%3A0%2C%22campaigns%22%3A%7B%22136371%22%3A%7B%22vv%22%3A1%2C%22lvt%22%3A1435781969%2C%22lavid%22%3A1435724258614315%2C%22la%22%3A1435724646%2C%22fsa%22%3A1435724646%2C%22av%22%3A0%2C%22as%22%3A0%2C%22ao%22%3A1%7D%7D%2C%22lvt%22%3A1435781969%2C%22ibxt%22%3A%22MTQzNTcyNDI1ODYxNDMxNQ%253D%253D%22%7D&vars[is_logged_in]=false', 2, 'www.runnersworld.com'], 514 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 515 | ['https://www.facebook.com/connect/ping?client_id=424005050993003&domain=www.runnersworld.com&origin=1&redirect_uri=http%3A%2F%2Fstatic.ak.facebook.com%2Fconnect%2Fxd_arbiter%2FxRlIuTsSMoE.js%3Fversion%3D41%23cb%3Df3cfa365d52fe4a%26domain%3Dwww.runnersworld.com%26origin%3Dhttp%253A%252F%252Fwww.runnersworld.com%252Ff208c5224a630fe%26relation%3Dparent&response_type=token%2Csigned_request%2Ccode&sdk=joey', 7, 'www.runnersworld.com'], 516 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 517 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 518 | ['https://www.facebook.com/plugins/comments.php?api_key=424005050993003&channel_url=http%3A%2F%2Fstatic.ak.facebook.com%2Fconnect%2Fxd_arbiter%2FxRlIuTsSMoE.js%3Fversion%3D41%23cb%3Df9c1754d4da2aa%26domain%3Dwww.runnersworld.com%26origin%3Dhttp%253A%252F%252Fwww.runnersworld.com%252Ff208c5224a630fe%26relation%3Dparent.parent&colorscheme=light&href=http%3A%2F%2Fwww.runnersworld.com%2Fgear-check%2Fask-the-gear-guy-how-to-avoid-soggy-summer-runs&locale=en_US&numposts=10&sdk=joey&skin=light&width=100%25', 7, 'www.runnersworld.com'], 519 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 520 | ['http://fonts.gstatic.com/s/robotocondensed/v13/b9QBgL0iMZfDSpmcXcE8nPX2or14QGUHgbhSBV1Go0E.woff2', 14, 'www.runnersworld.com'], 521 | ['http://fonts.gstatic.com/s/abrilfatface/v8/X1g_KwGeBV3ajZIXQ9VnDgYWpCd0FFfjqwFBDnEN0bM.woff2', 14, 'www.runnersworld.com'], 522 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 523 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 524 | ['http://fonts.gstatic.com/s/roboto/v15/oMMgfZMQthOryQo9n22dcuvvDin1pK8aKteLpeZ5c0A.woff2', 14, 'www.runnersworld.com'], 525 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 526 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 527 | ['http://ping.chartbeat.net/ping?h=runnersworld.com&p=%2Fgear-check%2Fask-the-gear-guy-how-to-avoid-soggy-summer-runs&u=CAuWcLC_5TBlPhIZ6&d=runnersworld.com&g=15891&g0=Running%20Shoes%20%26%20Gear&n=0&f=00001&c=0&x=0&m=0&y=4210&o=1058&w=515&j=45&R=1&W=0&I=0&E=0&e=0&r=&b=13926&t=6Nk_mCzPlhXC-4O8Htmt8kBnNj6&V=60&z=t%3DDLPhqbjWCQ9DwB3mBVKZSRB0t7wx%26E%3D0%26x%3D87%26c%3D0.55%26y%3D4120%26w%3D515&i=Ask%20the%20Gear%20Guy%3A%20How%20to%20Avoid%20Soggy%20Summer%20Runs%20%7C%20Runner%27s%20World&tz=240&sn=1&_', 3, 'www.runnersworld.com'], 528 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 529 | ['http://bounceexchange.com/assets/bounce/bounce.css?v40', 4, 'www.runnersworld.com'], 530 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 531 | ['https://fbstatic-a.akamaihd.net/rsrc.php/v1/yi/r/odA9sNLrE86.jpg', 3, 'www.runnersworld.com'], 532 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 533 | ['https://fbstatic-a.akamaihd.net/rsrc.php/v2/yU/r/6pY-oEb32kn.js', 2, 'www.runnersworld.com'], 534 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 535 | ['https://fbstatic-a.akamaihd.net/rsrc.php/v1/yi/r/odA9sNLrE86.jpg', 3, 'www.runnersworld.com'], 536 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 537 | ['https://fbstatic-a.akamaihd.net/rsrc.php/v1/yi/r/odA9sNLrE86.jpg', 3, 'www.runnersworld.com'], 538 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 539 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 540 | ['http://fonts.gstatic.com/s/robotocondensed/v13/b9QBgL0iMZfDSpmcXcE8nPX2or14QGUHgbhSBV1Go0E.woff2', 14, 'www.runnersworld.com'], 541 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 542 | ['http://fonts.gstatic.com/s/abrilfatface/v8/X1g_KwGeBV3ajZIXQ9VnDgYWpCd0FFfjqwFBDnEN0bM.woff2', 14, 'www.runnersworld.com'], 543 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 544 | ['http://fonts.gstatic.com/s/roboto/v15/oMMgfZMQthOryQo9n22dcuvvDin1pK8aKteLpeZ5c0A.woff2', 14, 'www.runnersworld.com'], 545 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 546 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 547 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 548 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 549 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 550 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 551 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 552 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 553 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 554 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 555 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 556 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 557 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 558 | ['http://api.bounceexchange.com/bounce/iframe_campaign/136371?mode=0&website_id=869&device_type=d&cv_id=&visit_id=1435784844979020&height=515&w=655px&h=460px&width=1058&campaign_id=136371&cvt=1435784844&fsa=1435724646&scale=0.6969696969697&pos=overlay&vars%5Bis_logged_in%5D=false', 7, 'www.runnersworld.com'], 559 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 560 | ['http://fonts.gstatic.com/s/robotocondensed/v13/b9QBgL0iMZfDSpmcXcE8nPX2or14QGUHgbhSBV1Go0E.woff2', 14, 'www.runnersworld.com'], 561 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 562 | ['http://fonts.gstatic.com/s/abrilfatface/v8/X1g_KwGeBV3ajZIXQ9VnDgYWpCd0FFfjqwFBDnEN0bM.woff2', 14, 'www.runnersworld.com'], 563 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 564 | ['http://fonts.gstatic.com/s/roboto/v15/oMMgfZMQthOryQo9n22dcuvvDin1pK8aKteLpeZ5c0A.woff2', 14, 'www.runnersworld.com'], 565 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 566 | ['http://assets.bounceexchange.com/static1/jquery.min.js', 2, 'www.runnersworld.com'], 567 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 568 | ['http://api.bounceexchange.com/assets/bounce/overlay.js?v13', 2, 'www.runnersworld.com'], 569 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 570 | ['http://assets.bounceexchange.com/static1/jquery.min.js', 2, 'www.runnersworld.com'], 571 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 572 | ['http://api.bounceexchange.com/assets/bounce/bounce.css?v40', 4, 'www.runnersworld.com'], 573 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 574 | ['https://assets.bounceexchange.com/assets/uploads/clients/869/ads/acdcrRC1.png', 3, 'www.runnersworld.com'], 575 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 576 | ['https://assets.bounceexchange.com/assets/uploads/clients/869/ads/wsiR4alr.png', 3, 'www.runnersworld.com'], 577 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 578 | ['http://api.viglink.com/api/domains', 11, 'www.runnersworld.com'], 579 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 580 | ['http://api.bounceexchange.com/assets/bounce/overlay.js?v13', 2, 'www.runnersworld.com'], 581 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 582 | ['http://api.bounceexchange.com/assets/bounce/bounce.css?v40', 4, 'www.runnersworld.com'], 583 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 584 | ['https://assets.bounceexchange.com/assets/uploads/clients/869/ads/acdcrRC1.png', 3, 'www.runnersworld.com'], 585 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 586 | ['https://assets.bounceexchange.com/assets/uploads/clients/869/ads/acdcrRC1.png', 3, 'www.runnersworld.com'], 587 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 588 | ['https://assets.bounceexchange.com/assets/uploads/clients/869/ads/wsiR4alr.png', 3, 'www.runnersworld.com'], 589 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 590 | ['https://assets.bounceexchange.com/assets/uploads/clients/869/ads/wsiR4alr.png', 3, 'www.runnersworld.com'], 591 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 592 | ['http://api.bounceexchange.com/capture/report.gif?uq=1&m=0&website_id=869&d=d&type=views&cv_id=undefined&c_id=136371&v_id=1435784844979020&opt_rand=0.49372647024393335', 3, 'www.runnersworld.com'], 593 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 594 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 595 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 596 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 597 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 598 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 599 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 600 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 601 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 602 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 603 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 604 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 605 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 606 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 607 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 608 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 609 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 610 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 611 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 612 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 613 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 614 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 615 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 616 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 617 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 618 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 619 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 620 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 621 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 622 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 623 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 624 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 625 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 626 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 627 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 628 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 629 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 630 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 631 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 632 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 633 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 634 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 635 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 636 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 637 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 638 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 639 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 640 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 641 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 642 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 643 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 644 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 645 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 646 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 647 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 648 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 649 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 650 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 651 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 652 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 653 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 654 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 655 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 656 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 657 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 658 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 659 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 660 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 661 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 662 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 663 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 664 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 665 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 666 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 667 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 668 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 669 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 670 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 671 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 672 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 673 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 674 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 675 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 676 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 677 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 678 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 679 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 680 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 681 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 682 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 683 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 684 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 685 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 686 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 687 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 688 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 689 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 690 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 691 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 692 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 693 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 694 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 695 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 696 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 697 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 698 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 699 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 700 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 701 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 702 | ['http://ping.chartbeat.net/ping?h=runnersworld.com&p=%2Fgear-check%2Fask-the-gear-guy-how-to-avoid-soggy-summer-runs&u=CAuWcLC_5TBlPhIZ6&d=runnersworld.com&g=15891&g0=Running%20Shoes%20%26%20Gear&n=0&f=00001&c=0.5&x=0&m=0&y=4210&o=1058&w=515&j=60&R=0&W=0&I=1&E=0&e=0&b=13926&t=6Nk_mCzPlhXC-4O8Htmt8kBnNj6&V=60&tz=240&sn=2&_', 3, 'www.runnersworld.com'], 703 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 704 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 705 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 706 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 707 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 708 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 709 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 710 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 711 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 712 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 713 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 714 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 715 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 716 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 717 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 718 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 719 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 720 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 721 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 722 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 723 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 724 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 725 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 726 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 727 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 728 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 729 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 730 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 731 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 732 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 733 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 734 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 735 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 736 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 737 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 738 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 739 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 740 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 741 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 742 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 743 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 744 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 745 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 746 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 747 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 748 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 749 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 750 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 751 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 752 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 753 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 754 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 755 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 756 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 757 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 758 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 759 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 760 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 761 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 762 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 763 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 764 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 765 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 766 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 767 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 768 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 769 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 770 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 771 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 772 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 773 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 774 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 775 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 776 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 777 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 778 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 779 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 780 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 781 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 782 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 783 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 784 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 785 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 786 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 787 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 788 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 789 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 790 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 791 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 792 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 793 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 794 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 795 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 796 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 797 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 798 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 799 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 800 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 801 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 802 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 803 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 804 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 805 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 806 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 807 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 808 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 809 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 810 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 811 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 812 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 813 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 814 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 815 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 816 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 817 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 818 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 819 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 820 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 821 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 822 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 823 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 824 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 825 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 826 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 827 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 828 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 829 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 830 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 831 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 832 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 833 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 834 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 835 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 836 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 837 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 838 | ['http://nodeassets.nbcnews.com/images/022272a4.nightly-news-logo-mark.png', 3, 'www.nbcnews.com'], 839 | ['http://nodeassets.nbcnews.com/images/022272a4.nightly-news-logo-mark.png', 3, 'www.nbcnews.com'], 840 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 841 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 842 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 843 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 844 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 845 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 846 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 847 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 848 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 849 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 850 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 851 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 852 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 853 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 854 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 855 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 856 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 857 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 858 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 859 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 860 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 861 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 862 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 863 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 864 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 865 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 866 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 867 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 868 | ['http://nodeassets.nbcnews.com/scripts/vendor/e13156bf.modernizr.js', 2, 'www.nbcnews.com'], 869 | ['http://nodeassets.nbcnews.com/styles/fonts/ProximaNova-Sbold-webfont.woff', 14, 'www.nbcnews.com'], 870 | ['http://nodeassets.nbcnews.com/styles/fonts/ProximaNova-Reg-webfont.woff', 14, 'www.nbcnews.com'], 871 | ['http://nodeassets.nbcnews.com/styles/fonts/ProximaNova-Bold-webfont.woff', 14, 'www.nbcnews.com'], 872 | ['http://nodeassets.nbcnews.com/styles/fonts/ProximaNovaCond-Light-webfont.woff', 14, 'www.nbcnews.com'], 873 | ['http://nodeassets.nbcnews.com/styles/fonts/ProximaNovaCond-Sbold-webfont.woff', 14, 'www.nbcnews.com'], 874 | ['http://netdna.bootstrapcdn.com/font-awesome/4.0.3/fonts/fontawesome-webfont.woff?v=4.0.3', 14, 'www.nbcnews.com'], 875 | ['http://mps.nbcnews.com/fetch/ext/load-nbcnews-web.js', 2, 'www.nbcnews.com'], 876 | ['http://mps.nbcnews.com/request/page/jsonp?CALLBACK=mpsCallback&cat=cover&site=nbcnews-web&path=%2Fcover&type=cover&NOLOAD=mpstools', 2, 'www.nbcnews.com'], 877 | ['http://www.nbcnews.com/news/us-news/u-s-authorities-gear-july-4-amid-worries-isis-inspired-n385176', 6, 'www.nbcnews.com'], 878 | ['http://nodeassets.nbcnews.com/scripts/6f1cab75.vendor.js', 2, 'www.nbcnews.com'], 879 | ['http://assets.adobedtm.com/cd771b0aa897f931a306d7ab6af0d448836b5fd1/satelliteLib-d7647ef38f862ffb17587d65d0a95182256c1765.js', 2, 'www.nbcnews.com'], 880 | ['http://stats.g.doubleclick.net/dc.js', 2, 'www.nbcnews.com'], 881 | ['http://nvcdn.nbcnews.com/_elliott/jenga?widgets=newsletter,zinger2', 2, 'www.nbcnews.com'], 882 | ['http://nodeassets.nbcnews.com/scripts/f2bfebfe.main.js', 2, 'www.nbcnews.com'], 883 | ['http://assets.adobedtm.com/cd771b0aa897f931a306d7ab6af0d448836b5fd1/scripts/satellite-53d275e7db0fc7cc1100016e.js', 2, 'www.nbcnews.com'], 884 | ['http://nvg.nbcnews.com/trackingService/trackingService.min.js', 2, 'www.nbcnews.com'], 885 | ['http://assets.adobedtm.com/cd771b0aa897f931a306d7ab6af0d448836b5fd1/scripts/satellite-54aeb36432373700158a0200.js', 2, 'www.nbcnews.com'], 886 | ['http://assets.adobedtm.com/cd771b0aa897f931a306d7ab6af0d448836b5fd1/scripts/satellite-543fd4ace1507bb6340002ed.js', 2, 'www.nbcnews.com'], 887 | ['http://assets.adobedtm.com/cd771b0aa897f931a306d7ab6af0d448836b5fd1/scripts/satellite-5510ce673962350019f20700.js', 2, 'www.nbcnews.com'], 888 | ['http://assets.adobedtm.com/cd771b0aa897f931a306d7ab6af0d448836b5fd1/scripts/satellite-55688c5e6531640017ce0500.js', 2, 'www.nbcnews.com'], 889 | ['http://assets.adobedtm.com/cd771b0aa897f931a306d7ab6af0d448836b5fd1/scripts/satellite-5570dcbf6434390017f10300.js', 2, 'www.nbcnews.com'], 890 | ['http://assets.adobedtm.com/cd771b0aa897f931a306d7ab6af0d448836b5fd1/scripts/satellite-54db64ce6161370016650000.js', 2, 'www.nbcnews.com'], 891 | ['http://assets.adobedtm.com/cd771b0aa897f931a306d7ab6af0d448836b5fd1/s-code-contents-df22810c703bbcb4da38ea9a83b0ffa1091846fd.js', 2, 'www.nbcnews.com'], 892 | ['http://media4.s-nbcnews.com/j/newscms/2015_27/1103286/150701-terror-alert-jhc-1541_e09d2dbd54e02d90185515cb0fcd7d20.nbcnews-fp-680-320.jpg', 3, 'www.nbcnews.com'], 893 | ['http://netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.min.css', 4, 'www.nbcnews.com'], 894 | ['http://netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.min.css', 4, 'www.nbcnews.com'], 895 | ['http://cdnjs.cloudflare.com/ajax/libs/weather-icons/1.2/css/weather-icons.min.css', 4, 'www.nbcnews.com'], 896 | ['http://cdnjs.cloudflare.com/ajax/libs/weather-icons/1.2/css/weather-icons.min.css', 4, 'www.nbcnews.com'], 897 | ['http://nvcdn.nbcnews.com/_elliott/jenga_css?widgets=zinger2', 4, 'www.nbcnews.com'], 898 | ['http://nvcdn.nbcnews.com/_elliott/jenga_css?widgets=zinger2', 4, 'www.nbcnews.com'], 899 | ['http://st.dynamicyield.com/ast?sec=8765428&id=1751900436871446816', 2, 'www.nbcnews.com'], 900 | ['http://nodeassets.nbcnews.com/styles/fc21d61b.main.css', 4, 'www.nbcnews.com'], 901 | ['http://nodeassets.nbcnews.com/scripts/vendor/e13156bf.modernizr.js', 2, 'www.nbcnews.com'], 902 | ['http://nodeassets.nbcnews.com/scripts/6f1cab75.vendor.js', 2, 'www.nbcnews.com'], 903 | ['http://assets.adobedtm.com/cd771b0aa897f931a306d7ab6af0d448836b5fd1/satelliteLib-d7647ef38f862ffb17587d65d0a95182256c1765.js', 2, 'www.nbcnews.com'], 904 | ['http://nvcdn.nbcnews.com/_elliott/jenga?widgets=newsletter,zinger2', 2, 'www.nbcnews.com'], 905 | ['http://nodeassets.nbcnews.com/scripts/f2bfebfe.main.js', 2, 'www.nbcnews.com'], 906 | ['http://nodeassets.nbcnews.com/scripts/5b5ada32.articleApp.js', 2, 'www.nbcnews.com'], 907 | ['http://nodeassets.nbcnews.com/styles/fc21d61b.main.css', 4, 'www.nbcnews.com'], 908 | ['http://www.nbcnews.com/news/us-news/u-s-authorities-gear-july-4-amid-worries-isis-inspired-n385176', 6, 'www.nbcnews.com'], 909 | ['http://nodeassets.nbcnews.com/styles/fc21d61b.main.css', 4, 'www.nbcnews.com'], 910 | ['http://nodeassets.nbcnews.com/styles/fc21d61b.main.css', 4, 'www.nbcnews.com'], 911 | ['http://nodeassets.nbcnews.com/scripts/vendor/e13156bf.modernizr.js', 2, 'www.nbcnews.com'], 912 | ['http://nodeassets.nbcnews.com/scripts/6f1cab75.vendor.js', 2, 'www.nbcnews.com'], 913 | ['http://ping.chartbeat.net/ping?h=runnersworld.com&p=%2Fgear-check%2Fask-the-gear-guy-how-to-avoid-soggy-summer-runs&u=CAuWcLC_5TBlPhIZ6&d=runnersworld.com&g=15891&g0=Running%20Shoes%20%26%20Gear&n=0&f=00001&c=1.25&x=0&m=0&y=4210&o=1058&w=515&j=90&R=0&W=0&I=1&E=0&e=0&b=13926&t=6Nk_mCzPlhXC-4O8Htmt8kBnNj6&V=60&tz=240&sn=3&_', 3, 'www.runnersworld.com'], 914 | ['http://assets.adobedtm.com/cd771b0aa897f931a306d7ab6af0d448836b5fd1/satelliteLib-d7647ef38f862ffb17587d65d0a95182256c1765.js', 2, 'www.nbcnews.com'], 915 | ['http://nvcdn.nbcnews.com/_elliott/jenga?widgets=newsletter,zinger2', 2, 'www.nbcnews.com'], 916 | ['http://nodeassets.nbcnews.com/scripts/f2bfebfe.main.js', 2, 'www.nbcnews.com'], 917 | ['http://nodeassets.nbcnews.com/scripts/5b5ada32.articleApp.js', 2, 'www.nbcnews.com'], 918 | ['http://nodeassets.nbcnews.com/styles/658e3d49.fonts.css', 4, 'www.nbcnews.com'], 919 | ['http://nodeassets.nbcnews.com/styles/658e3d49.fonts.css', 4, 'www.nbcnews.com'], 920 | ['http://netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.min.css', 4, 'www.nbcnews.com'], 921 | ['http://netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.min.css', 4, 'www.nbcnews.com'], 922 | ['http://sslnodeassets.nbcnews.com/images/non-rev/nbcnews-logo.svg', 3, 'www.nbcnews.com'], 923 | ['http://sslnodeassets.nbcnews.com/images/non-rev/nbcnews-logo.svg', 3, 'www.nbcnews.com'], 924 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 925 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 926 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 927 | ['http://nodeassets.nbcnews.com/images/nbcnews-logo-mark.png', 3, 'www.nbcnews.com'], 928 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 929 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 930 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 931 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 932 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 933 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 934 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 935 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 936 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 937 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 938 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 939 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 940 | ['http://sslnodeassets.nbcnews.com/images/transparent-placeholder.gif', 3, 'www.nbcnews.com'], 941 | ['http://nodeassets.nbcnews.com/scripts/vendor/e13156bf.modernizr.js', 2, 'www.nbcnews.com'], 942 | ['http://mps.nbcnews.com/fetch/ext/load-nbcnews-web.js', 2, 'www.nbcnews.com'], 943 | ['http://nodeassets.nbcnews.com/styles/fonts/ProximaNova-Sbold-webfont.woff', 14, 'www.nbcnews.com'], 944 | ['http://netdna.bootstrapcdn.com/font-awesome/4.0.3/fonts/fontawesome-webfont.woff?v=4.0.3', 14, 'www.nbcnews.com'], 945 | ['http://nodeassets.nbcnews.com/styles/fonts/ProximaNova-Reg-webfont.woff', 14, 'www.nbcnews.com'], 946 | ['http://nodeassets.nbcnews.com/styles/fonts/ProximaNova-Bold-webfont.woff', 14, 'www.nbcnews.com'], 947 | ['http://nodeassets.nbcnews.com/styles/fonts/ProximaNovaCond-Sbold-webfont.woff', 14, 'www.nbcnews.com'], 948 | ['http://mps.nbcnews.com/request/page/jsonp?CALLBACK=mpsCallback&cat=news%7Cus-news%7Carticle&site=nbcnews-web&path=%2Fnews%2Fus-news%2Fu-s-authorities-gear-july-4-amid-worries-isis-inspired-n385176&type=spread&NOLOAD=mpstools', 2, 'www.nbcnews.com'], 949 | ['http://mps.nbcnews.com/js/advertising/dev_global_header.js', 2, 'www.nbcnews.com'], 950 | ['http://www.nbcudigitaladops.com/hosted/site.js?h=nbcnews_com_header', 2, 'www.nbcnews.com'], 951 | ['http://async-lb-2129785755.us-east-1.elb.amazonaws.com/admantx/service?request={decorator:%22template.nbc_template%22,key:%2262263fff3cc1d07f85c7f8261a0c8f7dc096b35f59c82a713f20a9db8d562ff2%22,method:%22descriptor%22,filter:%22default%22,mode:%22async%22,type:%22URL%22,body:%22http%3A//www.nbcnews.com/news/us-news/u-s-authorities-gear-july-4-amid-worries-isis-inspired-n385176%22}', 2, 'www.nbcnews.com'], 952 | ['http://www.googletagservices.com/tag/js/gpt.js', 2, 'www.nbcnews.com'], 953 | ['http://nodeassets.nbcnews.com/scripts/6f1cab75.vendor.js', 2, 'www.nbcnews.com'], 954 | ['http://assets.adobedtm.com/cd771b0aa897f931a306d7ab6af0d448836b5fd1/satelliteLib-d7647ef38f862ffb17587d65d0a95182256c1765.js', 2, 'www.nbcnews.com'], 955 | ['http://stats.g.doubleclick.net/dc.js', 2, 'www.nbcnews.com'], 956 | ['http://nvcdn.nbcnews.com/_elliott/jenga?widgets=newsletter,zinger2', 2, 'www.nbcnews.com'], 957 | ['http://nodeassets.nbcnews.com/scripts/f2bfebfe.main.js', 2, 'www.nbcnews.com'], 958 | ['http://www.nbcnews.com/pages/ads/taboola/rightrail.html?csrc=http://www.nbcnews.com/news/us-news/u-s-authorities-gear-july-4-amid-worries-isis-inspired-n385176', 7, 'www.nbcnews.com'], 959 | ['http://www.nbcnews.com/pages/ads/taboola/belowarticle.html?canonical=http://www.nbcnews.com/news/us-news/u-s-authorities-gear-july-4-amid-worries-isis-inspired-n385176', 7, 'www.nbcnews.com'], 960 | ['http://nodeassets.nbcnews.com/scripts/5b5ada32.articleApp.js', 2, 'www.nbcnews.com'], 961 | ['http://code.hpprintx.com/printx-client-latest.min.js', 2, 'www.nbcnews.com'], 962 | ['http://assets.adobedtm.com/cd771b0aa897f931a306d7ab6af0d448836b5fd1/scripts/satellite-5526a92334373200145d0300.js', 2, 'www.nbcnews.com'], 963 | ['http://nvg.nbcnews.com/trackingService/trackingService.min.js', 2, 'www.nbcnews.com'], 964 | ['http://assets.adobedtm.com/cd771b0aa897f931a306d7ab6af0d448836b5fd1/scripts/satellite-54aeb36432373700158a0200.js', 2, 'www.nbcnews.com'], 965 | ['http://assets.adobedtm.com/cd771b0aa897f931a306d7ab6af0d448836b5fd1/scripts/satellite-543fd4ace1507bb6340002ed.js', 2, 'www.nbcnews.com'], 966 | ['http://assets.adobedtm.com/cd771b0aa897f931a306d7ab6af0d448836b5fd1/scripts/satellite-5510ce673962350019f20700.js', 2, 'www.nbcnews.com'], 967 | ['http://assets.adobedtm.com/cd771b0aa897f931a306d7ab6af0d448836b5fd1/scripts/satellite-55688c5e6531640017ce0500.js', 2, 'www.nbcnews.com'], 968 | ['http://assets.adobedtm.com/cd771b0aa897f931a306d7ab6af0d448836b5fd1/scripts/satellite-5570dcbf6434390017f10300.js', 2, 'www.nbcnews.com'], 969 | ['http://assets.adobedtm.com/cd771b0aa897f931a306d7ab6af0d448836b5fd1/scripts/satellite-54db64ce6161370016650000.js', 2, 'www.nbcnews.com'], 970 | ['http://assets.adobedtm.com/cd771b0aa897f931a306d7ab6af0d448836b5fd1/s-code-contents-df22810c703bbcb4da38ea9a83b0ffa1091846fd.js', 2, 'www.nbcnews.com'], 971 | ['http://media4.s-nbcnews.com/j/newscms/2015_27/1103286/150701-terror-alert-jhc-1541_e09d2dbd54e02d90185515cb0fcd7d20.nbcnews-fp-1000-400.jpg', 3, 'www.nbcnews.com'], 972 | ['http://netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.min.css', 4, 'www.nbcnews.com'], 973 | ['http://netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.min.css', 4, 'www.nbcnews.com'], 974 | ['http://cdnjs.cloudflare.com/ajax/libs/weather-icons/1.2/css/weather-icons.min.css', 4, 'www.nbcnews.com'], 975 | ['http://cdnjs.cloudflare.com/ajax/libs/weather-icons/1.2/css/weather-icons.min.css', 4, 'www.nbcnews.com'], 976 | ['http://nvcdn.nbcnews.com/_elliott/jenga_css?widgets=zinger2', 4, 'www.nbcnews.com'], 977 | ['http://nvcdn.nbcnews.com/_elliott/jenga_css?widgets=zinger2', 4, 'www.nbcnews.com'], 978 | ['http://st.dynamicyield.com/ast?sec=8765428&id=1751900436871446816', 2, 'www.nbcnews.com'], 979 | ['http://b3.mookie1.com/2/LB/5602314550@x96?', 2, 'www.nbcnews.com'], 980 | ['http://assets.adobedtm.com/cd771b0aa897f931a306d7ab6af0d448836b5fd1/scripts/satellite-54aeb36432373700158a0200.js', 2, 'www.nbcnews.com'], 981 | ['http://partner.googleadservices.com/gpt/pubads_impl_65.js', 2, 'www.nbcnews.com'], 982 | ['http://tpc.googlesyndication.com/safeframe/1-0-2/html/container.html', 7, 'www.nbcnews.com'], 983 | ['http://www.googletagservices.com/tag/js/check_359604.js', 2, 'www.nbcnews.com'], 984 | ['http://mps.nbcnews.com/js/advertising/dev_global.js', 2, 'www.nbcnews.com'], 985 | ['http://stats.g.doubleclick.net/__utm.gif?utmwv=5.6.4dc&utms=1&utmn=1481003907&utmhn=www.nbcnews.com&utme=8(40!bluenode)9(40!bluenode)&utmcs=UTF-8&utmsr=1680x1050&utmvp=1058x515&utmsc=24-bit&utmul=en-us&utmje=0&utmfl=-&utmdt=Worries%20of%20ISIS-Inspired%20Attacks%20Cloud%20July%204%20Holiday%20Weekend%20-%20NBC%20News&utmhid=2021150843&utmr=-&utmp=%2Fnews%2Fus-news%2Fu-s-authorities-gear-july-4-amid-worries-isis-inspired-n385176&utmht=1435784936219&utmac=UA-43189446-2&utmcc=__utma%3D37970300.677566931.1435697460.1435721497.1435784936.3%3B%2B__utmz%3D37970300.1435697460.1.1.utmcsr%3D(direct)%7Cutmccn%3D(direct)%7Cutmcmd%3D(none)%3B&utmu=qRCg~', 3, 'www.nbcnews.com'], 986 | ['http://sqs.us-west-1.amazonaws.com/109494492107/PrintX_Analytics_PRODUCTION?Action=SendMessage&MessageBody=%7B%22type%22%3A%22load%22%2C%22info%22%3A%7B%22url%22%3A%22http%3A%2F%2Fwww.nbcnews.com%2Fnews%2Fus-news%2Fu-s-authorities-gear-july-4-amid-worries-isis-inspired-n385176%22%2C%22userAgent%22%3A%22Mozilla%2F5.0%20(Macintosh%3B%20Intel%20Mac%20OS%20X%2010.10%3B%20rv%3A41.0)%20Gecko%2F20100101%20Firefox%2F41.0%22%7D%7D&__t=1435784936410', 11, 'www.nbcnews.com'], 987 | ['http://connect.facebook.net/en_US/fbds.js', 2, 'www.nbcnews.com'], 988 | ['http://b.scorecardresearch.com/beacon.js', 2, 'www.nbcnews.com'], 989 | ['http://secure-us.imrworldwide.com/cgi-bin/m?ci=us-505401h&cg=0&cc=1&si=http%3A//www.nbcnews.com/news/us-news/u-s-authorities-gear-july-4-amid-worries-isis-inspired-n385176&rp=&ts=compact&rnd=1435784937051', 3, 'www.nbcnews.com'], 990 | ['http://ddrn6tjst80qg.cloudfront.net/api/8765428/api_dynamic.js', 2, 'www.nbcnews.com'], 991 | ['http://ddrn6tjst80qg.cloudfront.net/api/8765428/api_static.js', 2, 'www.nbcnews.com'], 992 | ['http://7204487.collect.igodigital.com/collect.js', 2, 'www.nbcnews.com'], 993 | ['http://msnbc.112.2o7.net/b/ss/msnbcnbcnewscomprod/1/H.26.1-D56H/s36304927974637?AQB=1&ndh=1&t=1%2F6%2F2015%2017%3A8%3A57%203%20240&D=D%3D&fid=3C8A02C042B5C650-3B54961C30225A42&ns=msnbc&pageName=nbcnews%3Aspread%3Aworries-isis-inspired-attacks-cloud-july-4-holiday-weekend&g=http%3A%2F%2Fwww.nbcnews.com%2Fnews%2Fus-news%2Fu-s-authorities-gear-july-4-amid-worries-isis-inspired-n385176&cc=USD&ch=news&server=nbcnews.com&events=event1%3A1435784937845&v1=nbcnews%3Aspread%3Aworries-isis-inspired-attacks-cloud-july-4-holiday-weekend&c2=us-news&v2=spread&v3=nbcnews.com&v4=news&v5=news&c6=http%3A%2F%2Fwww.nbcnews.com%2Fnews%2Fus-news%2Fu-s-authorities-gear-july-4-amid-worries-isis-inspired-n385176&v6=us-news&c7=responsive&c9=no%20referrer%20url&c10=responsive&v10=news-us-news&c12=spread&v12=5%3A00PM&v13=Wednesday&v14=Weekday&v15=4&v16=Worries%20of%20ISIS-Inspired%20Attacks%20Cloud%20July%204%20Holiday%20Weekend&v18=The%20year-long%20rise%20of%20ISIS%2C%20and%20its%20leaders%27%20appeals%20for%20supporters%20to%20carry%20out%20attacks%20around%20the%20world%2C%20has%20authorities%20on%20high%20alert.&v19=2015-07-01%2021%3A00%3A41%20Z&c23=NBCNews&v23=nbcnews&v24=pqa1zkyxo&v28=no%20referrer%20url&v33=1929775bbcf6b333adc22bf7241140ae&v34=3C8A02C042B5C650-3B54961C30225A42&v35=3&v42=http%3A%2F%2Fwww.nbcnews.com%2Fnews%2Fus-news%2Fu-s-authorities-gear-july-4-amid-worries-isis-inspired-n385176&v63=NewsCms%2FEntry%2F385176&s=1680x1050&c=24&j=1.8.5&v=N&k=Y&bw=1058&bh=515&AQE=1', 3, 'www.nbcnews.com'], 994 | ['http://www.nbcudigitaladops.com/hosted/site.js?h=nbcnews_com', 2, 'www.nbcnews.com'], 995 | ['http://static.dynamicyield.com/scripts/12001/dyjq-min.js?v=3638', 2, 'www.nbcnews.com'], 996 | ['http://static.dynamicyield.com/scripts/12001/dy-min.js?v=3638', 2, 'www.nbcnews.com'], 997 | ['https://www.facebook.com/tr/?id=514991798612189&ev=PixelInitialized&dl=http%3A%2F%2Fwww.nbcnews.com%2Fnews%2Fus-news%2Fu-s-authorities-gear-july-4-amid-worries-isis-inspired-n385176&rl=&if=false&ts=1435784938739&cd[dl]=%2Fnews%2Fus-news%2Fu-s-authorities-gear-july-4-amid-worries-isis-inspired-n385176&cd[rl]=no%20referrer%20url', 3, 'www.nbcnews.com'], 998 | ['http://b.scorecardresearch.com/b?c1=2&c2=3000001&c3=NBCNews&c4=&ns__t=1435784938927&ns_c=UTF-8&c8=Worries%20of%20ISIS-Inspired%20Attacks%20Cloud%20July%204%20Holiday%20Weekend%20-%20NBC%20News&c7=http%3A%2F%2Fwww.nbcnews.com%2Fnews%2Fus-news%2Fu-s-authorities-gear-july-4-amid-worries-isis-inspired-n385176&c9=', 3, 'www.nbcnews.com'], 999 | ['http://cdn.krxd.net/controltag?confid=Hhr_tdFP', 2, 'www.nbcnews.com'], 1000 | ['http://www.nbcudigitaladops.com/hosted/housepix.gif', 3, 'www.nbcnews.com'], 1001 | ['http://nova.collect.igodigital.com/c2/7204487/track_page_view?payload=%7B%22url%22%3A%22http%3A%2F%2Fwww.nbcnews.com%2Fnews%2Fus-news%2Fu-s-authorities-gear-july-4-amid-worries-isis-inspired-n385176%22%2C%22category%22%3A%22us-news%22%2C%22title%22%3A%22Worries%20of%20ISIS-Inspired%20Attacks%20Cloud%20July%204%20Holiday%20Weekend%20-%20NBC%20News%22%2C%22referrer%22%3A%22%22%2C%22user_info%22%3A%7B%22email%22%3A%223C8A02C042B5C650-3B54961C30225A42%22%7D%7D', 3, 'www.nbcnews.com'], 1002 | ['http://media4.s-nbcnews.com/j/newscms/2015_27/1103286/150701-terror-alert-jhc-1541_e09d2dbd54e02d90185515cb0fcd7d20.nbcnews-fp-1000-400.jpg', 3, 'www.nbcnews.com'], 1003 | ['http://media4.s-nbcnews.com/j/newscms/2015_27/1103286/150701-terror-alert-jhc-1541_e09d2dbd54e02d90185515cb0fcd7d20.nbcnews-fp-1000-400.jpg', 3, 'www.nbcnews.com'], 1004 | ['http://www.nbcnews.com/databox/data.aspx?callback=localSearch&dbid=55384635&s=10113', 11, 'www.nbcnews.com'], 1005 | ['http://www.nbcnews.com/widget/pdkplayer?csid=nbcnews_fallbacksitesection§ion=&topic=&show=&storyline=&tags=&feature=#playerurl=http://www.nbcnews.com', 7, 'www.nbcnews.com'], 1006 | ['http://www.polls.newsvine.com/_api/hostConfig?remoteHost=www.nbcnews.com&callback=_jqjsp', 2, 'www.nbcnews.com'], 1007 | ['http://media1.s-nbcnews.com/j/newscms/2015_26/1096056/150626-american-security-july-fourth-yh-0321p_613fa1ba5f69bb26db0d438229939413.nbcnews-ux-600-480.jpg', 3, 'www.nbcnews.com'], 1008 | ['http://cdn.krxd.net/ctjs/controltag.js.875fd5b280a77e06def8c74a5a268e2c', 2, 'www.nbcnews.com'], 1009 | ['http://px.dynamicyield.com/dpx?_=335728&name=new_session_start&props=%7B%22session_id%22%3A1435785311102.0293%2C%22lastActivity%22%3A1435784941257%7D&uid=1751900436871446816&sec=8765428&cl=m.frv2.ms.f.&ses=209cdd6d1ff5b721f45c781627d741f7&l=def&p=null&sd=&rf=&aud=1870.1808.2005&svars=142%3A%40%3A.%40.143%3A%40%3A.%40.158%3A%40%3Anews.%40.200%3A%40%3Ano%20topic.%40.201%3A%40%3Ano%20topic.%40.202%3A%40%3Ano%20topic&url=http%3A%2F%2Fwww.nbcnews.com%2Fnews%2Fus-news%2Fu-s-authorities-gear-july-4-amid-worries-isis-inspired-n385176&exps=%5B%5D', 11, 'www.nbcnews.com'], 1010 | ['http://px.dynamicyield.com/dpx?_=795454&name=pageviews&props=%7B%7D&uid=1751900436871446816&sec=8765428&cl=m.frv2.ms.f.&ses=209cdd6d1ff5b721f45c781627d741f7&l=def&p=null&sd=&rf=&aud=1870.1808.2005&svars=142%3A%40%3A.%40.143%3A%40%3A.%40.158%3A%40%3Anews.%40.200%3A%40%3Ano%20topic.%40.201%3A%40%3Ano%20topic.%40.202%3A%40%3Ano%20topic&url=http%3A%2F%2Fwww.nbcnews.com%2Fnews%2Fus-news%2Fu-s-authorities-gear-july-4-amid-worries-isis-inspired-n385176&exps=%5B%5D', 11, 'www.nbcnews.com'], 1011 | ['http://px.dynamicyield.com/uia?id=1751900436871446816&se=8765428&us=11.6.1&cl=m.frv2.ms.f.&rf=&p=1&sub=www.nbcnews.com&sd=&url=http%3A%2F%2Fwww.nbcnews.com%2Fnews%2Fus-news%2Fu-s-authorities-gear-july-4-amid-worries-isis-inspired-n385176&title=Worries+of+ISIS-Inspired+Attacks+Cloud+July+4+Holiday+Weekend+-+NBC+News&lay=def&ses=209cdd6d1ff5b721f45c781627d741f7&aud=1870.1694.1808.2005&svars=142%3A%40%3A.%40.143%3A%40%3A.%40.158%3A%40%3Anews.%40.200%3A%40%3Ano+topic.%40.201%3A%40%3Ano+topic.%40.202%3A%40%3Ano+topic&gv=&exps=%5B%5D<s=17%3A9&_=1435784941796', 11, 'www.nbcnews.com'], 1012 | ['http://nodeassets.nbcnews.com/styles/d1544992.video-main.css', 4, 'www.nbcnews.com'], 1013 | ['http://netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.min.css', 4, 'www.nbcnews.com'], 1014 | ['http://nodeassets.nbcnews.com/libs/pdk_1_1/tpPdk.js', 2, 'www.nbcnews.com'], 1015 | ['http://nodeassets.nbcnews.com/libs/pdk_1_1/images/CC-Close.gif', 3, 'www.nbcnews.com'], 1016 | ['http://nodeassets.nbcnews.com/scripts/6e5dd46d.video-player.js', 2, 'www.nbcnews.com'], 1017 | ['http://nodeassets.nbcnews.com/styles/d1544992.video-main.css', 4, 'www.nbcnews.com'], 1018 | ['http://netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.min.css', 4, 'www.nbcnews.com'], 1019 | ['http://nodeassets.nbcnews.com/libs/pdk_1_1/tpPdk.js', 2, 'www.nbcnews.com'], 1020 | ['http://media1.s-nbcnews.com/j/newscms/2015_26/1096056/150626-american-security-july-fourth-yh-0321p_613fa1ba5f69bb26db0d438229939413.nbcnews-ux-600-480.jpg', 3, 'www.nbcnews.com'], 1021 | ['http://media1.s-nbcnews.com/j/newscms/2015_26/1096056/150626-american-security-july-fourth-yh-0321p_613fa1ba5f69bb26db0d438229939413.nbcnews-ux-600-480.jpg', 3, 'www.nbcnews.com'], 1022 | ['http://nodeassets.nbcnews.com/libs/pdk_1_1/style/default.css', 4, 'www.nbcnews.com'], 1023 | ['http://nodeassets.nbcnews.com/libs/pdk_1_1/js/app/69DE732B62CB5CD8191328E15598F67D.cache.js', 2, 'www.nbcnews.com'], 1024 | ['http://nodeassets.nbcnews.com/libs/pdk_1_1/images/CC-Close.gif', 3, 'www.nbcnews.com'], 1025 | ['http://netdna.bootstrapcdn.com/font-awesome/4.0.3/fonts/fontawesome-webfont.woff?v=4.0.3', 14, 'www.nbcnews.com'], 1026 | ['http://nodeassets.nbcnews.com/libs/pdk_1_1/images/CC-Close.gif', 3, 'www.nbcnews.com'], 1027 | ['http://nodeassets.nbcnews.com/scripts/6e5dd46d.video-player.js', 2, 'www.nbcnews.com'], 1028 | ['http://static.chartbeat.com/js/chartbeat.js', 2, 'www.nbcnews.com'], 1029 | ['http://pixel.mathtag.com/sync/js?sync=auto', 2, 'www.nbcnews.com'], 1030 | ['http://beacon.krxd.net/optout_check?callback=Krux.ns._default.kxjsonp_optOutCheck', 2, 'www.nbcnews.com'], 1031 | ['http://cdn.krxd.net/userdata/get?pub=54983c83-8810-4a6b-9ff1-81f7349ce967&technographics=1&callback=Krux.ns._default.kxjsonp_userdata', 2, 'www.nbcnews.com'], 1032 | ['http://nodeassets.nbcnews.com/images/loading-spinner-yellow-lg.png', 3, 'www.nbcnews.com'], 1033 | ['http://nodeassets.nbcnews.com/libs/pdk_1_1/js/app/deferredjs/69DE732B62CB5CD8191328E15598F67D/4.cache.js?serial=0', 2, 'www.nbcnews.com'], 1034 | ['http://nodeassets.nbcnews.com/libs/pdk_1_1/js/plugins/akamaiHD.js', 2, 'www.nbcnews.com'], 1035 | ['http://px.dynamicyield.com/imp?id=1751900436871446816&sec=8765428&imps%5B%5D=dyother%7C26056%7C%7C81%7C%7C%7C&imps%5B%5D=dyother%7C26184%7C%7C81%7C%7C%7C&imps%5B%5D=dyother%7C26185%7C%7C81%7C%7C%7C&imps%5B%5D=dyother%7C26186%7C%7C81%7C%7C%7C&imps%5B%5D=dyother%7C26188%7C%7C81%7C%7C%7C&imps%5B%5D=dyother%7C26189%7C%7C81%7C%7C%7C&imps%5B%5D=dyother%7C26190%7C%7C81%7C%7C%7C&imps%5B%5D=dyother%7C26191%7C%7C81%7C%7C%7C&imps%5B%5D=dyother%7C26192%7C%7C81%7C%7C%7C&imps%5B%5D=dyother%7C26193%7C%7C81%7C%7C%7C&imps%5B%5D=dyother%7C26194%7C%7C81%7C%7C%7C&imps%5B%5D=dyother%7C26195%7C%7C81%7C%7C%7C&imps%5B%5D=dyother%7C26196%7C%7C81%7C%7C%7C&imps%5B%5D=dyother%7C26056%7C%7C81%7C%7C%7C&imps%5B%5D=dyother%7C26197%7C%7C81%7C%7C%7C&imps%5B%5D=dyother%7C26198%7C%7C81%7C%7C%7C&imps%5B%5D=dyother%7C26199%7C%7C81%7C%7C%7C&imps%5B%5D=dyother%7C26200%7C%7C81%7C%7C%7C&imps%5B%5D=dyother%7C26056%7C%7C4795%7C%7C%7C&cl=m.frv2.ms.f.&bl=0&l=def&p=1&sd=&rf=&sr=1680x1050&ses=209cdd6d1ff5b721f45c781627d741f7&aud=1870.1694.1808.2005&svars=142%3A%40%3A.%40.143%3A%40%3A.%40.158%3A%40%3Anews.%40.200%3A%40%3Ano+topic.%40.201%3A%40%3Ano+topic.%40.202%3A%40%3Ano+topic&url=http%3A%2F%2Fwww.nbcnews.com%2Fnews%2Fus-news%2Fu-s-authorities-gear-july-4-amid-worries-isis-inspired-n385176&exps=%5B%5D&_=1435784946977', 11, 'www.nbcnews.com'], 1036 | ['http://ping.chartbeat.net/ping?h=nbcnews.com&p=%2Fnews%2Fus-news%2Fu-s-authorities-gear-july-4-amid-worries-isis-inspired-n385176&u=BZBCmuBX7sIe4FVbr&d=nbcnews.com&g=27410&n=0&f=10003&c=0&x=0&m=0&y=4710&o=1058&w=515&j=45&R=1&W=0&I=0&E=0&e=0&r=&b=8877&t=BEeZo5D75gN-hHTgJDq1YbUBj7tKS&V=60&i=Worries%20of%20ISIS-Inspired%20Attacks%20Cloud%20July%204%20Holiday%20Weekend%20-%20NBC%20News&tz=240&sn=1&_', 3, 'www.nbcnews.com'], 1037 | ['http://pixel.mathtag.com/misc/img?mop_seq=0:1&mt_cb=169264&mop_top=', 3, 'www.nbcnews.com'], 1038 | ['http://js.revsci.net/gateway/gw.js?csid=F09828&auto=t&bpid=nbcu', 2, 'www.nbcnews.com'], 1039 | ['http://nodeassets.nbcnews.com/libs/pdk_1_1/js/app/deferredjs/69DE732B62CB5CD8191328E15598F67D/3.cache.js?serial=0', 2, 'www.nbcnews.com'], 1040 | ['http://icompass.insightexpressai.com/3077.js', 2, 'www.nbcnews.com'], 1041 | ['http://nodeassets.nbcnews.com/libs/pdk_1_1/js/plugins/freewheel.js', 2, 'www.nbcnews.com'], 1042 | ['http://snas.nbcuni.com/snas/api/getRemoteDomainCookies?callback=__nbcsnasadops.doSCallback', 2, 'www.nbcnews.com'], 1043 | ['http://secure.quantserve.com/quant.js', 2, 'www.nbcnews.com'], 1044 | ['http://www.nbcnews.com/id/52493270?nbcnews.json', 11, 'www.nbcnews.com'], 1045 | ['http://adadvisor.net/adscores/g.pixel?sid=9211132948&_mt=2a1b5593-045f-4700-b1a1-5e2096a4156d', 3, 'www.nbcnews.com'], 1046 | ['http://pixel.mathtag.com/misc/img?mop_seq=1:1&mt_cb=416470&check=2a1b5593-045f-4700-b1a1-5e2096a4156d&mop_top=10009:1435784945|', 3, 'www.nbcnews.com'], 1047 | ['http://adm.fwmrm.net/p/nbcnews_live/AdManager.js', 2, 'www.nbcnews.com'], 1048 | ['http://www.nbcnews.com/id/52493270?nbcnews.json', 11, 'www.nbcnews.com'], 1049 | ['http://pixel.quantserve.com/pixel;r=2097076061;a=p-9eJ8k4iSzux46;fpan=0;fpa=P0-167389382-1435721502509;ns=0;ce=1;cm=;je=0;sr=1680x1050x24;enc=n;dst=1;et=1435784949462;tzo=240;ref=;url=http%3A%2F%2Fwww.nbcnews.com%2Fnews%2Fus-news%2Fu-s-authorities-gear-july-4-amid-worries-isis-inspired-n385176;ogl=site_name.NBC%20News%2Cdescription.The%20year-long%20rise%20of%20ISIS%252C%20and%20its%20leaders\'%20appeals%20for%20supporters%20to%20carry%20out%2Ctitle.Worries%20of%20ISIS-Inspired%20Attacks%20Cloud%20July%204%20Holiday%20Weekend%2Curl.http%3A%2F%2Fwww%252Enbcnews%252Ecom%2Fnews%2Fus-news%2Fu-s-authorities-gear-july-4-amid-worries-isi%2Ctype.article%2Cimage.http%3A%2F%2Fmedia4%252Es-nbcnews%252Ecom%2Fj%2Fnewscms%2F2015_27%2F1103286%2F150701-terror-alert-jhc-15', 3, 'www.nbcnews.com'], 1050 | ['http://krxd.nexac.com/dlx.gif?_kdpid=2dd640a6-6ebd-4d4f-af30-af8baa441a0d&kuid=J6DuiqBK', 3, 'www.nbcnews.com'], 1051 | ['http://beacon.krxd.net/event.gif?event_id=Jo7PIOui&type=regular&event_type=cnt', 3, 'www.nbcnews.com'], 1052 | ['http://loadm.exelator.com/load?_kdpid=e4942ff0-4070-4896-a7ef-e6a5a30ce9f9&buid=J6DuiqBK&p=204&g=270&j=0', 3, 'www.nbcnews.com'], 1053 | ['http://adadvisor.net/adscores/g.js?sid=9212244187&_kdpid=2111c0af-fc3a-446f-ab07-63aa74fbde8e', 3, 'www.nbcnews.com'], 1054 | ['http://adadvisor.net/adscores/g.js?sid=9212244187&_kdpid=2111c0af-fc3a-446f-ab07-63aa74fbde8e', 3, 'www.nbcnews.com'], 1055 | ['https://idsync.rlcdn.com/379708.gif?partner_uid=J6DuiqBK', 3, 'www.nbcnews.com'], 1056 | ['http://rtd.tubemogul.com/upi/pid/NC4WTmcy?redir=http%3A%2F%2Fbeacon.krxd.net%2Fusermatch.gif%3Fpartner_id%3Dcb276571-e0d9-4438-9fd4-80a1ff034b01%26puid%3D%24%7BTM_USER_ID%7D', 3, 'www.nbcnews.com'], 1057 | ['http://pixel.quantserve.com/seg/r;a=p-9eJ8k4iSzux46;rand=106500081;redirect=http://beacon.krxd.net/data.gif?_kdpid=c28722fa-1ec3-4a33-838f-d360c76c0aca&segs=!qcsegs', 3, 'www.nbcnews.com'], 1058 | ['http://static.crowdscience.com/max-7881f43af0.js?callback=CS_data_callback', 2, 'www.nbcnews.com'], 1059 | ['http://link.theplatform.com/s/2E2eJC/9xilC0LpOFIP?switch=http&format=SMIL&tracking=true&embedded=true&formats=MPEG4', 11, 'www.nbcnews.com'], 1060 | ['http://ping.crowdscience.com/max_log.js?a=7881f43af0&lv=9:9&v=9ca9b19a0e7ae44d&h=www.nbcnews.com&cs=&sr=1&fl=www.nbcnews.com%7Cnews/us-news/u-s-authorities-gear-july-4-amid-worries-isis-inspired-n385176&fr=6&fd=3&fk=&ft=4&fp=2&fb=2&fs=', 2, 'www.nbcnews.com'], 1061 | ['http://www.nbcnews.com/widget/pdkplayer?csid=nbcnews_fallbacksitesection§ion=&topic=&show=&storyline=&tags=&feature=', 3, 'www.nbcnews.com'], 1062 | ['http://nodeassets.nbcnews.com/libs/pdk_1_1/js/app/deferredjs/69DE732B62CB5CD8191328E15598F67D/2.cache.js?serial=0', 2, 'www.nbcnews.com'], 1063 | ['http://www.nbcnews.com/widget/pdkplayer?csid=nbcnews_fallbacksitesection§ion=&topic=&show=&storyline=&tags=&feature=', 3, 'www.nbcnews.com'], 1064 | ['http://www.nbcnews.com/widget/pdkplayer?csid=nbcnews_fallbacksitesection§ion=&topic=&show=&storyline=&tags=&feature=', 3, 'www.nbcnews.com'], 1065 | ['http://beacon.krxd.net/pixel.gif?source=smarttag&fired=user_data_timeout&confid=Hhr_tdFP&_kpid=54983c83-8810-4a6b-9ff1-81f7349ce967&_kcp_s=NBC%20News&_kcp_sc=www.nbcnews.com&_kcp_d=www.nbcnews.com&_knifr=7&_kua_kx_tz=240&geo_country=ca&geo_region=on&_kua_kx_lang=en-us&_kua_kx_tech_browser_language=en-us&_kua_kx_tech_browser=Firefox%204&_kua_kx_tech_manufacturer=Apple%20Inc.&_kua_kx_tech_device=Computer&_kua_kx_tech_os=Mac%20OS%20X&_kua_kx_geo_country=ca&_kua_kx_geo_region=on&_kpa_dart_genreDELIM=%2C&_kpa_url_path_1=news&_kpa_url_path_2=us-news&_kpa_url_path_3=u-s-authorities-gear-july-4-amid-worries-isis-inspired-n385176&_kpa_FullUrl=http%3A%2F%2Fwww.nbcnews.com%2Fnews%2Fus-news%2Fu-s-authorities-gear-july-4-amid-worries-isis-inspired-n385176&t_navigation_type=0&t_dns=0&t_tcp=0&t_http_request=-1&t_http_response=8&t_content_ready=20549&t_window_load=26282&t_redirect=0&interchange_ran=true&store_user=pqa1zkyxo&userdata_was_requested=true&userdata_did_respond=true&store_user_after=pqa1zkyxo&userdata_user=J6DuiqBK%2Cpqa1zkyxo&kfuid=c06e22ea6ad6a383e5a1e0201e23f94d5526a7f5&kxfp=c06e22ea6ad6a383e5a1e0201e23f94d5526a7f5&sview=1&kplt0=59177&kplt1=55860&kplt2=28327&kplt3=27697&kplt4=45116&kplt5=11327&kplt6=16002&kplt7=23254&kplt8=14072&kplt9=12072&kplt10=38962&kplt11=11109&kplt12=19045&kplt14=18290&kplt15=35454&kplt16=24980&kplt19=11476&kplt20=15596&kplt21=20727&kplt22=27407&kplt24=32786&kplt27=22975&kplt28=14704&kplt29=25022&kplt30=13132&kplt31=10688&kplt32=10957&kplt33=10971&kplt34=10993&jsonp_requests=%2F%2Fbeacon.krxd.net%2Foptout_check%2C1049%2C%2F%2Fcdn.krxd.net%2Fuserdata%2Fget%2C1091', 3, 'www.nbcnews.com'], 1066 | ['http://nodeassets.nbcnews.com/libs/pdk_1_1/js/app/deferredjs/69DE732B62CB5CD8191328E15598F67D/1.cache.js?serial=0', 2, 'www.nbcnews.com'], 1067 | ['http://ads.freewheel.tv/', 15, 'www.nbcnews.com'], 1068 | ['http://px.dynamicyield.com/rimp?id=1751900436871446816&sec=8765428&rimps%5B%5D=dyother%7C26200%7C%7C81%7C%7C%7C&rimps%5B%5D=dyother%7C26199%7C%7C81%7C%7C%7C&rimps%5B%5D=dyother%7C26198%7C%7C81%7C%7C%7C&rimps%5B%5D=dyother%7C26197%7C%7C81%7C%7C%7C&rimps%5B%5D=dyother%7C26056%7C%7C81%7C%7C%7C&rimps%5B%5D=dyother%7C26196%7C%7C81%7C%7C%7C&rimps%5B%5D=dyother%7C26195%7C%7C81%7C%7C%7C&rimps%5B%5D=dyother%7C26194%7C%7C81%7C%7C%7C&rimps%5B%5D=dyother%7C26193%7C%7C81%7C%7C%7C&rimps%5B%5D=dyother%7C26192%7C%7C81%7C%7C%7C&rimps%5B%5D=dyother%7C26191%7C%7C81%7C%7C%7C&rimps%5B%5D=dyother%7C26190%7C%7C81%7C%7C%7C&rimps%5B%5D=dyother%7C26189%7C%7C81%7C%7C%7C&rimps%5B%5D=dyother%7C26188%7C%7C81%7C%7C%7C&rimps%5B%5D=dyother%7C26186%7C%7C81%7C%7C%7C&rimps%5B%5D=dyother%7C26185%7C%7C81%7C%7C%7C&rimps%5B%5D=dyother%7C26184%7C%7C81%7C%7C%7C&rimps%5B%5D=dyother%7C26056%7C%7C81%7C%7C%7C&cl=m.frv2.ms.f.&l=def&p=1&sd=&rf=&ses=209cdd6d1ff5b721f45c781627d741f7&aud=1870.1694.1808.2005&svars=142%3A%40%3A.%40.143%3A%40%3A.%40.158%3A%40%3Anews.%40.200%3A%40%3Ano+topic.%40.201%3A%40%3Ano+topic.%40.202%3A%40%3Ano+topic&_=1435784957204', 11, 'www.nbcnews.com'], 1069 | ['http://pixel.mathtag.com/misc/img?mop_seq=1:1&mt_cb=416470&check=2a1b5593-045f-4700-b1a1-5e2096a4156d&mop_top=10009:1435784945|&final&timings=0:855|0:2315|&errors=10009:591|', 3, 'www.nbcnews.com'], 1070 | ['http://playback.nbcnews.com/videoredirect/h264/std/tdy_lauer_4th_150701.mp4', 15, 'www.nbcnews.com'], 1071 | ['http://ping.chartbeat.net/ping?h=nbcnews.com&p=%2Fnews%2Fus-news%2Fu-s-authorities-gear-july-4-amid-worries-isis-inspired-n385176&u=BZBCmuBX7sIe4FVbr&d=nbcnews.com&g=27410&n=0&f=10003&c=0.5&x=0&m=0&y=4710&o=1058&w=515&j=60&R=0&W=0&I=1&E=0&e=0&b=8877&t=BEeZo5D75gN-hHTgJDq1YbUBj7tKS&V=60&tz=240&sn=2&_', 3, 'www.nbcnews.com'], 1072 | ['http://ping.chartbeat.net/ping?h=runnersworld.com&p=%2Fgear-check%2Fask-the-gear-guy-how-to-avoid-soggy-summer-runs&u=CAuWcLC_5TBlPhIZ6&d=runnersworld.com&g=15891&g0=Running%20Shoes%20%26%20Gear&n=0&f=00001&c=2.5&x=0&m=0&y=4210&o=1058&w=515&j=150&R=0&W=0&I=1&E=0&e=0&b=13926&t=6Nk_mCzPlhXC-4O8Htmt8kBnNj6&V=60&tz=240&sn=4&_', 3, 'www.runnersworld.com'], 1073 | ]; 1074 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "abp-filter-parser", 3 | "version": "0.2.0", 4 | "main": "dist/src/abp-filter-parser.js", 5 | "scripts": { 6 | "test": "mocha --compilers js:babel-core/register", 7 | "lint": "eslint src/abp-filter-parser.js src/extractInfo.js test/*.js", 8 | "build": "babel --modules umd src/*.js --out-dir dist --source-maps", 9 | "build-jsm": "babel --modules ignore --plugins babel-jsm-plugin src --out-dir dist --source-maps", 10 | "build-common": "babel --modules common src/abp-filter-parser.js --out-file dist/abp-filter-parser-commonjs.js --source-maps", 11 | "extract": "babel-node src/extractInfo.js", 12 | "prepublish": "npm run build" 13 | }, 14 | "author": "Brian R. Bondy (http://www.brianbondy.com)", 15 | "license": "MPL-2.0", 16 | "devDependencies": { 17 | "babel-cli": "^6.1.2", 18 | "babel-core": "^6.1.2", 19 | "babel-eslint": "^4.1.3", 20 | "babel-jsm-plugin": "^1.0.2", 21 | "babel-polyfill": "^6.0.16", 22 | "babel-preset-es2015": "^6.1.2", 23 | "babel-preset-stage-2": "^6.1.2", 24 | "eslint": "^2.1.0", 25 | "mocha": "^2.3.3", 26 | "pre-commit": "^1.1.2" 27 | }, 28 | "repository": { 29 | "type": "git", 30 | "url": "git+https://github.com/bbondy/abp-filter-parser.git" 31 | }, 32 | "bugs": { 33 | "url": "https://github.com/bbondy/abp-filter-parser/issues" 34 | }, 35 | "homepage": "https://github.com/bbondy/abp-filter-parser#readme", 36 | "description": "", 37 | "dependencies": { 38 | "bloom-filter-js": "0.0.12" 39 | }, 40 | "engines": { 41 | "node": "~5.0" 42 | }, 43 | "pre-commit": [ 44 | "lint" 45 | ] 46 | } 47 | -------------------------------------------------------------------------------- /src/abp-filter-parser.js: -------------------------------------------------------------------------------- 1 | import * as BloomFilterJS from 'bloom-filter-js'; 2 | import {badFingerprints, badSubstrings} from './badFingerprints.js'; 3 | 4 | let fs = require('fs'); 5 | 6 | /** 7 | * bitwise mask of different request types 8 | */ 9 | export const elementTypes = { 10 | SCRIPT: 0o1, 11 | IMAGE: 0o2, 12 | STYLESHEET: 0o4, 13 | OBJECT: 0o10, 14 | XMLHTTPREQUEST: 0o20, 15 | OBJECTSUBREQUEST: 0o40, 16 | SUBDOCUMENT: 0o100, 17 | DOCUMENT: 0o200, 18 | OTHER: 0o400, 19 | }; 20 | 21 | // Maximum number of cached entries to keep for subsequent lookups 22 | const maxCached = 100; 23 | 24 | // Maximum number of URL chars to check in match clauses 25 | const maxUrlChars = 100; 26 | 27 | // Exact size for fingerprints, if you change also change fingerprintRegexs 28 | const fingerprintSize = 8; 29 | 30 | // Regexes used to create fingerprints 31 | // There's more than one because sometimes a fingerprint is determined to be a bad 32 | // one and would lead to a lot of collisions in the bloom filter). In those cases 33 | // we use the 2nd fingerprint. 34 | let fingerprintRegexs = [ 35 | /.*([./&_\-=a-zA-Z0-9]{8})\$?.*/, 36 | /([./&_\-=a-zA-Z0-9]{8})\$?.*/, 37 | ]; 38 | 39 | /** 40 | * Maps element types to type mask. 41 | */ 42 | export const elementTypeMaskMap = new Map([ 43 | ['script', elementTypes.SCRIPT], 44 | ['image', elementTypes.IMAGE], 45 | ['stylesheet', elementTypes.STYLESHEET], 46 | ['object', elementTypes.OBJECT], 47 | ['xmlhttprequest', elementTypes.XMLHTTPREQUEST], 48 | ['object-subrequest', elementTypes.OBJECTSUBREQUEST], 49 | ['subdocument', elementTypes.SUBDOCUMENT], 50 | ['document', elementTypes.DOCUMENT], 51 | ['other', elementTypes.OTHER] 52 | ]); 53 | 54 | const separatorCharacters = ':?/=^'; 55 | 56 | /** 57 | * Parses the domain string using the passed in separator and 58 | * fills in options. 59 | */ 60 | export function parseDomains(input, separator, options) { 61 | options.domains = options.domains || []; 62 | options.skipDomains = options.skipDomains || []; 63 | let domains = input.split(separator); 64 | options.domains = options.domains.concat(domains.filter((domain) => domain[0] !== '~')); 65 | options.skipDomains = options.skipDomains.concat(domains 66 | .filter((domain) => domain[0] === '~') 67 | .map((domain) => domain.substring(1))); 68 | } 69 | 70 | if (!Array.prototype.includes) { 71 | Array.prototype.includes = function(searchElement /*, fromIndex*/ ) { 72 | 'use strict'; 73 | var O = Object(this); 74 | var len = parseInt(O.length, 10) || 0; 75 | if (len === 0) { 76 | return false; 77 | } 78 | var n = parseInt(arguments[1], 10) || 0; 79 | var k; 80 | if (n >= 0) { 81 | k = n; 82 | } else { 83 | k = len + n; 84 | if (k < 0) {k = 0;} 85 | } 86 | var currentElement; 87 | while (k < len) { 88 | currentElement = O[k]; 89 | if (searchElement === currentElement || 90 | (searchElement !== searchElement && currentElement !== currentElement)) { // NaN !== NaN 91 | return true; 92 | } 93 | k++; 94 | } 95 | return false; 96 | }; 97 | } 98 | 99 | 100 | /** 101 | * Parses options from the passed in input string 102 | */ 103 | export function parseOptions(input) { 104 | let output = { 105 | binaryOptions: new Set(), 106 | }; 107 | input.split(',').forEach((option) => { 108 | option = option.trim(); 109 | if (option.startsWith('domain=')) { 110 | let domainString = option.split('=')[1].trim(); 111 | parseDomains(domainString, '|', output); 112 | } else { 113 | let optionWithoutPrefix = option[0] === '~' ? option.substring(1) : option; 114 | if (elementTypeMaskMap.has(optionWithoutPrefix)) { 115 | if (option[0] === '~') { 116 | output.skipElementTypeMask |= elementTypeMaskMap.get(optionWithoutPrefix); 117 | } else { 118 | output.elementTypeMask |= elementTypeMaskMap.get(optionWithoutPrefix); 119 | } 120 | } 121 | output.binaryOptions.add(option); 122 | } 123 | }); 124 | return output; 125 | } 126 | 127 | /** 128 | * Finds the first separator character in the input string 129 | */ 130 | function findFirstSeparatorChar(input, startPos) { 131 | for (let i = startPos; i < input.length; i++) { 132 | if (separatorCharacters.indexOf(input[i]) !== -1) { 133 | return i; 134 | } 135 | } 136 | return -1; 137 | } 138 | 139 | /** 140 | * Parses an HTML filter and modifies the passed in parsedFilterData 141 | * as necessary. 142 | * 143 | * @param input: The entire input string to consider 144 | * @param index: Index of the first hash 145 | * @param parsedFilterData: The parsedFilterData object to fill 146 | */ 147 | export function parseHTMLFilter(input, index, parsedFilterData) { 148 | let domainsStr = input.substring(0, index); 149 | parsedFilterData.options = {}; 150 | if (domainsStr.length > 0) { 151 | parseDomains(domainsStr, ',', parsedFilterData.options); 152 | } 153 | 154 | // The XOR parsedFilterData.elementHidingException is in case the rule already 155 | // was specified as exception handling with a prefixed @@ 156 | parsedFilterData.isException = !!(input[index + 1] === '@' ^ 157 | parsedFilterData.isException); 158 | if (input[index + 1] === '@') { 159 | // Skip passed the first # since @# is 2 chars same as ## 160 | index++; 161 | } 162 | parsedFilterData.htmlRuleSelector = input.substring(index + 2); 163 | } 164 | 165 | export function parseFilter(input, parsedFilterData, bloomFilter, exceptionBloomFilter) { 166 | input = input.trim(); 167 | parsedFilterData.rawFilter = input; 168 | 169 | // Check for comment or nothing 170 | if (input.length === 0) { 171 | return false; 172 | } 173 | 174 | // Check for comments 175 | let beginIndex = 0; 176 | if (input[beginIndex] === '[' || input[beginIndex] === '!') { 177 | parsedFilterData.isComment = true; 178 | return false; 179 | } 180 | 181 | // Check for exception instead of filter 182 | parsedFilterData.isException = input[beginIndex] === '@' && 183 | input[beginIndex + 1] === '@'; 184 | if (parsedFilterData.isException) { 185 | beginIndex = 2; 186 | } 187 | 188 | // Check for element hiding rules 189 | let index = input.indexOf('#', beginIndex); 190 | if (index !== -1) { 191 | if (input[index + 1] === '#' || input[index + 1] === '@') { 192 | parseHTMLFilter(input.substring(beginIndex), index - beginIndex, parsedFilterData); 193 | // HTML rules cannot be combined with other parsing, 194 | // other than @@ exception marking. 195 | return true; 196 | } 197 | } 198 | 199 | // Check for options, regex can have options too so check this before regex 200 | index = input.indexOf('$', beginIndex); 201 | if (index !== -1) { 202 | parsedFilterData.options = parseOptions(input.substring(index + 1)); 203 | // Get rid of the trailing options for the rest of the parsing 204 | input = input.substring(0, index); 205 | } else { 206 | parsedFilterData.options = {}; 207 | } 208 | 209 | // Check for a regex 210 | parsedFilterData.isRegex = input[beginIndex] === '/' && 211 | input[input.length - 1] === '/' && beginIndex !== input.length - 1; 212 | if (parsedFilterData.isRegex) { 213 | parsedFilterData.data = input.slice(beginIndex + 1, -1); 214 | return true; 215 | } 216 | 217 | // Check if there's some kind of anchoring 218 | if (input[beginIndex] === '|') { 219 | // Check for an anchored domain name 220 | if (input[beginIndex + 1] === '|') { 221 | parsedFilterData.hostAnchored = true; 222 | let indexOfSep = findFirstSeparatorChar(input, beginIndex + 1); 223 | if (indexOfSep === -1) { 224 | indexOfSep = input.length; 225 | } 226 | beginIndex += 2; 227 | parsedFilterData.host = input.substring(beginIndex, indexOfSep); 228 | } else { 229 | parsedFilterData.leftAnchored = true; 230 | beginIndex++; 231 | } 232 | } 233 | if (input[input.length - 1] === '|') { 234 | parsedFilterData.rightAnchored = true; 235 | input = input.substring(0, input.length - 1); 236 | } 237 | 238 | parsedFilterData.data = input.substring(beginIndex) || '*'; 239 | // Use the host bloom filter if the filter is a host anchored filter rule with no other data 240 | if (exceptionBloomFilter && parsedFilterData.isException) { 241 | exceptionBloomFilter.add(getFingerprint(parsedFilterData.data)); 242 | } else if (bloomFilter) { 243 | // To check for duplicates 244 | //if (bloomFilter.exists(getFingerprint(parsedFilterData.data))) { 245 | // console.log('duplicate found for data: ' + getFingerprint(parsedFilterData.data)); 246 | //} 247 | // console.log('parse:', parsedFilterData.data, 'fingerprint:', getFingerprint(parsedFilterData.data)); 248 | bloomFilter.add(getFingerprint(parsedFilterData.data)); 249 | } 250 | 251 | return true; 252 | } 253 | 254 | /** 255 | * Parses the set of filter rules and fills in parserData 256 | * @param input filter rules 257 | * @param parserData out parameter which will be filled 258 | * with the filters, exceptionFilters and htmlRuleFilters. 259 | */ 260 | export function parse(input, parserData) { 261 | parserData.bloomFilter = parserData.bloomFilter || new BloomFilterJS.BloomFilter(); 262 | parserData.exceptionBloomFilter = parserData.exceptionBloomFilter || new BloomFilterJS.BloomFilter(); 263 | parserData.filters = parserData.filters || []; 264 | parserData.noFingerprintFilters = parserData.noFingerprintFilters || []; 265 | parserData.exceptionFilters = parserData.exceptionFilters || []; 266 | parserData.htmlRuleFilters = parserData.htmlRuleFilters || []; 267 | let startPos = 0; 268 | let endPos = input.length; 269 | let newline = '\n'; 270 | while (startPos <= input.length) { 271 | endPos = input.indexOf(newline, startPos); 272 | if (endPos === -1) { 273 | newline = '\r'; 274 | endPos = input.indexOf(newline, startPos); 275 | } 276 | if (endPos === -1) { 277 | endPos = input.length; 278 | } 279 | let filter = input.substring(startPos, endPos); 280 | let parsedFilterData = {}; 281 | if (parseFilter(filter, parsedFilterData, parserData.bloomFilter, parserData.exceptionBloomFilter)) { 282 | let fingerprint = getFingerprint(parsedFilterData.data); 283 | if (parsedFilterData.htmlRuleSelector) { 284 | parserData.htmlRuleFilters.push(parsedFilterData); 285 | } else if (parsedFilterData.isException) { 286 | parserData.exceptionFilters.push(parsedFilterData); 287 | } else if (fingerprint.length > 0) { 288 | parserData.filters.push(parsedFilterData); 289 | } else { 290 | parserData.noFingerprintFilters.push(parsedFilterData); 291 | } 292 | } 293 | startPos = endPos + 1; 294 | } 295 | } 296 | 297 | /** 298 | * Obtains the domain index of the input filter line 299 | */ 300 | function getDomainIndex(input) { 301 | let index = input.indexOf(':'); 302 | ++index; 303 | while (input[index] === '/') { 304 | index++; 305 | } 306 | return index; 307 | } 308 | 309 | /** 310 | * Similar to str1.indexOf(filter, startingPos) but with 311 | * extra consideration to some ABP filter rules like ^. 312 | */ 313 | function indexOfFilter(input, filter, startingPos) { 314 | if (filter.length > input.length) { 315 | return -1; 316 | } 317 | 318 | let filterParts = filter.split('^'); 319 | let index = startingPos; 320 | let beginIndex = -1; 321 | let prefixedSeparatorChar = false; 322 | 323 | for (let f = 0; f < filterParts.length; f++) { 324 | if (filterParts[f] === '') { 325 | prefixedSeparatorChar = true; 326 | continue; 327 | } 328 | 329 | index = input.indexOf(filterParts[f], index); 330 | if (index === -1) { 331 | return -1; 332 | } 333 | if (beginIndex === -1) { 334 | beginIndex = index; 335 | } 336 | 337 | if (prefixedSeparatorChar) { 338 | if (separatorCharacters.indexOf(input[index - 1]) === -1) { 339 | return -1; 340 | } 341 | } 342 | // If we are in an in between filterPart 343 | if (f + 1 < filterParts.length && 344 | // and we have some chars left in the input past the last filter match 345 | input.length > index + filterParts[f].length) { 346 | if (separatorCharacters.indexOf(input[index + filterParts[f].length]) === -1) { 347 | return -1; 348 | } 349 | 350 | } 351 | 352 | prefixedSeparatorChar = false; 353 | } 354 | return beginIndex; 355 | } 356 | 357 | function getUrlHost(input) { 358 | let domainIndexStart = getDomainIndex(input); 359 | let domainIndexEnd = findFirstSeparatorChar(input, domainIndexStart); 360 | if (domainIndexEnd === -1) { 361 | domainIndexEnd = input.length; 362 | } 363 | return input.substring(domainIndexStart, domainIndexEnd); 364 | } 365 | 366 | function filterDataContainsOption(parsedFilterData, option) { 367 | return parsedFilterData.options && 368 | parsedFilterData.options.binaryOptions && 369 | parsedFilterData.options.binaryOptions.has(option); 370 | } 371 | 372 | function isThirdPartyHost(baseContextHost, testHost) { 373 | if (!testHost.endsWith(baseContextHost)) { 374 | return true; 375 | } 376 | 377 | let c = testHost[testHost.length - baseContextHost.length - 1]; 378 | return c !== '.' && c !== undefined; 379 | } 380 | 381 | // Determines if there's a match based on the options, this doesn't 382 | // mean that the filter rule shoudl be accepted, just that the filter rule 383 | // should be considered given the current context. 384 | // By specifying context params, you can filter out the number of rules which are 385 | // considered. 386 | function matchOptions(parsedFilterData, input, contextParams = {}) { 387 | if (contextParams.elementTypeMask !== undefined && parsedFilterData.options) { 388 | if (parsedFilterData.options.elementTypeMask !== undefined && 389 | !(parsedFilterData.options.elementTypeMask & contextParams.elementTypeMask)) { 390 | return false; 391 | } if (parsedFilterData.options.skipElementTypeMask !== undefined && 392 | parsedFilterData.options.skipElementTypeMask & contextParams.elementTypeMask) { 393 | return false; 394 | } 395 | } 396 | 397 | // Domain option check 398 | if (contextParams.domain !== undefined && parsedFilterData.options) { 399 | if (parsedFilterData.options.domains || parsedFilterData.options.skipDomains) { 400 | // Get the domains that should be considered 401 | let shouldBlockDomains = parsedFilterData.options.domains.filter((domain) => 402 | !isThirdPartyHost(domain, contextParams.domain)); 403 | 404 | let shouldSkipDomains = parsedFilterData.options.skipDomains.filter((domain) => 405 | !isThirdPartyHost(domain, contextParams.domain)); 406 | // Handle cases like: example.com|~foo.example.com should llow for foo.example.com 407 | // But ~example.com|foo.example.com should block for foo.example.com 408 | let leftOverBlocking = shouldBlockDomains.filter((shouldBlockDomain) => 409 | shouldSkipDomains.every((shouldSkipDomain) => 410 | isThirdPartyHost(shouldBlockDomain, shouldSkipDomain))); 411 | let leftOverSkipping = shouldSkipDomains.filter((shouldSkipDomain) => 412 | shouldBlockDomains.every((shouldBlockDomain) => 413 | isThirdPartyHost(shouldSkipDomain, shouldBlockDomain))); 414 | 415 | // If we have none left over, then we shouldn't consider this a match 416 | if (shouldBlockDomains.length === 0 && parsedFilterData.options.domains.length !== 0 || 417 | shouldBlockDomains.length > 0 && leftOverBlocking.length === 0 || 418 | shouldSkipDomains.length > 0 && leftOverSkipping.length > 0) { 419 | return false; 420 | } 421 | } 422 | } 423 | 424 | // If we're in the context of third-party site, then consider third-party option checks 425 | if (contextParams['third-party'] !== undefined) { 426 | // Is the current rule check for third party only? 427 | if (filterDataContainsOption(parsedFilterData, 'third-party')) { 428 | let inputHost = getUrlHost(input); 429 | let inputHostIsThirdParty = isThirdPartyHost(parsedFilterData.host, inputHost); 430 | if (inputHostIsThirdParty || !contextParams['third-party']) { 431 | return false; 432 | } 433 | } 434 | } 435 | 436 | return true; 437 | } 438 | 439 | /** 440 | * Given an individual parsed filter data determines if the input url should block. 441 | */ 442 | export function matchesFilter(parsedFilterData, input, contextParams = {}, cachedInputData = {}) { 443 | if (!matchOptions(parsedFilterData, input, contextParams)) { 444 | return false; 445 | } 446 | 447 | // Check for a regex match 448 | if (parsedFilterData.isRegex) { 449 | if (!parsedFilterData.regex) { 450 | parsedFilterData.regex = new RegExp(parsedFilterData.data); 451 | } 452 | return parsedFilterData.regex.test(input); 453 | } 454 | 455 | // Check for both left and right anchored 456 | if (parsedFilterData.leftAnchored && parsedFilterData.rightAnchored) { 457 | return parsedFilterData.data === input; 458 | } 459 | 460 | // Check for right anchored 461 | if (parsedFilterData.rightAnchored) { 462 | return input.slice(-parsedFilterData.data.length) === parsedFilterData.data; 463 | } 464 | 465 | // Check for left anchored 466 | if (parsedFilterData.leftAnchored) { 467 | return input.substring(0, parsedFilterData.data.length) === parsedFilterData.data; 468 | } 469 | 470 | // Check for domain name anchored 471 | if (parsedFilterData.hostAnchored) { 472 | if (!cachedInputData.currentHost) { 473 | cachedInputData.currentHost = getUrlHost(input); 474 | } 475 | 476 | return !isThirdPartyHost(parsedFilterData.host, cachedInputData.currentHost) && 477 | indexOfFilter(input, parsedFilterData.data) !== -1; 478 | } 479 | 480 | // Wildcard match comparison 481 | let parts = parsedFilterData.data.split('*'); 482 | let index = 0; 483 | for (let part of parts) { 484 | let newIndex = indexOfFilter(input, part, index); 485 | if (newIndex === -1) { 486 | return false; 487 | } 488 | index = newIndex + part.length; 489 | } 490 | 491 | return true; 492 | } 493 | 494 | function discoverMatchingPrefix(array, bloomFilter, str, prefixLen = fingerprintSize) { 495 | for (var i = 0; i < str.length - prefixLen + 1; i++) { 496 | let sub = str.substring(i, i + prefixLen); 497 | if (bloomFilter.exists(sub)) { 498 | array.push({ badFingerprint: sub, src: str}); 499 | // console.log('bad-fingerprint:', sub, 'for url:', str); 500 | } else { 501 | // console.log('good-fingerprint:', sub, 'for url:', str); 502 | } 503 | } 504 | } 505 | 506 | function hasMatchingFilters(filterList, parsedFilterData, input, contextParams, cachedInputData) { 507 | const foundFilter = filterList.find(parsedFilterData2 => 508 | matchesFilter(parsedFilterData2, input, contextParams, cachedInputData)); 509 | if (foundFilter && cachedInputData.matchedFilters && foundFilter.rawFilter) { 510 | 511 | // increment the count of matches 512 | // we store an extra object and a count so that in the future 513 | // other bits of information can be recorded during match time 514 | if (cachedInputData.matchedFilters[foundFilter.rawFilter]) { 515 | cachedInputData.matchedFilters[foundFilter.rawFilter].matches += 1; 516 | } else { 517 | cachedInputData.matchedFilters[foundFilter.rawFilter] = { matches: 1 }; 518 | } 519 | 520 | fs.writeFileSync('easylist-matches.json', JSON.stringify(cachedInputData.matchedFilters), 'utf-8'); 521 | } 522 | return !!foundFilter; 523 | } 524 | 525 | /** 526 | * Using the parserData rules will try to see if the input URL should be blocked or not 527 | * @param parserData The filter data obtained from a call to parse 528 | * @param input The input URL 529 | * @return true if the URL should be blocked 530 | */ 531 | export function matches(parserData, input, contextParams = {}, cachedInputData = { }) { 532 | cachedInputData.bloomNegativeCount = cachedInputData.bloomNegativeCount || 0; 533 | cachedInputData.bloomPositiveCount = cachedInputData.bloomPositiveCount || 0; 534 | cachedInputData.notMatchCount = cachedInputData.notMatchCount || 0; 535 | cachedInputData.badFingerprints = cachedInputData.badFingerprints || []; 536 | cachedInputData.matchedFilters = cachedInputData.matchedFilters || {}; 537 | 538 | cachedInputData.bloomFalsePositiveCount = cachedInputData.bloomFalsePositiveCount || 0; 539 | let hasMatchingNoFingerprintFilters; 540 | let cleanedInput = input.replace(/^https?:\/\//, ''); 541 | if (cleanedInput.length > maxUrlChars) { 542 | cleanedInput = cleanedInput.substring(0, maxUrlChars); 543 | } 544 | if (parserData.bloomFilter) { 545 | if (!parserData.bloomFilter.substringExists(cleanedInput, fingerprintSize)) { 546 | cachedInputData.bloomNegativeCount++; 547 | cachedInputData.notMatchCount++; 548 | // console.log('early return because of bloom filter check!'); 549 | hasMatchingNoFingerprintFilters = 550 | hasMatchingFilters(parserData.noFingerprintFilters, parserData, input, contextParams, cachedInputData); 551 | 552 | if (!hasMatchingNoFingerprintFilters) { 553 | return false; 554 | } 555 | } 556 | // console.log('looked for url in bloom filter and it said yes:', cleaned); 557 | } 558 | cachedInputData.bloomPositiveCount++; 559 | 560 | // console.log('not early return: ', input); 561 | delete cachedInputData.currentHost; 562 | cachedInputData.misses = cachedInputData.misses || new Set(); 563 | cachedInputData.missList = cachedInputData.missList || []; 564 | if (cachedInputData.missList.length > maxCached) { 565 | cachedInputData.misses.delete(cachedInputData.missList[0]); 566 | cachedInputData.missList = cachedInputData.missList.splice(1); 567 | } 568 | if (cachedInputData.misses.has(input)) { 569 | cachedInputData.notMatchCount++; 570 | // console.log('positive match for input: ', input); 571 | return false; 572 | } 573 | 574 | if (hasMatchingFilters(parserData.filters, parserData, input, contextParams, cachedInputData) || 575 | hasMatchingNoFingerprintFilters === true || hasMatchingNoFingerprintFilters === undefined && 576 | hasMatchingFilters(parserData.noFingerprintFilters, parserData, input, contextParams, cachedInputData)) { 577 | // Check for exceptions only when there's a match because matches are 578 | // rare compared to the volume of checks 579 | let exceptionBloomFilterMiss = parserData.exceptionBloomFilter && !parserData.exceptionBloomFilter.substringExists(cleanedInput, fingerprintSize); 580 | if (!exceptionBloomFilterMiss || hasMatchingFilters(parserData.exceptionFilters, parserData, input, contextParams, cachedInputData)) { 581 | cachedInputData.notMatchCount++; 582 | return false; 583 | } 584 | return true; 585 | } 586 | 587 | // The bloom filter had a false positive, se we checked for nothing! :'( 588 | // This is probably (but not always) an indication that the fingerprint selection should be tweaked! 589 | cachedInputData.missList.push(input); 590 | cachedInputData.misses.add(input); 591 | cachedInputData.notMatchCount++; 592 | cachedInputData.bloomFalsePositiveCount++; 593 | discoverMatchingPrefix(cachedInputData.badFingerprints, parserData.bloomFilter, cleanedInput); 594 | // console.log('positive match for input: ', input); 595 | return false; 596 | } 597 | 598 | /** 599 | * Obtains a fingerprint for the specified filter 600 | */ 601 | export function getFingerprint(str) { 602 | for (var i = 0; i < fingerprintRegexs.length; i++) { 603 | let fingerprintRegex = fingerprintRegexs[i]; 604 | let result = fingerprintRegex.exec(str); 605 | fingerprintRegex.lastIndex = 0; 606 | 607 | if (result && 608 | !badFingerprints.includes(result[1]) && 609 | !badSubstrings.find(badSubstring => result[1].includes(badSubstring))) { 610 | return result[1]; 611 | } 612 | if (result) { 613 | // console.log('checking again for str:', str, 'result:', result[1]); 614 | } else { 615 | // console.log('checking again for str, no result'); 616 | } 617 | } 618 | // This is pretty ugly but getting fingerprints is assumed to be used only when preprocessing and 619 | // in a live environment. 620 | if (str.length > 8) { 621 | // Remove first and last char 622 | return getFingerprint(str.slice(1, -1)); 623 | } 624 | // console.warn('Warning: Could not determine a good fingerprint for:', str); 625 | return ''; 626 | } 627 | -------------------------------------------------------------------------------- /src/badFingerprints.js: -------------------------------------------------------------------------------- 1 | export const badFingerprints = ['/google/','optimize','/widget.','load.php','95d2-d38','googleta','storage.','callback','leclick.','default_','lacement','/assets/','s/skins/','/themes/','-loader-','/header-','/public/','default/','d/jsonp/','gallery-','k/widget','-curve-m','eloader/','tooltip/','/footer/','/footer-','oogletag','google.c','uv_I-qM8','oogle.co','ogletags','bleclick','gletagse','letagser','eclick.n','click.ne','googlesy','ooglesyn','arousel/', 2 | 'm-0.0.12','gallery/','es-heade','-header-','message.','Callback','channel=','onp/pid=','ayer.swf','include.','amazonaw','allback&','s/client','article_','79942%22','allback_','_wrapper','wrapper.','m/tools/','takeover','_bottom_','mponent/','ference/','s/index.','ebottom.','&domain=','atic/js/','ad_type=','u4eSmzTp','ign=null','aterial.','/upload/','amazon.c','b50c29dd','dformat=','rvices.c','eywords=','2n%22:0,','C&v=404&','mazon.co', 'vices.co', 's/views/', 'hardware', 'es-heade']; 3 | export const badSubstrings = ['com', 'net', 'http', 'image', 'www', 'img', '.js', 'oogl', 'min.', 'que', 'synd', 'dicat', 'templ', 'tube', 'page', 'home', 'mepa', 'mplat', 'tati', 'user', 'aws', 'omp', 'icros', 'espon', 'org', 'nalyti', 'acebo', 'lead', 'con', 'count', 'vers', 'pres', 'aff', 'atio', 'tent', 'ative', 'en_', 'fr_', 'es_', 'ha1', 'ha2', 'live', 'odu', 'esh', 'adm', 'crip', 'ect', 'tics', 'edia', 'ini', 'yala', 'ana', 'rac', 'trol', 'tern', 'card', 'yah', 'tion', 'erv', '.co', 'lug', 'eat', 'ugi', 'ates', 'loud', 'ner', 'earc', 'atd', 'fro', 'ruct', 'sour', 'news', 'ddr', 'htm', 'fram', 'dar', 'flas', 'lay', 'orig', 'uble', 'om/', 'ext', 'link', '.png', 'com/', 'tri', 'but', 'vity', 'spri']; 4 | -------------------------------------------------------------------------------- /src/extractInfo.js: -------------------------------------------------------------------------------- 1 | import {parse, getFingerprint} from './abp-filter-parser.js'; 2 | import fs from 'fs'; 3 | import {BloomFilter} from 'bloom-filter-js'; 4 | 5 | console.log(getFingerprint('oauth.googleusercontent.com/gadgets/js/core:rpc:shindig.random:shindig.sha1.js?c=2')); 6 | 7 | 8 | function discoverMatchingPrefix(bloomFilter, str, prefixLen = 8) { 9 | if (!bloomFilter.substringExists(str, prefixLen)) { 10 | console.log('no substring exists for url:', str); 11 | } 12 | for (var i = 0; i < str.length - prefixLen + 1; i++) { 13 | let sub = str.substring(i, i + prefixLen); 14 | let cleaned = sub.replace(/^https?:\/\//, ''); 15 | if (bloomFilter.exists(cleaned)) { 16 | console.log('bad-fingerprint:', sub, 'for url:', str); 17 | } 18 | } 19 | } 20 | 21 | let sitesToCheck = [ 22 | 'http://c.s-microsoft.com/en-ca/CMSImages/store_symbol.png?version=e2eecca5-4550-10c6-57b1-5114804a4c01', 23 | ]; 24 | 25 | fs.readFile('./test/data/easylist.txt', 'utf8', function (err,data) { 26 | if (err) { 27 | return console.log(err); 28 | } 29 | 30 | let parserData = {}; 31 | parse(data, parserData); 32 | 33 | // Write out the bloom filter data files 34 | fs.writeFileSync('dist/bloomFilterData', new Buffer(new Uint8Array(parserData.bloomFilter.toJSON()))); 35 | fs.writeFileSync('dist/exceptionBloomFilterData', new Buffer(new Uint8Array(parserData.exceptionBloomFilter.toJSON()))); 36 | 37 | let readData = fs.readFileSync('./dist/bloomFilterData'); 38 | let bloomData = new BloomFilter(new Uint8Array(readData)); 39 | console.log(bloomData); 40 | let bloomFilter = new BloomFilter(bloomData); 41 | 42 | //console.log('Number of filters processed: ', parserData.filterCount); 43 | 44 | 45 | console.log('-------'); 46 | sitesToCheck.forEach(s => 47 | discoverMatchingPrefix(bloomFilter/*parserData.bloomFilter*/, s)); 48 | 49 | // WRite out the POD cached filter data JSM 50 | delete parserData.bloomFilter; 51 | delete parserData.exceptionBloomFilter; 52 | let cachedFilterDataJSM = 'dump("######Loaded cached-rules.jsm\\n");\nthis.EXPORTED_SYMBOLS = ["parserData"];\nthis.parserData = ' + JSON.stringify(parserData) + ';\n'; 53 | fs.writeFileSync('cachedFilterData.jsm', cachedFilterDataJSM); 54 | }); 55 | -------------------------------------------------------------------------------- /test/helpers.js: -------------------------------------------------------------------------------- 1 | require('babel-polyfill'); 2 | -------------------------------------------------------------------------------- /test/options-test.js: -------------------------------------------------------------------------------- 1 | import assert from 'assert'; 2 | import {parseFilter, parseOptions} from '../src/abp-filter-parser.js'; 3 | 4 | // Maps option strings to [set of binary options, domains, skipDomains] 5 | let splitOptions = new Map([ 6 | ['subdocument,third-party', [ 7 | new Set(['subdocument', 'third-party']), 8 | undefined, 9 | undefined, 10 | ]], ['object-subrequest,script,domain=~msnbc.msn.com|~www.nbcnews.com', [ 11 | new Set(['object-subrequest', 'script']), 12 | [], 13 | ['msnbc.msn.com', 'www.nbcnews.com'] 14 | ]], ['object-subrequest,script,domain=~msnbc.msn.com|~www.nbcnews.com', [ 15 | new Set(['object-subrequest', 'script']), 16 | [], 17 | ['msnbc.msn.com', 'www.nbcnews.com'] 18 | ]], ['~document,xbl,domain=~foo|bar|baz,~collapse,domain=foo.xbl|bar', [ 19 | new Set(['~document', 'xbl', '~collapse']), 20 | ['bar', 'baz', 'foo.xbl', 'bar'], 21 | ['foo'] 22 | ]], ['domain=~example.com|foo.example.com,script', [ 23 | new Set(['script']), 24 | ['foo.example.com'], 25 | ['example.com'] 26 | ]], 27 | ]); 28 | 29 | // Maps option strings to [domains, skipDomains] 30 | let domainOptionStrings = new Map([ 31 | ['domain=example.com', [ 32 | ['example.com'], 33 | [] 34 | ]], ['domain=example.com|example.net', [ 35 | ['example.com', 'example.net'], 36 | [] 37 | ]], ['domain=~example.com', [ 38 | [], 39 | ['example.com'], 40 | ]], ['domain=example.com|~foo.example.com', [ 41 | ['example.com'], 42 | ['foo.example.com'] 43 | ]], ['domain=~foo.example.com|example.com', [ 44 | ['example.com'], 45 | ['foo.example.com'], 46 | ]], 47 | ['domain=example.com|example.net', [ 48 | ['example.com', 'example.net'], 49 | [], 50 | ]], 51 | ['domain=example.com|~foo.example.com', [ 52 | ['example.com'], 53 | ['foo.example.com'], 54 | ]], 55 | ['domain=~msnbc.msn.com|~www.nbcnews.com', [ 56 | [], 57 | ['msnbc.msn.com', 'www.nbcnews.com'], 58 | ]], 59 | ]); 60 | 61 | let parseOptionTests = new Map([ 62 | ['domain=foo.bar', [ 63 | undefined, 64 | undefined, 65 | undefined, 66 | ]], ['+Ads/$~stylesheet', [ 67 | new Set(['~stylesheet']), 68 | undefined, 69 | undefined, 70 | ]], ['-advertising-$domain=~advertise.bingads.domain.com', [ 71 | new Set(), 72 | [], 73 | ['advertise.bingads.domain.com'], 74 | ]], ['.se/?placement=$script,third-party', [ 75 | new Set(['script', 'third-party']), 76 | undefined, 77 | undefined, 78 | ]], ['||tst.net^$object-subrequest,third-party,domain=domain1.com|domain5.com', [ 79 | new Set(['object-subrequest', 'third-party']), 80 | ['domain1.com', 'domain5.com'], 81 | [], 82 | ]], 83 | ]); 84 | 85 | describe('options#parseOptions()', function() { 86 | it('Option parsing should split options properly', function() { 87 | splitOptions.forEach(([expectedOptions, domains, skipDomains], optionsString) => { 88 | let options = parseOptions(optionsString); 89 | assert.equal(JSON.stringify(options.binaryOptions), JSON.stringify(expectedOptions)); 90 | assert.equal(JSON.stringify(options.domains), JSON.stringify(domains)); 91 | assert.equal(JSON.stringify(options.skipDomains), JSON.stringify(skipDomains)); 92 | }); 93 | }); 94 | it('domain rule types should be properly parsed', function() { 95 | domainOptionStrings.forEach(([domains, skipDomains], optionsString) => { 96 | let options = parseOptions(optionsString); 97 | assert.equal(JSON.stringify(options.domains), JSON.stringify(domains)); 98 | assert.equal(JSON.stringify(options.skipDomains), JSON.stringify(skipDomains)); 99 | }); 100 | }); 101 | it('parseFilter for full rules properly extracts options', function() { 102 | parseOptionTests.forEach(([expectedOptions, domains, skipDomains], filterString) => { 103 | let parsedFilterOptions = {}; 104 | parseFilter(filterString, parsedFilterOptions); 105 | assert.equal(JSON.stringify(parsedFilterOptions.options.binaryOptions), JSON.stringify(expectedOptions)); 106 | assert.equal(JSON.stringify(parsedFilterOptions.options.domains), JSON.stringify(domains)); 107 | assert.equal(JSON.stringify(parsedFilterOptions.options.skipDomains), JSON.stringify(skipDomains)); 108 | }); 109 | }); 110 | }); 111 | -------------------------------------------------------------------------------- /test/parser-test.js: -------------------------------------------------------------------------------- 1 | import assert from 'assert'; 2 | import {parse, parseFilter, matches, matchesFilter, elementTypes} from '../src/abp-filter-parser.js'; 3 | import fs from 'fs'; 4 | 5 | let testRules = new Map([ 6 | ['/banner/*/img', { 7 | isRegex: false, 8 | isException: false, 9 | elementHiding: undefined, 10 | elementHidingException: undefined, 11 | hostAnchored: undefined, 12 | leftAnchored: undefined, 13 | rightAnchored: undefined, 14 | options: {}, 15 | data: '/banner/*/img', 16 | blocked: [ 17 | 'http://example.com/banner/foo/img', 18 | 'http://example.com/banner/foo/bar/img?param', 19 | 'http://example.com/banner//img/foo', 20 | 'http://example.com/banner//img.gif', 21 | ], 22 | notBlocked: [ 23 | 'http://example.com/banner/', 24 | 'http://example.com/banner/img', 25 | 'http://example.com/img/banner/', 26 | ] 27 | }], 28 | ['/banner/*/img^', { 29 | isRegex: false, 30 | isException: false, 31 | elementHiding: undefined, 32 | elementHidingException: undefined, 33 | hostAnchored: undefined, 34 | leftAnchored: undefined, 35 | rightAnchored: undefined, 36 | options: {}, 37 | data: '/banner/*/img^', 38 | blocked: [ 39 | 'http://example.com/banner/foo/img', 40 | 'http://example.com/banner/foo/bar/img?param', 41 | 'http://example.com/banner//img/foo', 42 | ], 43 | notBlocked: [ 44 | 'http://example.com/banner/img', 45 | 'http://example.com/banner/foo/imgraph', 46 | 'http://example.com/banner/foo/img.gif', 47 | ] 48 | }], 49 | ['||ads.example.com^', { 50 | isRegex: false, 51 | isException: false, 52 | elementHiding: undefined, 53 | elementHidingException: undefined, 54 | hostAnchored: true, 55 | leftAnchored: undefined, 56 | rightAnchored: undefined, 57 | options: {}, 58 | data: 'ads.example.com^', 59 | blocked: [ 60 | 'http://ads.example.com/foo.gif', 61 | 'http://server1.ads.example.com/foo.gif', 62 | 'https://ads.example.com:8000/', 63 | ], 64 | notBlocked: [ 65 | 'http://ads.example.com.ua/foo.gif', 66 | 'http://example.com/redirect/http://ads.example.com/', 67 | ], 68 | }], 69 | ['|http://example.com/|', { 70 | isRegex: false, 71 | isException: false, 72 | elementHiding: undefined, 73 | elementHidingException: undefined, 74 | hostAnchored: undefined, 75 | leftAnchored: true, 76 | rightAnchored: true, 77 | options: {}, 78 | data: 'http://example.com/', 79 | blocked: [ 80 | 'http://example.com/' 81 | ], 82 | notBlocked: [ 83 | 'http://example.com/foo.gif', 84 | 'http://example.info/redirect/http://example.com/', 85 | ], 86 | }], 87 | ['swf|', { 88 | isRegex: false, 89 | isException: false, 90 | elementHiding: undefined, 91 | elementHidingException: undefined, 92 | hostAnchored: undefined, 93 | leftAnchored: undefined, 94 | rightAnchored: true, 95 | options: {}, 96 | data: 'swf', 97 | blocked: [ 98 | 'http://example.com/annoyingflash.swf', 99 | ], 100 | notBlocked: [ 101 | 'http://example.com/swf/index.html' 102 | ], 103 | }], 104 | ['|http://baddomain.example/', { 105 | isRegex: false, 106 | isException: false, 107 | elementHiding: undefined, 108 | elementHidingException: undefined, 109 | hostAnchored: undefined, 110 | leftAnchored: true, 111 | rightAnchored: undefined, 112 | options: {}, 113 | data: 'http://baddomain.example/', 114 | blocked: [ 115 | 'http://baddomain.example/banner.gif', 116 | ], 117 | notBlocked: [ 118 | 'http://gooddomain.example/analyze?http://baddomain.example', 119 | ], 120 | }], 121 | ['||example.com/banner.gif', { 122 | isRegex: false, 123 | isException: false, 124 | elementHiding: undefined, 125 | elementHidingException: undefined, 126 | hostAnchored: true, 127 | leftAnchored: undefined, 128 | rightAnchored: undefined, 129 | options: {}, 130 | data: 'example.com/banner.gif', 131 | blocked: [ 132 | 'http://example.com/banner.gif', 133 | 'https://example.com/banner.gif', 134 | 'http://www.example.com/banner.gif', 135 | ], 136 | notBlocked: [ 137 | 'http://badexample.com/banner.gif', 138 | 'http://gooddomain.example/analyze?http://example.com/banner.gif', 139 | 'http://example.com.au/banner.gif', 140 | 'http://example.com/banner2.gif', 141 | ], 142 | }], 143 | ['http://example.com^', { 144 | isRegex: false, 145 | isException: false, 146 | elementHiding: undefined, 147 | elementHidingException: undefined, 148 | hostAnchored: undefined, 149 | leftAnchored: undefined, 150 | rightAnchored: undefined, 151 | options: {}, 152 | data: 'http://example.com^', 153 | blocked: [ 154 | 'http://example.com/', 155 | 'http://example.com:8000/ ', 156 | ], 157 | notBlocked: [], 158 | }], 159 | ['^example.com^', { 160 | isRegex: false, 161 | isException: false, 162 | elementHiding: undefined, 163 | elementHidingException: undefined, 164 | hostAnchored: undefined, 165 | leftAnchored: undefined, 166 | rightAnchored: undefined, 167 | options: {}, 168 | data: '^example.com^', 169 | blocked: [ 170 | 'http://example.com:8000/foo.bar?a=12&b=%D1%82%D0%B5%D1%81%D1%82', 171 | ], 172 | notBlocked: [], 173 | }], 174 | ['^%D1%82%D0%B5%D1%81%D1%82^', { 175 | isRegex: false, 176 | isException: false, 177 | elementHiding: undefined, 178 | elementHidingException: undefined, 179 | hostAnchored: undefined, 180 | leftAnchored: undefined, 181 | rightAnchored: undefined, 182 | options: {}, 183 | data: '^%D1%82%D0%B5%D1%81%D1%82^', 184 | blocked: [ 185 | 'http://example.com:8000/foo.bar?a=12&b=%D1%82%D0%B5%D1%81%D1%82', 186 | ], 187 | notBlocked: [ 188 | 'http://example.com:8000/foo.bar?a=12&b%D1%82%D0%B5%D1%81%D1%823', 189 | ], 190 | }], 191 | ['^foo.bar^', { 192 | isRegex: false, 193 | isException: false, 194 | elementHiding: undefined, 195 | elementHidingException: undefined, 196 | hostAnchored: undefined, 197 | leftAnchored: undefined, 198 | rightAnchored: undefined, 199 | options: {}, 200 | data: '^foo.bar^', 201 | blocked: [ 202 | 'http://example.com:8000/foo.bar?a=12&b=%D1%82%D0%B5%D1%81%D1%82' 203 | ], 204 | notBlocked: [ 205 | ], 206 | }], 207 | ['/banner\\d+/', { 208 | isRegex: true, 209 | isException: false, 210 | elementHiding: undefined, 211 | elementHidingException: undefined, 212 | hostAnchored: undefined, 213 | leftAnchored: undefined, 214 | rightAnchored: undefined, 215 | options: {}, 216 | data: 'banner\\d+', 217 | blocked: [ 218 | 'banner123', 219 | 'testbanner1', 220 | ], 221 | notBlocked: [ 222 | 'banners', 223 | 'banners123', 224 | ], 225 | }], 226 | ['||static.tumblr.com/dhqhfum/WgAn39721/cfh_header_banner_v2.jpg', { 227 | isRegex: false, 228 | isException: false, 229 | elementHiding: undefined, 230 | elementHidingException: undefined, 231 | hostAnchored: true, 232 | leftAnchored: undefined, 233 | rightAnchored: undefined, 234 | options: {}, 235 | data: 'static.tumblr.com/dhqhfum/WgAn39721/cfh_header_banner_v2.jpg', 236 | blocked: [ 237 | 'http://static.tumblr.com/dhqhfum/WgAn39721/cfh_header_banner_v2.jpg', 238 | ], 239 | notBlocked: [ 240 | ], 241 | }], 242 | ['||googlesyndication.com/safeframe/$third-party', { 243 | isRegex: false, 244 | isException: false, 245 | elementHiding: undefined, 246 | elementHidingException: undefined, 247 | hostAnchored: true, 248 | leftAnchored: undefined, 249 | rightAnchored: undefined, 250 | options: { 'binaryOptions': ['third-party'] }, 251 | data: 'googlesyndication.com/safeframe/', 252 | blocked: [ 253 | 'http://tpc.googlesyndication.com/safeframe/1-0-2/html/container.html#xpc=sf-gdn-exp-2&p=http%3A//slashdot.org;', 254 | ], 255 | notBlocked: [ 256 | ], 257 | }], 258 | ]); 259 | 260 | let exceptionRules = new Map([ 261 | [`adv 262 | @@advice.`, { 263 | blocked: [ 264 | 'http://example.com/advert.html', 265 | ], 266 | notBlocked: [ 267 | 'http://example.com/advice.html', 268 | ] 269 | }], 270 | [`@@advice. 271 | adv`, { 272 | blocked: [ 273 | 'http://example.com/advert.html' 274 | ], 275 | notBlocked: [ 276 | 'http://example.com/advice.html' 277 | ], 278 | }], 279 | [`@@|http://example.com 280 | @@advice. 281 | adv 282 | !foo`, { 283 | blocked: [ 284 | 'http://examples.com/advert.html', 285 | ], 286 | notBlocked: [ 287 | 'http://example.com/advice.html', 288 | 'http://example.com/advert.html', 289 | 'http://examples.com/advice.html', 290 | 'http://examples.com/#!foo', 291 | ], 292 | }], 293 | ]); 294 | 295 | // Map from a key with a ABP filter rule to a set of [testUrl, context params, should block?] 296 | let optionRules = new Map([ 297 | ['||example.com', new Set([ 298 | ['http://example.com', {'third-party': true}, true], 299 | ['http://example2.com', {'third-party': true}, false], 300 | ['http://example.com', {'third-party': false}, true], 301 | ])], ['||example.com^$third-party', new Set([ 302 | ['http://example.com', {'third-party': true}, true], 303 | ['http://example.com', {'third-party': false}, false], 304 | ['http://ad.example.com', {'third-party': true}, true], 305 | ['http://ad.example.com', {'third-party': false}, false], 306 | ['http://example2.com', {'third-party': true}, false], 307 | ['http://example2.com', {'third-party': false}, false], 308 | ['http://example.com.au', {'third-party': true}, false], 309 | ['http://example.com.au', {'third-party': false}, false], 310 | ])], ['||example.com^$third-party,~script', new Set([ 311 | ['http://example.com', {'third-party': true, elementTypeMask: elementTypes.SCRIPT}, false], 312 | ['http://example.com', {'third-party': true, elementTypeMask: elementTypes.OTHER}, true], 313 | ['http://example2.com', {'third-party': true, elementTypeMask: elementTypes.OTHER}, false], 314 | ['http://example.com', {'third-party': false, elementTypeMask: elementTypes.OTHER}, false], 315 | ])], ['adv$domain=example.com|example.net', new Set([ 316 | ['http://example.net/adv', {'domain': 'example.net'}, true], 317 | ['http://somewebsite.com/adv', {'domain': 'example.com'}, true], 318 | ['http://www.example.net/adv', {'domain': 'www.example.net'}, true], 319 | ['http://my.subdomain.example.com/adv', {'domain': 'my.subdomain.example.com'}, true], 320 | ['http://example.com/adv', {'domain': 'badexample.com'}, false], 321 | ['http://example.com/adv', {'domain': 'otherdomain.net'}, false], 322 | ['http://example.net/ad', {'domain': 'example.net'}, false], 323 | ])], ['adv$domain=example.com|~foo.example.com', new Set([ 324 | ['http://example.net/adv', {'domain': 'example.com'}, true], 325 | ['http://example.net/adv', {'domain': 'foo.example.com'}, false], 326 | ['http://example.net/adv', {'domain': 'www.foo.example.com'}, false], 327 | ])], ['adv$domain=~example.com|foo.example.com', new Set([ 328 | ['http://example.net/adv', {'domain': 'example.com'}, false], 329 | ['http://example.net/adv', {'domain': 'foo.example.com'}, true], 330 | ['http://example.net/adv', {'domain': 'www.foo.example.com'}, true], 331 | ])], ['adv$domain=~example.com', new Set([ 332 | ['http://example.net/adv', {'domain': 'otherdomain.com'}, true], 333 | ['http://somewebsite.com/adv', {'domain': 'example.com'}, false], 334 | ])], ['adv$domain=~example.com|~example.net', new Set([ 335 | ['http://example.net/adv', {'domain': 'example.net'}, false], 336 | ['http://somewebsite.com/adv', {'domain': 'example.com'}, false], 337 | ['http://www.example.net/adv', {'domain': 'www.example.net'}, false], 338 | ['http://my.subdomain.example.com/adv', {'domain': 'my.subdomain.example.com'}, false], 339 | ['http://example.com/adv', {'domain': 'badexample.com'}, true], 340 | ['http://example.com/adv', {'domain': 'otherdomain.net'}, true], 341 | ['http://example.net/ad', {'domain': 'example.net'}, false], 342 | ])], ['adv$domain=example.com|~example.net', new Set([ 343 | ['http://example.net/adv', {'domain': 'example.net'}, false], 344 | ['http://somewebsite.com/adv', {'domain': 'example.com'}, true], 345 | ['http://www.example.net/adv', {'domain': 'www.example.net'}, false], 346 | ['http://my.subdomain.example.com/adv', {'domain': 'my.subdomain.example.com'}, true], 347 | ['http://example.com/adv', {'domain': 'badexample.com'}, false], 348 | ['http://example.com/adv', {'domain': 'otherdomain.net'}, false], 349 | ['http://example.net/ad', {'domain': 'example.net'}, false], 350 | ])], ['adv$domain=example.com|~foo.example.com,script', new Set([ 351 | ['http://example.net/adv', {'domain': 'example.com', elementTypeMask: elementTypes.SCRIPT}, true], 352 | ['http://example.net/adv', {'domain': 'foo.example.com', elementTypeMask: elementTypes.SCRIPT}, false], 353 | ['http://example.net/adv', {'domain': 'www.foo.example.com', elementTypeMask: elementTypes.SCRIPT}, false], 354 | ['http://example.net/adv', {'domain': 'example.com', elementTypeMask: elementTypes.OTHER}, false], 355 | ['http://example.net/adv', {'domain': 'foo.example.com', elementTypeMask: elementTypes.OTHER}, false], 356 | ['http://example.net/adv', {'domain': 'www.foo.example.com', elementTypeMask: elementTypes.OTHER}, false], 357 | ])], [`adv 358 | @@advice.$~script`, new Set([ 359 | ['http://example.com/advice.html', {elementTypeMask: elementTypes.OTHER}, false], 360 | ['http://example.com/advice.html', {elementTypeMask: elementTypes.SCRIPT}, true], 361 | ['http://example.com/advert.html', {elementTypeMask: elementTypes.OTHER}, true], 362 | ['http://example.com/advert.html', {elementTypeMask: elementTypes.SCRIPT}, true], 363 | ])], 364 | ]); 365 | 366 | 367 | describe('parser#parseFilter()', function() { 368 | it('should extract proper parsing info for filter rules', function() { 369 | let cachedInputData = {}; 370 | testRules.forEach((testRule, key) => { 371 | let parsedFilterData = {}; 372 | parseFilter(key, parsedFilterData); 373 | for (let p in testRule) { 374 | if (!['blocked', 'notBlocked'].includes(p)) { 375 | assert.equal(JSON.stringify(testRule[p]), 376 | JSON.stringify(parsedFilterData[p]), 377 | `for property ${p}: ${testRule[p]} !== ${parsedFilterData[p]}`); 378 | } 379 | } 380 | for (let input of testRule.blocked) { 381 | // With cached data 382 | assert(matchesFilter(parsedFilterData, input, cachedInputData), 383 | `${key} should block ${input}`); 384 | // Without cached data 385 | assert(matchesFilter(parsedFilterData, input), 386 | `${key} should block ${input}`); 387 | 388 | } 389 | for (let input of testRule.notBlocked) { 390 | // With cached data 391 | assert(!matchesFilter(parsedFilterData, input, cachedInputData), 392 | `${key} should not block ${input}`); 393 | // Without cached data 394 | assert(!matchesFilter(parsedFilterData, input), 395 | `${key} should not block ${input}`); 396 | } 397 | }); 398 | }); 399 | 400 | it('Exception tests work correctly', function() { 401 | exceptionRules.forEach((testRule, key) => { 402 | let parserData = {}; 403 | parse(key, parserData); 404 | for (let input of testRule.blocked) { 405 | assert(matches(parserData, input), 406 | `${key} should block ${input}`); 407 | } 408 | for (let input of testRule.notBlocked) { 409 | assert(!matches(parserData, input), 410 | `${key} should not block ${input}`); 411 | } 412 | }); 413 | }); 414 | 415 | it('Option and param context rules work correctly', function() { 416 | // Map from a key with a ABP filter rule to a set of [testUrl, context params, should block?] 417 | optionRules.forEach((setOfTests, filterRule) => { 418 | let parserData = {}; 419 | parse(filterRule, parserData); 420 | setOfTests.forEach((testData) => { 421 | let [testUrl, contextParams, shouldBlock] = testData; 422 | assert.equal(matches(parserData, testUrl, contextParams), shouldBlock, 423 | `${filterRule} should ` + (shouldBlock ? 'block' : 'not block') + ` ${testUrl} ` + 424 | `with context params: ${JSON.stringify(contextParams)}`); 425 | }); 426 | }); 427 | }); 428 | }); 429 | 430 | describe('parser#parse()', function() { 431 | it('should parse EasyList without failing', function(cb) { 432 | this.timeout(5000); 433 | fs.readFile('./test/data/easylist.txt', 'utf8', function (err, data) { 434 | if (err) { 435 | return console.log(err); 436 | } 437 | let parserData = {}; 438 | parse(data, parserData); 439 | // Num lines minus (num empty lines + num comment lines) 440 | assert.equal(parserData.htmlRuleFilters.length, 26465); 441 | assert.equal(parserData.filters.length + parserData.noFingerprintFilters.length, 18096); 442 | assert.equal(parserData.exceptionFilters.length, 2975); 443 | cb(); 444 | }); 445 | }); 446 | it('Calling parse amongst 2 different lists should preserve both sets of rules', function() { 447 | let parserData = {}; 448 | parse(`adv 449 | @@test 450 | ###test`, parserData); 451 | parse(`adv2 452 | @@test2 453 | ###test2 454 | adv3 455 | @@test3 456 | ###test3`, parserData); 457 | assert.equal(parserData.htmlRuleFilters.length, 3); 458 | assert.equal(parserData.filters.length, 0); 459 | assert.equal(parserData.noFingerprintFilters.length, 3); 460 | assert.equal(parserData.exceptionFilters.length, 3); 461 | }); 462 | }); 463 | -------------------------------------------------------------------------------- /test/rule-types-test.js: -------------------------------------------------------------------------------- 1 | import assert from 'assert'; 2 | import {parseFilter} from '../src/abp-filter-parser.js'; 3 | 4 | let commentRules = new Set([ 5 | '[Adblock Plus 2.0]', 6 | '! Checksum: nVIXktYXKU6M+cu+Txkhuw', 7 | '!/cb.php?sub$script,third-party', 8 | '!@@/cb.php?sub', 9 | '!###ADSLOT_SKYSCRAPER', 10 | '! *** easylist:easylist/easylist_whitelist_general_hide.txt ***', 11 | ' !###ADSLOT_SKYSCRAPER', 12 | ]); 13 | 14 | let elementHidingRules = new Set([ 15 | ' ###ADSLOT_SKYSCRAPER', 16 | '###ADSLOT_SKYSCRAPER', 17 | '@@###ADSLOT_SKYSCRAPER', 18 | '##.adsBox', 19 | 'eee.se#@##adspace_top', 20 | 'domain1.com,domain2.com#@##adwrapper', 21 | 'edgesuitedomain.net#@##ad-unit', 22 | 'mydomain.com#@#.ad-unit', 23 | '##a[href^=\'http://affiliate.sometracker.com/\']', 24 | ]); 25 | 26 | describe('rule-types#parse()', function(){ 27 | it('rule types should be properly detected', function(){ 28 | commentRules.forEach(commentRule => { 29 | let parsedFilterData = {}; 30 | parseFilter(commentRule, parsedFilterData); 31 | assert(parsedFilterData.isComment, `${commentRule} should be marked as a comment`); 32 | }); 33 | elementHidingRules.forEach(elementHidingRule => { 34 | let parsedFilterData = {}; 35 | parseFilter(elementHidingRule, parsedFilterData); 36 | assert(parsedFilterData.htmlRuleSelector.length > 0); 37 | assert(parsedFilterData.isException !== undefined); 38 | }); 39 | }); 40 | }); 41 | --------------------------------------------------------------------------------