├── .gitignore ├── CODE_OF_CONDUCT.md ├── LICENSE ├── README.md ├── package.json ├── public ├── .well-known │ └── gpc.json ├── client.js ├── prism-vsc-dark-plus.css ├── prism.js └── style.css ├── server.js ├── shrinkwrap.yaml └── views ├── index.ejs └── partials ├── dom-signal-status.ejs ├── footer.ejs ├── header-signal-status.ejs └── well-known-status.ejs /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled source 2 | *.com 3 | *.class 4 | *.dll 5 | *.exe 6 | *.o 7 | *.so 8 | 9 | # Packages 10 | # it's better to unpack these files and commit the raw source 11 | # git has its own built in compression methods 12 | *.7z 13 | *.dmg 14 | *.gz 15 | *.iso 16 | *.jar 17 | *.rar 18 | *.tar 19 | *.zip 20 | 21 | # Logs and databases 22 | *.log 23 | *.sql 24 | *.sqlite 25 | 26 | # OS generated files 27 | .DS_Store 28 | .DS_Store? 29 | ._* 30 | .Spotlight-V100 31 | .Trashes 32 | ehthumbs.db 33 | Thumbs.db 34 | 35 | # Byte-compiled / optimized / DLL files 36 | __pycache__/ 37 | *.py[cod] 38 | *$py.class 39 | 40 | # C extensions 41 | *.so 42 | 43 | # Distribution / packaging 44 | .Python 45 | build/ 46 | develop-eggs/ 47 | downloads/ 48 | eggs/ 49 | .eggs/ 50 | lib/ 51 | lib64/ 52 | parts/ 53 | sdist/ 54 | var/ 55 | wheels/ 56 | pip-wheel-metadata/ 57 | share/python-wheels/ 58 | *.egg-info/ 59 | .installed.cfg 60 | *.egg 61 | MANIFEST 62 | 63 | # PyInstaller 64 | # Usually these files are written by a python script from a template 65 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 66 | *.manifest 67 | *.spec 68 | 69 | # Installer logs 70 | pip-log.txt 71 | pip-delete-this-directory.txt 72 | 73 | # Unit test / coverage reports 74 | htmlcov/ 75 | .tox/ 76 | .nox/ 77 | .coverage 78 | .coverage.* 79 | .cache 80 | nosetests.xml 81 | coverage.xml 82 | *.cover 83 | *.py,cover 84 | .hypothesis/ 85 | .pytest_cache/ 86 | 87 | # Translations 88 | *.mo 89 | *.pot 90 | 91 | # Django stuff: 92 | *.log 93 | local_settings.py 94 | db.sqlite3 95 | db.sqlite3-journal 96 | 97 | # Flask stuff: 98 | instance/ 99 | .webassets-cache 100 | 101 | # Scrapy stuff: 102 | .scrapy 103 | 104 | # Sphinx documentation 105 | docs/_build/ 106 | 107 | # PyBuilder 108 | target/ 109 | 110 | # Jupyter Notebook 111 | .ipynb_checkpoints 112 | 113 | # IPython 114 | profile_default/ 115 | ipython_config.py 116 | 117 | # pyenv 118 | .python-version 119 | 120 | # pipenv 121 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 122 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 123 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 124 | # install all needed dependencies. 125 | #Pipfile.lock 126 | 127 | # celery beat schedule file 128 | celerybeat-schedule 129 | 130 | # SageMath parsed files 131 | *.sage.py 132 | 133 | # Environments 134 | .env 135 | .venv 136 | env/ 137 | venv/ 138 | ENV/ 139 | env.bak/ 140 | venv.bak/ 141 | 142 | # Spyder project settings 143 | .spyderproject 144 | .spyproject 145 | 146 | # Rope project settings 147 | .ropeproject 148 | 149 | # mkdocs documentation 150 | /site 151 | 152 | # mypy 153 | .mypy_cache/ 154 | .dmypy.json 155 | dmypy.json 156 | 157 | # Pyre type checker 158 | .pyre/ 159 | 160 | node_modules 161 | /dist 162 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | 2 | # Contributor Covenant Code of Conduct 3 | 4 | ## Our Pledge 5 | 6 | We as members, contributors, and leaders pledge to make participation in our 7 | community a harassment-free experience for everyone, regardless of age, body 8 | size, visible or invisible disability, ethnicity, sex characteristics, gender 9 | identity and expression, level of experience, education, socio-economic status, 10 | nationality, personal appearance, race, religion, or sexual identity 11 | and orientation. 12 | 13 | We pledge to act and interact in ways that contribute to an open, welcoming, 14 | diverse, inclusive, and healthy community. 15 | 16 | ## Our Standards 17 | 18 | Examples of behavior that contributes to a positive environment for our 19 | community include: 20 | 21 | * Demonstrating empathy and kindness toward other people 22 | * Being respectful of differing opinions, viewpoints, and experiences 23 | * Giving and gracefully accepting constructive feedback 24 | * Accepting responsibility and apologizing to those affected by our mistakes, 25 | and learning from the experience 26 | * Focusing on what is best not just for us as individuals, but for the 27 | overall community 28 | 29 | Examples of unacceptable behavior include: 30 | 31 | * The use of sexualized language or imagery, and sexual attention or 32 | advances of any kind 33 | * Trolling, insulting or derogatory comments, and personal or political attacks 34 | * Public or private harassment 35 | * Publishing others' private information, such as a physical or email 36 | address, without their explicit permission 37 | * Other conduct which could reasonably be considered inappropriate in a 38 | professional setting 39 | 40 | ## Enforcement Responsibilities 41 | 42 | Community leaders are responsible for clarifying and enforcing our standards of 43 | acceptable behavior and will take appropriate and fair corrective action in 44 | response to any behavior that they deem inappropriate, threatening, offensive, 45 | or harmful. 46 | 47 | Community leaders have the right and responsibility to remove, edit, or reject 48 | comments, commits, code, wiki edits, issues, and other contributions that are 49 | not aligned to this Code of Conduct, and will communicate reasons for moderation 50 | decisions when appropriate. 51 | 52 | ## Scope 53 | 54 | This Code of Conduct applies within all community spaces, and also applies when 55 | an individual is officially representing the community in public spaces. 56 | Examples of representing our community include using an official e-mail address, 57 | posting via an official social media account, or acting as an appointed 58 | representative at an online or offline event. 59 | 60 | ## Enforcement 61 | 62 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 63 | reported to the community leaders responsible for enforcement at 64 | info@globalprivacycontrol.org. 65 | All complaints will be reviewed and investigated promptly and fairly. 66 | 67 | All community leaders are obligated to respect the privacy and security of the 68 | reporter of any incident. 69 | 70 | ## Enforcement Guidelines 71 | 72 | Community leaders will follow these Community Impact Guidelines in determining 73 | the consequences for any action they deem in violation of this Code of Conduct: 74 | 75 | ### 1. Correction 76 | 77 | **Community Impact**: Use of inappropriate language or other behavior deemed 78 | unprofessional or unwelcome in the community. 79 | 80 | **Consequence**: A private, written warning from community leaders, providing 81 | clarity around the nature of the violation and an explanation of why the 82 | behavior was inappropriate. A public apology may be requested. 83 | 84 | ### 2. Warning 85 | 86 | **Community Impact**: A violation through a single incident or series 87 | of actions. 88 | 89 | **Consequence**: A warning with consequences for continued behavior. No 90 | interaction with the people involved, including unsolicited interaction with 91 | those enforcing the Code of Conduct, for a specified period of time. This 92 | includes avoiding interactions in community spaces as well as external channels 93 | like social media. Violating these terms may lead to a temporary or 94 | permanent ban. 95 | 96 | ### 3. Temporary Ban 97 | 98 | **Community Impact**: A serious violation of community standards, including 99 | sustained inappropriate behavior. 100 | 101 | **Consequence**: A temporary ban from any sort of interaction or public 102 | communication with the community for a specified period of time. No public or 103 | private interaction with the people involved, including unsolicited interaction 104 | with those enforcing the Code of Conduct, is allowed during this period. 105 | Violating these terms may lead to a permanent ban. 106 | 107 | ### 4. Permanent Ban 108 | 109 | **Community Impact**: Demonstrating a pattern of violation of community 110 | standards, including sustained inappropriate behavior, harassment of an 111 | individual, or aggression toward or disparagement of classes of individuals. 112 | 113 | **Consequence**: A permanent ban from any sort of public interaction within 114 | the community. 115 | 116 | ## Attribution 117 | 118 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 119 | version 2.0, available at 120 | https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. 121 | 122 | Community Impact Guidelines were inspired by [Mozilla's code of conduct 123 | enforcement ladder](https://github.com/mozilla/diversity). 124 | 125 | [homepage]: https://www.contributor-covenant.org 126 | 127 | For answers to common questions about this code of conduct, see the FAQ at 128 | https://www.contributor-covenant.org/faq. Translations are available at 129 | https://www.contributor-covenant.org/translations. 130 | 131 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | This license does not apply to any logos or marks that may be contained in this repo. 2 | 3 | Copyright (c) 2020 Global Privacy Control 4 | 5 | Attribution 4.0 International 6 | 7 | ======================================================================= 8 | 9 | Creative Commons Corporation ("Creative Commons") is not a law firm and 10 | does not provide legal services or legal advice. Distribution of 11 | Creative Commons public licenses does not create a lawyer-client or 12 | other relationship. Creative Commons makes its licenses and related 13 | information available on an "as-is" basis. Creative Commons gives no 14 | warranties regarding its licenses, any material licensed under their 15 | terms and conditions, or any related information. Creative Commons 16 | disclaims all liability for damages resulting from their use to the 17 | fullest extent possible. 18 | 19 | Using Creative Commons Public Licenses 20 | 21 | Creative Commons public licenses provide a standard set of terms and 22 | conditions that creators and other rights holders may use to share 23 | original works of authorship and other material subject to copyright 24 | and certain other rights specified in the public license below. The 25 | following considerations are for informational purposes only, are not 26 | exhaustive, and do not form part of our licenses. 27 | 28 | Considerations for licensors: Our public licenses are 29 | intended for use by those authorized to give the public 30 | permission to use material in ways otherwise restricted by 31 | copyright and certain other rights. Our licenses are 32 | irrevocable. Licensors should read and understand the terms 33 | and conditions of the license they choose before applying it. 34 | Licensors should also secure all rights necessary before 35 | applying our licenses so that the public can reuse the 36 | material as expected. Licensors should clearly mark any 37 | material not subject to the license. This includes other CC- 38 | licensed material, or material used under an exception or 39 | limitation to copyright. More considerations for licensors: 40 | wiki.creativecommons.org/Considerations_for_licensors 41 | 42 | Considerations for the public: By using one of our public 43 | licenses, a licensor grants the public permission to use the 44 | licensed material under specified terms and conditions. If 45 | the licensor's permission is not necessary for any reason--for 46 | example, because of any applicable exception or limitation to 47 | copyright--then that use is not regulated by the license. Our 48 | licenses grant only permissions under copyright and certain 49 | other rights that a licensor has authority to grant. Use of 50 | the licensed material may still be restricted for other 51 | reasons, including because others have copyright or other 52 | rights in the material. A licensor may make special requests, 53 | such as asking that all changes be marked or described. 54 | Although not required by our licenses, you are encouraged to 55 | respect those requests where reasonable. More_considerations 56 | for the public: 57 | wiki.creativecommons.org/Considerations_for_licensees 58 | 59 | ======================================================================= 60 | 61 | Creative Commons Attribution 4.0 International Public License 62 | 63 | By exercising the Licensed Rights (defined below), You accept and agree 64 | to be bound by the terms and conditions of this Creative Commons 65 | Attribution 4.0 International Public License ("Public License"). To the 66 | extent this Public License may be interpreted as a contract, You are 67 | granted the Licensed Rights in consideration of Your acceptance of 68 | these terms and conditions, and the Licensor grants You such rights in 69 | consideration of benefits the Licensor receives from making the 70 | Licensed Material available under these terms and conditions. 71 | 72 | 73 | Section 1 -- Definitions. 74 | 75 | a. Adapted Material means material subject to Copyright and Similar 76 | Rights that is derived from or based upon the Licensed Material 77 | and in which the Licensed Material is translated, altered, 78 | arranged, transformed, or otherwise modified in a manner requiring 79 | permission under the Copyright and Similar Rights held by the 80 | Licensor. For purposes of this Public License, where the Licensed 81 | Material is a musical work, performance, or sound recording, 82 | Adapted Material is always produced where the Licensed Material is 83 | synched in timed relation with a moving image. 84 | 85 | b. Adapter's License means the license You apply to Your Copyright 86 | and Similar Rights in Your contributions to Adapted Material in 87 | accordance with the terms and conditions of this Public License. 88 | 89 | c. Copyright and Similar Rights means copyright and/or similar rights 90 | closely related to copyright including, without limitation, 91 | performance, broadcast, sound recording, and Sui Generis Database 92 | Rights, without regard to how the rights are labeled or 93 | categorized. For purposes of this Public License, the rights 94 | specified in Section 2(b)(1)-(2) are not Copyright and Similar 95 | Rights. 96 | 97 | d. Effective Technological Measures means those measures that, in the 98 | absence of proper authority, may not be circumvented under laws 99 | fulfilling obligations under Article 11 of the WIPO Copyright 100 | Treaty adopted on December 20, 1996, and/or similar international 101 | agreements. 102 | 103 | e. Exceptions and Limitations means fair use, fair dealing, and/or 104 | any other exception or limitation to Copyright and Similar Rights 105 | that applies to Your use of the Licensed Material. 106 | 107 | f. Licensed Material means the artistic or literary work, database, 108 | or other material to which the Licensor applied this Public 109 | License. 110 | 111 | g. Licensed Rights means the rights granted to You subject to the 112 | terms and conditions of this Public License, which are limited to 113 | all Copyright and Similar Rights that apply to Your use of the 114 | Licensed Material and that the Licensor has authority to license. 115 | 116 | h. Licensor means the individual(s) or entity(ies) granting rights 117 | under this Public License. 118 | 119 | i. Share means to provide material to the public by any means or 120 | process that requires permission under the Licensed Rights, such 121 | as reproduction, public display, public performance, distribution, 122 | dissemination, communication, or importation, and to make material 123 | available to the public including in ways that members of the 124 | public may access the material from a place and at a time 125 | individually chosen by them. 126 | 127 | j. Sui Generis Database Rights means rights other than copyright 128 | resulting from Directive 96/9/EC of the European Parliament and of 129 | the Council of 11 March 1996 on the legal protection of databases, 130 | as amended and/or succeeded, as well as other essentially 131 | equivalent rights anywhere in the world. 132 | 133 | k. You means the individual or entity exercising the Licensed Rights 134 | under this Public License. Your has a corresponding meaning. 135 | 136 | 137 | Section 2 -- Scope. 138 | 139 | a. License grant. 140 | 141 | 1. Subject to the terms and conditions of this Public License, 142 | the Licensor hereby grants You a worldwide, royalty-free, 143 | non-sublicensable, non-exclusive, irrevocable license to 144 | exercise the Licensed Rights in the Licensed Material to: 145 | 146 | a. reproduce and Share the Licensed Material, in whole or 147 | in part; and 148 | 149 | b. produce, reproduce, and Share Adapted Material. 150 | 151 | 2. Exceptions and Limitations. For the avoidance of doubt, where 152 | Exceptions and Limitations apply to Your use, this Public 153 | License does not apply, and You do not need to comply with 154 | its terms and conditions. 155 | 156 | 3. Term. The term of this Public License is specified in Section 157 | 6(a). 158 | 159 | 4. Media and formats; technical modifications allowed. The 160 | Licensor authorizes You to exercise the Licensed Rights in 161 | all media and formats whether now known or hereafter created, 162 | and to make technical modifications necessary to do so. The 163 | Licensor waives and/or agrees not to assert any right or 164 | authority to forbid You from making technical modifications 165 | necessary to exercise the Licensed Rights, including 166 | technical modifications necessary to circumvent Effective 167 | Technological Measures. For purposes of this Public License, 168 | simply making modifications authorized by this Section 2(a) 169 | (4) never produces Adapted Material. 170 | 171 | 5. Downstream recipients. 172 | 173 | a. Offer from the Licensor -- Licensed Material. Every 174 | recipient of the Licensed Material automatically 175 | receives an offer from the Licensor to exercise the 176 | Licensed Rights under the terms and conditions of this 177 | Public License. 178 | 179 | b. No downstream restrictions. You may not offer or impose 180 | any additional or different terms or conditions on, or 181 | apply any Effective Technological Measures to, the 182 | Licensed Material if doing so restricts exercise of the 183 | Licensed Rights by any recipient of the Licensed 184 | Material. 185 | 186 | 6. No endorsement. Nothing in this Public License constitutes or 187 | may be construed as permission to assert or imply that You 188 | are, or that Your use of the Licensed Material is, connected 189 | with, or sponsored, endorsed, or granted official status by, 190 | the Licensor or others designated to receive attribution as 191 | provided in Section 3(a)(1)(A)(i). 192 | 193 | b. Other rights. 194 | 195 | 1. Moral rights, such as the right of integrity, are not 196 | licensed under this Public License, nor are publicity, 197 | privacy, and/or other similar personality rights; however, to 198 | the extent possible, the Licensor waives and/or agrees not to 199 | assert any such rights held by the Licensor to the limited 200 | extent necessary to allow You to exercise the Licensed 201 | Rights, but not otherwise. 202 | 203 | 2. Patent and trademark rights are not licensed under this 204 | Public License. 205 | 206 | 3. To the extent possible, the Licensor waives any right to 207 | collect royalties from You for the exercise of the Licensed 208 | Rights, whether directly or through a collecting society 209 | under any voluntary or waivable statutory or compulsory 210 | licensing scheme. In all other cases the Licensor expressly 211 | reserves any right to collect such royalties. 212 | 213 | 214 | Section 3 -- License Conditions. 215 | 216 | Your exercise of the Licensed Rights is expressly made subject to the 217 | following conditions. 218 | 219 | a. Attribution. 220 | 221 | 1. If You Share the Licensed Material (including in modified 222 | form), You must: 223 | 224 | a. retain the following if it is supplied by the Licensor 225 | with the Licensed Material: 226 | 227 | i. identification of the creator(s) of the Licensed 228 | Material and any others designated to receive 229 | attribution, in any reasonable manner requested by 230 | the Licensor (including by pseudonym if 231 | designated); 232 | 233 | ii. a copyright notice; 234 | 235 | iii. a notice that refers to this Public License; 236 | 237 | iv. a notice that refers to the disclaimer of 238 | warranties; 239 | 240 | v. a URI or hyperlink to the Licensed Material to the 241 | extent reasonably practicable; 242 | 243 | b. indicate if You modified the Licensed Material and 244 | retain an indication of any previous modifications; and 245 | 246 | c. indicate the Licensed Material is licensed under this 247 | Public License, and include the text of, or the URI or 248 | hyperlink to, this Public License. 249 | 250 | 2. You may satisfy the conditions in Section 3(a)(1) in any 251 | reasonable manner based on the medium, means, and context in 252 | which You Share the Licensed Material. For example, it may be 253 | reasonable to satisfy the conditions by providing a URI or 254 | hyperlink to a resource that includes the required 255 | information. 256 | 257 | 3. If requested by the Licensor, You must remove any of the 258 | information required by Section 3(a)(1)(A) to the extent 259 | reasonably practicable. 260 | 261 | 4. If You Share Adapted Material You produce, the Adapter's 262 | License You apply must not prevent recipients of the Adapted 263 | Material from complying with this Public License. 264 | 265 | 266 | Section 4 -- Sui Generis Database Rights. 267 | 268 | Where the Licensed Rights include Sui Generis Database Rights that 269 | apply to Your use of the Licensed Material: 270 | 271 | a. for the avoidance of doubt, Section 2(a)(1) grants You the right 272 | to extract, reuse, reproduce, and Share all or a substantial 273 | portion of the contents of the database; 274 | 275 | b. if You include all or a substantial portion of the database 276 | contents in a database in which You have Sui Generis Database 277 | Rights, then the database in which You have Sui Generis Database 278 | Rights (but not its individual contents) is Adapted Material; and 279 | 280 | c. You must comply with the conditions in Section 3(a) if You Share 281 | all or a substantial portion of the contents of the database. 282 | 283 | For the avoidance of doubt, this Section 4 supplements and does not 284 | replace Your obligations under this Public License where the Licensed 285 | Rights include other Copyright and Similar Rights. 286 | 287 | 288 | Section 5 -- Disclaimer of Warranties and Limitation of Liability. 289 | 290 | a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE 291 | EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS 292 | AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF 293 | ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, 294 | IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, 295 | WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR 296 | PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, 297 | ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT 298 | KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT 299 | ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. 300 | 301 | b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE 302 | TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, 303 | NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, 304 | INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, 305 | COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR 306 | USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN 307 | ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR 308 | DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR 309 | IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. 310 | 311 | c. The disclaimer of warranties and limitation of liability provided 312 | above shall be interpreted in a manner that, to the extent 313 | possible, most closely approximates an absolute disclaimer and 314 | waiver of all liability. 315 | 316 | 317 | Section 6 -- Term and Termination. 318 | 319 | a. This Public License applies for the term of the Copyright and 320 | Similar Rights licensed here. However, if You fail to comply with 321 | this Public License, then Your rights under this Public License 322 | terminate automatically. 323 | 324 | b. Where Your right to use the Licensed Material has terminated under 325 | Section 6(a), it reinstates: 326 | 327 | 1. automatically as of the date the violation is cured, provided 328 | it is cured within 30 days of Your discovery of the 329 | violation; or 330 | 331 | 2. upon express reinstatement by the Licensor. 332 | 333 | For the avoidance of doubt, this Section 6(b) does not affect any 334 | right the Licensor may have to seek remedies for Your violations 335 | of this Public License. 336 | 337 | c. For the avoidance of doubt, the Licensor may also offer the 338 | Licensed Material under separate terms or conditions or stop 339 | distributing the Licensed Material at any time; however, doing so 340 | will not terminate this Public License. 341 | 342 | d. Sections 1, 5, 6, 7, and 8 survive termination of this Public 343 | License. 344 | 345 | 346 | Section 7 -- Other Terms and Conditions. 347 | 348 | a. The Licensor shall not be bound by any additional or different 349 | terms or conditions communicated by You unless expressly agreed. 350 | 351 | b. Any arrangements, understandings, or agreements regarding the 352 | Licensed Material not stated herein are separate from and 353 | independent of the terms and conditions of this Public License. 354 | 355 | 356 | Section 8 -- Interpretation. 357 | 358 | a. For the avoidance of doubt, this Public License does not, and 359 | shall not be interpreted to, reduce, limit, restrict, or impose 360 | conditions on any use of the Licensed Material that could lawfully 361 | be made without permission under this Public License. 362 | 363 | b. To the extent possible, if any provision of this Public License is 364 | deemed unenforceable, it shall be automatically reformed to the 365 | minimum extent necessary to make it enforceable. If the provision 366 | cannot be reformed, it shall be severed from this Public License 367 | without affecting the enforceability of the remaining terms and 368 | conditions. 369 | 370 | c. No term or condition of this Public License will be waived and no 371 | failure to comply consented to unless expressly agreed to by the 372 | Licensor. 373 | 374 | d. Nothing in this Public License constitutes or may be interpreted 375 | as a limitation upon, or waiver of, any privileges and immunities 376 | that apply to the Licensor or You, including from the legal 377 | processes of any jurisdiction or authority. 378 | 379 | 380 | ======================================================================= 381 | 382 | Creative Commons is not a party to its public 383 | licenses. Notwithstanding, Creative Commons may elect to apply one of 384 | its public licenses to material it publishes and in those instances 385 | will be considered the Licensor. The text of the Creative Commons 386 | public licenses is dedicated to the public domain under the CC0 Public 387 | Domain Dedication. Except for the limited purpose of indicating that 388 | material is shared under a Creative Commons public license or as 389 | otherwise permitted by the Creative Commons policies published at 390 | creativecommons.org/policies, Creative Commons does not authorize the 391 | use of the trademark "Creative Commons" or any other trademark or logo 392 | of Creative Commons without its prior written consent including, 393 | without limitation, in connection with any unauthorized modifications 394 | to any of its public licenses or any other arrangements, 395 | understandings, or agreements concerning use of licensed material. For 396 | the avoidance of doubt, this paragraph does not form part of the 397 | public licenses. 398 | 399 | Creative Commons may be contacted at creativecommons.org. 400 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![][gpc-logo]][gpc-url] 2 | [![License](https://img.shields.io/badge/license-CC%20BY%204.0-0c7453)](https://github.com/globalprivacycontrol/reference-server-express/blob/main/LICENSE) 3 | [![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-v2.0%20adopted-0c7453.svg)](CODE_OF_CONDUCT.md) 4 | [![Twitter](https://img.shields.io/twitter/follow/globalprivctrl.svg?style=social&label=Follow)](https://twitter.com/intent/follow?screen_name=globalprivctrl) 5 | 6 | # Global Privacy Control Server Reference Implementation 7 | 8 | Reference implementation of proposed Global Privacy Control standard written in Node/Express with sample code and instructions. 9 | Visit https://global-privacy-control.glitch.me to see this site live. 10 | 11 | This project adheres to the Contributor Covenant [code of conduct](CODE_OF_CONDUCT.md). 12 | By participating, you are expected to uphold this code. Please report unacceptable behavior to info@globalprivacycontrol.org. 13 | 14 | ## Getting Involved 15 | Please email info@globalprivacycontrol.org if you want more information or are interested in contributing -- particularly if you're interested in developing other reference implementations in languages we don't yet feature including Python, Ruby, etc. 16 | 17 | ## License 18 | Apart from any logos or marks that may be contained in this repo, this work is licensed under a 19 | [Creative Commons Attribution 4.0 International License](https://github.com/globalprivacycontrol/landing-page/blob/master/LICENSE). 20 | 21 | [![CC BY 4.0][cc-by-image]][cc-by] 22 | 23 | ## Resources 24 | - Visit [landing page](https://globalprivacycontrol.org) to learn more about the proposed standard 25 | - Read [proposed specification](https://privacycg.github.io/gpc-spec/) for technical details 26 | 27 | [cc-by]: http://creativecommons.org/licenses/by/4.0/ 28 | [cc-by-image]: https://i.creativecommons.org/l/by/4.0/88x31.png 29 | [gpc-url]: https://globalprivacycontrol.org/ 30 | [gpc-logo]: https://pbs.twimg.com/profile_banners/1311398695162703872/1601662219/1500x500 31 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "reference-server-express", 3 | "version": "1.0.0", 4 | "description": "Reference implementation of the proposed Global Privacy Control standard with sample code and instructions", 5 | "main": "server.js", 6 | "dependencies": { 7 | "express": "^4.17.1", 8 | "ejs": "^3.1.10" 9 | }, 10 | "scripts": { 11 | "start": "node server.js" 12 | }, 13 | "repository": { 14 | "type": "git", 15 | "url": "git+https://github.com/globalprivacycontrol/reference-server-express.git" 16 | }, 17 | "license": "CC BY 4.0", 18 | "bugs": { 19 | "url": "https://github.com/globalprivacycontrol/reference-server-express/issues" 20 | }, 21 | "homepage": "https://github.com/globalprivacycontrol/reference-server-express#readme", 22 | "keywords": [ 23 | "gpc", 24 | "global", 25 | "privacy", 26 | "control" 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /public/.well-known/gpc.json: -------------------------------------------------------------------------------- 1 | { 2 | "gpc": true, 3 | "lastUpdate": "2021-05-13" 4 | } -------------------------------------------------------------------------------- /public/client.js: -------------------------------------------------------------------------------- 1 | document.addEventListener('readystatechange', (event) => { 2 | if (document.readyState === 'interactive') { 3 | const gpcStatus = document.getElementById('dom-signal-status') 4 | gpcStatus.classList.remove('hidden') 5 | } 6 | if (document.readyState === 'interactive' && typeof(navigator.globalPrivacyControl) !== 'undefined') { 7 | const gpcStatus = document.getElementById('dom-signal-status') 8 | const gpcValue = document.getElementById('gpc-dom-value') 9 | const domSvgPath = document.getElementById('dom-thumbs-up') 10 | 11 | if (navigator.globalPrivacyControl) { 12 | domSvgPath.style.fill = "rgb(0, 212, 255)" 13 | } 14 | 15 | gpcValue.innerHTML = navigator.globalPrivacyControl 16 | gpcStatus.classList.remove('dom-signal-missing') 17 | } 18 | }) 19 | 20 | fetch("/.well-known/gpc.json") 21 | .then(response => response.json()) 22 | .then(json => { 23 | const wellKnownWrapper = document.getElementById('well-known-code') 24 | const wellKnownCode = JSON.stringify(json, null, 2) 25 | wellKnownWrapper.innerHTML = wellKnownCode 26 | Prism.highlightElement(wellKnownWrapper) 27 | }) 28 | -------------------------------------------------------------------------------- /public/prism-vsc-dark-plus.css: -------------------------------------------------------------------------------- 1 | pre[class*="language-"], 2 | code[class*="language-"] { 3 | color: #d4d4d4; 4 | font-size: 13px; 5 | text-shadow: none; 6 | font-family: Menlo, Monaco, Consolas, "Andale Mono", "Ubuntu Mono", "Courier New", monospace; 7 | direction: ltr; 8 | text-align: left; 9 | white-space: pre; 10 | word-spacing: normal; 11 | word-break: normal; 12 | line-height: 1.5; 13 | -moz-tab-size: 4; 14 | -o-tab-size: 4; 15 | tab-size: 4; 16 | -webkit-hyphens: none; 17 | -moz-hyphens: none; 18 | -ms-hyphens: none; 19 | hyphens: none; 20 | } 21 | 22 | pre[class*="language-"]::selection, 23 | code[class*="language-"]::selection, 24 | pre[class*="language-"] *::selection, 25 | code[class*="language-"] *::selection { 26 | text-shadow: none; 27 | background: #75a7ca; 28 | } 29 | 30 | @media print { 31 | pre[class*="language-"], 32 | code[class*="language-"] { 33 | text-shadow: none; 34 | } 35 | } 36 | 37 | pre[class*="language-"] { 38 | padding: 1em; 39 | margin: .5em 0; 40 | overflow: auto; 41 | background: #1e1e1e; 42 | } 43 | 44 | :not(pre) > code[class*="language-"] { 45 | padding: .1em .3em; 46 | border-radius: .3em; 47 | color: #db4c69; 48 | background: #f9f2f4; 49 | } 50 | /********************************************************* 51 | * Tokens 52 | */ 53 | .namespace { 54 | opacity: .7; 55 | } 56 | 57 | .token.doctype .token.doctype-tag { 58 | color: #569CD6; 59 | } 60 | 61 | .token.doctype .token.name { 62 | color: #9cdcfe; 63 | } 64 | 65 | .token.comment, 66 | .token.prolog { 67 | color: #6a9955; 68 | } 69 | 70 | .token.punctuation, 71 | .language-html .language-css .token.punctuation, 72 | .language-html .language-javascript .token.punctuation { 73 | color: #d4d4d4; 74 | } 75 | 76 | .token.property, 77 | .token.tag, 78 | .token.boolean, 79 | .token.number, 80 | .token.constant, 81 | .token.symbol, 82 | .token.deleted, 83 | .token.unit { 84 | color: #b5cea8; 85 | } 86 | 87 | .token.selector, 88 | .token.attr-name, 89 | .token.string, 90 | .token.char, 91 | .token.builtin, 92 | .token.inserted { 93 | color: #ce9178; 94 | } 95 | 96 | .language-css .token.string.url { 97 | text-decoration: underline; 98 | } 99 | 100 | .token.operator, 101 | .token.entity { 102 | color: #d4d4d4; 103 | } 104 | 105 | .token.operator.arrow { 106 | color: #569CD6; 107 | } 108 | 109 | .token.atrule { 110 | color: #ce9178; 111 | } 112 | 113 | .token.atrule .token.rule { 114 | color: #c586c0; 115 | } 116 | 117 | .token.atrule .token.url { 118 | color: #9cdcfe; 119 | } 120 | 121 | .token.atrule .token.url .token.function { 122 | color: #dcdcaa; 123 | } 124 | 125 | .token.atrule .token.url .token.punctuation { 126 | color: #d4d4d4; 127 | } 128 | 129 | .token.keyword { 130 | color: #569CD6; 131 | } 132 | 133 | .token.keyword.module, 134 | .token.keyword.control-flow { 135 | color: #c586c0; 136 | } 137 | 138 | .token.function, 139 | .token.function .token.maybe-class-name { 140 | color: #dcdcaa; 141 | } 142 | 143 | .token.regex { 144 | color: #d16969; 145 | } 146 | 147 | .token.important { 148 | color: #569cd6; 149 | } 150 | 151 | .token.italic { 152 | font-style: italic; 153 | } 154 | 155 | .token.constant { 156 | color: #9cdcfe; 157 | } 158 | 159 | .token.class-name, 160 | .token.maybe-class-name { 161 | color: #4ec9b0; 162 | } 163 | 164 | .token.console { 165 | color: #9cdcfe; 166 | } 167 | 168 | .token.parameter { 169 | color: #9cdcfe; 170 | } 171 | 172 | .token.interpolation { 173 | color: #9cdcfe; 174 | } 175 | 176 | .token.punctuation.interpolation-punctuation { 177 | color: #569cd6; 178 | } 179 | 180 | .token.boolean { 181 | color: #569cd6; 182 | } 183 | 184 | .token.property, 185 | .token.variable, 186 | .token.imports .token.maybe-class-name, 187 | .token.exports .token.maybe-class-name { 188 | color: #9cdcfe; 189 | } 190 | 191 | .token.selector { 192 | color: #d7ba7d; 193 | } 194 | 195 | .token.escape { 196 | color: #d7ba7d; 197 | } 198 | 199 | .token.tag { 200 | color: #569cd6; 201 | } 202 | 203 | .token.tag .token.punctuation { 204 | color: #808080; 205 | } 206 | 207 | .token.cdata { 208 | color: #808080; 209 | } 210 | 211 | .token.attr-name { 212 | color: #9cdcfe; 213 | } 214 | 215 | .token.attr-value, 216 | .token.attr-value .token.punctuation { 217 | color: #ce9178; 218 | } 219 | 220 | .token.attr-value .token.punctuation.attr-equals { 221 | color: #d4d4d4; 222 | } 223 | 224 | .token.entity { 225 | color: #569cd6; 226 | } 227 | 228 | .token.namespace { 229 | color: #4ec9b0; 230 | } 231 | /********************************************************* 232 | * Language Specific 233 | */ 234 | 235 | pre[class*="language-javascript"], 236 | code[class*="language-javascript"], 237 | pre[class*="language-jsx"], 238 | code[class*="language-jsx"], 239 | pre[class*="language-typescript"], 240 | code[class*="language-typescript"], 241 | pre[class*="language-tsx"], 242 | code[class*="language-tsx"] { 243 | color: #9cdcfe; 244 | } 245 | 246 | pre[class*="language-css"], 247 | code[class*="language-css"] { 248 | color: #ce9178; 249 | } 250 | 251 | pre[class*="language-html"], 252 | code[class*="language-html"] { 253 | color: #d4d4d4; 254 | } 255 | 256 | .language-regex .token.anchor { 257 | color: #dcdcaa; 258 | } 259 | 260 | .language-html .token.punctuation { 261 | color: #808080; 262 | } 263 | /********************************************************* 264 | * Line highlighting 265 | */ 266 | pre[data-line] { 267 | position: relative; 268 | } 269 | 270 | pre[class*="language-"] > code[class*="language-"] { 271 | position: relative; 272 | z-index: 1; 273 | } 274 | 275 | .line-highlight { 276 | position: absolute; 277 | left: 0; 278 | right: 0; 279 | padding: inherit 0; 280 | margin-top: 1em; 281 | background: #f7ebc6; 282 | box-shadow: inset 5px 0 0 #f7d87c; 283 | z-index: 0; 284 | pointer-events: none; 285 | line-height: inherit; 286 | white-space: pre; 287 | } 288 | 289 | 290 | pre[class*="language-"].line-numbers { 291 | position: relative; 292 | padding-left: 3.8em; 293 | counter-reset: linenumber; 294 | } 295 | 296 | pre[class*="language-"].line-numbers > code { 297 | position: relative; 298 | white-space: inherit; 299 | } 300 | 301 | .line-numbers .line-numbers-rows { 302 | position: absolute; 303 | pointer-events: none; 304 | top: 0; 305 | font-size: 100%; 306 | left: -3.8em; 307 | width: 3em; /* works for line-numbers below 1000 lines */ 308 | letter-spacing: -1px; 309 | border-right: 1px solid #999; 310 | 311 | -webkit-user-select: none; 312 | -moz-user-select: none; 313 | -ms-user-select: none; 314 | user-select: none; 315 | 316 | } 317 | 318 | .line-numbers-rows > span { 319 | display: block; 320 | counter-increment: linenumber; 321 | } 322 | 323 | .line-numbers-rows > span:before { 324 | content: counter(linenumber); 325 | color: #999; 326 | display: block; 327 | padding-right: 0.8em; 328 | text-align: right; 329 | } 330 | 331 | div.code-toolbar { 332 | position: relative; 333 | } 334 | 335 | div.code-toolbar > .toolbar { 336 | position: absolute; 337 | top: .3em; 338 | right: .2em; 339 | transition: opacity 0.3s ease-in-out; 340 | opacity: 0; 341 | } 342 | 343 | div.code-toolbar:hover > .toolbar { 344 | opacity: 1; 345 | } 346 | 347 | /* Separate line b/c rules are thrown out if selector is invalid. 348 | IE11 and old Edge versions don't support :focus-within. */ 349 | div.code-toolbar:focus-within > .toolbar { 350 | opacity: 1; 351 | } 352 | 353 | div.code-toolbar > .toolbar .toolbar-item { 354 | display: inline-block; 355 | } 356 | 357 | div.code-toolbar > .toolbar a { 358 | cursor: pointer; 359 | } 360 | 361 | div.code-toolbar > .toolbar button { 362 | background: none; 363 | border: 0; 364 | color: inherit; 365 | font: inherit; 366 | line-height: normal; 367 | overflow: visible; 368 | padding: 0; 369 | -webkit-user-select: none; /* for button */ 370 | -moz-user-select: none; 371 | -ms-user-select: none; 372 | } 373 | 374 | div.code-toolbar > .toolbar a, 375 | div.code-toolbar > .toolbar button, 376 | div.code-toolbar > .toolbar span { 377 | color: #bbb; 378 | font-size: .8em; 379 | padding: 0 .5em; 380 | background: #f5f2f0; 381 | background: rgba(224, 224, 224, 0.2); 382 | box-shadow: 0 2px 0 0 rgba(0,0,0,0.2); 383 | border-radius: .5em; 384 | } 385 | 386 | div.code-toolbar > .toolbar a:hover, 387 | div.code-toolbar > .toolbar a:focus, 388 | div.code-toolbar > .toolbar button:hover, 389 | div.code-toolbar > .toolbar button:focus, 390 | div.code-toolbar > .toolbar span:hover, 391 | div.code-toolbar > .toolbar span:focus { 392 | color: inherit; 393 | text-decoration: none; 394 | } -------------------------------------------------------------------------------- /public/prism.js: -------------------------------------------------------------------------------- 1 | /* PrismJS 1.21.0 2 | https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript+json&plugins=line-numbers+show-language+toolbar */ 3 | var _self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{},Prism=function(u){var c=/\blang(?:uage)?-([\w-]+)\b/i,n=0,M={manual:u.Prism&&u.Prism.manual,disableWorkerMessageHandler:u.Prism&&u.Prism.disableWorkerMessageHandler,util:{encode:function e(n){return n instanceof W?new W(n.type,e(n.content),n.alias):Array.isArray(n)?n.map(e):n.replace(/&/g,"&").replace(/=l.reach);k+=y.value.length,y=y.next){var b=y.value;if(t.length>n.length)return;if(!(b instanceof W)){var x=1;if(h&&y!=t.tail.prev){m.lastIndex=k;var w=m.exec(n);if(!w)break;var A=w.index+(f&&w[1]?w[1].length:0),P=w.index+w[0].length,S=k;for(S+=y.value.length;S<=A;)y=y.next,S+=y.value.length;if(S-=y.value.length,k=S,y.value instanceof W)continue;for(var E=y;E!==t.tail&&(Sl.reach&&(l.reach=j);var C=y.prev;L&&(C=I(t,C,L),k+=L.length),z(t,C,x);var _=new W(o,g?M.tokenize(O,g):O,v,O);y=I(t,C,_),N&&I(t,y,N),1"+a.content+""},!u.document)return u.addEventListener&&(M.disableWorkerMessageHandler||u.addEventListener("message",function(e){var n=JSON.parse(e.data),t=n.language,r=n.code,a=n.immediateClose;u.postMessage(M.highlight(r,M.languages[t],t)),a&&u.close()},!1)),M;var e=M.util.currentScript();function t(){M.manual||M.highlightAll()}if(e&&(M.filename=e.src,e.hasAttribute("data-manual")&&(M.manual=!0)),!M.manual){var r=document.readyState;"loading"===r||"interactive"===r&&e&&e.defer?document.addEventListener("DOMContentLoaded",t):window.requestAnimationFrame?window.requestAnimationFrame(t):window.setTimeout(t,16)}return M}(_self);"undefined"!=typeof module&&module.exports&&(module.exports=Prism),"undefined"!=typeof global&&(global.Prism=Prism); 4 | Prism.languages.markup={comment://,prolog:/<\?[\s\S]+?\?>/,doctype:{pattern:/"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^$|[[\]]/,"doctype-tag":/^DOCTYPE/,name:/[^\s<>'"]+/}},cdata://i,tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},Prism.languages.markup.tag.inside["attr-value"].inside.entity=Prism.languages.markup.entity,Prism.languages.markup.doctype.inside["internal-subset"].inside=Prism.languages.markup,Prism.hooks.add("wrap",function(a){"entity"===a.type&&(a.attributes.title=a.content.replace(/&/,"&"))}),Object.defineProperty(Prism.languages.markup.tag,"addInlined",{value:function(a,e){var s={};s["language-"+e]={pattern:/(^$)/i,lookbehind:!0,inside:Prism.languages[e]},s.cdata=/^$/i;var n={"included-cdata":{pattern://i,inside:s}};n["language-"+e]={pattern:/[\s\S]+/,inside:Prism.languages[e]};var t={};t[a]={pattern:RegExp("(<__[^]*?>)(?:))*\\]\\]>|(?!)".replace(/__/g,function(){return a}),"i"),lookbehind:!0,greedy:!0,inside:n},Prism.languages.insertBefore("markup","cdata",t)}}),Prism.languages.html=Prism.languages.markup,Prism.languages.mathml=Prism.languages.markup,Prism.languages.svg=Prism.languages.markup,Prism.languages.xml=Prism.languages.extend("markup",{}),Prism.languages.ssml=Prism.languages.xml,Prism.languages.atom=Prism.languages.xml,Prism.languages.rss=Prism.languages.xml; 5 | !function(e){var s=/("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/;e.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:/@[\w-]+[\s\S]*?(?:;|(?=\s*\{))/,inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\((?!\s*\))\s*)(?:[^()]|\((?:[^()]|\([^()]*\))*\))+?(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+s.source+"|(?:[^\\\\\r\n()\"']|\\\\[^])*)\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+s.source+"$"),alias:"url"}}},selector:RegExp("[^{}\\s](?:[^{};\"']|"+s.source+")*?(?=\\s*\\{)"),string:{pattern:s,greedy:!0},property:/[-_a-z\xA0-\uFFFF][-\w\xA0-\uFFFF]*(?=\s*:)/i,important:/!important\b/i,function:/[-a-z0-9]+(?=\()/i,punctuation:/[(){};:,]/},e.languages.css.atrule.inside.rest=e.languages.css;var t=e.languages.markup;t&&(t.tag.addInlined("style","css"),e.languages.insertBefore("inside","attr-value",{"style-attr":{pattern:/\s*style=("|')(?:\\[\s\S]|(?!\1)[^\\])*\1/i,inside:{"attr-name":{pattern:/^\s*style/i,inside:t.tag.inside},punctuation:/^\s*=\s*['"]|['"]\s*$/,"attr-value":{pattern:/.+/i,inside:e.languages.css}},alias:"language-css"}},t.tag))}(Prism); 6 | Prism.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/(\b(?:class|interface|extends|implements|trait|instanceof|new)\s+|\bcatch\s+\()[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/,boolean:/\b(?:true|false)\b/,function:/\w+(?=\()/,number:/\b0x[\da-f]+\b|(?:\b\d+\.?\d*|\B\.\d+)(?:e[+-]?\d+)?/i,operator:/[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/}; 7 | Prism.languages.javascript=Prism.languages.extend("clike",{"class-name":[Prism.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])[_$A-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\.(?:prototype|constructor))/,lookbehind:!0}],keyword:[{pattern:/((?:^|})\s*)(?:catch|finally)\b/,lookbehind:!0},{pattern:/(^|[^.]|\.\.\.\s*)\b(?:as|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|for|from|function|(?:get|set)(?=\s*[\[$\w\xA0-\uFFFF])|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],number:/\b(?:(?:0[xX](?:[\dA-Fa-f](?:_[\dA-Fa-f])?)+|0[bB](?:[01](?:_[01])?)+|0[oO](?:[0-7](?:_[0-7])?)+)n?|(?:\d(?:_\d)?)+n|NaN|Infinity)\b|(?:\b(?:\d(?:_\d)?)+\.?(?:\d(?:_\d)?)*|\B\.(?:\d(?:_\d)?)+)(?:[Ee][+-]?(?:\d(?:_\d)?)+)?/,function:/#?[_$a-zA-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,operator:/--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/}),Prism.languages.javascript["class-name"][0].pattern=/(\b(?:class|interface|extends|implements|instanceof|new)\s+)[\w.\\]+/,Prism.languages.insertBefore("javascript","keyword",{regex:{pattern:/((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)\/(?:\[(?:[^\]\\\r\n]|\\.)*]|\\.|[^/\\\[\r\n])+\/[gimyus]{0,6}(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/,lookbehind:!0,greedy:!0,inside:{"regex-source":{pattern:/^(\/)[\s\S]+(?=\/[a-z]*$)/,lookbehind:!0,alias:"language-regex",inside:Prism.languages.regex},"regex-flags":/[a-z]+$/,"regex-delimiter":/^\/|\/$/}},"function-variable":{pattern:/#?[_$a-zA-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|[_$a-zA-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*)\s*=>))/,alias:"function"},parameter:[{pattern:/(function(?:\s+[_$A-Za-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*)?\s*\(\s*)(?!\s)(?:[^()]|\([^()]*\))+?(?=\s*\))/,lookbehind:!0,inside:Prism.languages.javascript},{pattern:/[_$a-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*=>)/i,inside:Prism.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()]|\([^()]*\))+?(?=\s*\)\s*=>)/,lookbehind:!0,inside:Prism.languages.javascript},{pattern:/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:[_$A-Za-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()]|\([^()]*\))+?(?=\s*\)\s*\{)/,lookbehind:!0,inside:Prism.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),Prism.languages.insertBefore("javascript","string",{"template-string":{pattern:/`(?:\\[\s\S]|\${(?:[^{}]|{(?:[^{}]|{[^}]*})*})+}|(?!\${)[^\\`])*`/,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\${(?:[^{}]|{(?:[^{}]|{[^}]*})*})+}/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\${|}$/,alias:"punctuation"},rest:Prism.languages.javascript}},string:/[\s\S]+/}}}),Prism.languages.markup&&Prism.languages.markup.tag.addInlined("script","javascript"),Prism.languages.js=Prism.languages.javascript; 8 | Prism.languages.json={property:{pattern:/"(?:\\.|[^\\"\r\n])*"(?=\s*:)/,greedy:!0},string:{pattern:/"(?:\\.|[^\\"\r\n])*"(?!\s*:)/,greedy:!0},comment:{pattern:/\/\/.*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},number:/-?\b\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,punctuation:/[{}[\],]/,operator:/:/,boolean:/\b(?:true|false)\b/,null:{pattern:/\bnull\b/,alias:"keyword"}},Prism.languages.webmanifest=Prism.languages.json; 9 | !function(){if("undefined"!=typeof self&&self.Prism&&self.document){var o="line-numbers",a=/\n(?!$)/g,e=Prism.plugins.lineNumbers={getLine:function(e,n){if("PRE"===e.tagName&&e.classList.contains(o)){var t=e.querySelector(".line-numbers-rows"),i=parseInt(e.getAttribute("data-start"),10)||1,r=i+(t.children.length-1);n");(i=document.createElement("span")).setAttribute("aria-hidden","true"),i.className="line-numbers-rows",i.innerHTML=l,t.hasAttribute("data-start")&&(t.style.counterReset="linenumber "+(parseInt(t.getAttribute("data-start"),10)-1)),e.element.appendChild(i),u([t]),Prism.hooks.run("line-numbers",e)}}}),Prism.hooks.add("line-numbers",function(e){e.plugins=e.plugins||{},e.plugins.lineNumbers=!0})}function u(e){if(0!=(e=e.filter(function(e){var n=t(e)["white-space"];return"pre-wrap"===n||"pre-line"===n})).length){var n=e.map(function(e){var n=e.querySelector("code"),t=e.querySelector(".line-numbers-rows");if(n&&t){var i=e.querySelector(".line-numbers-sizer"),r=n.textContent.split(a);i||((i=document.createElement("span")).className="line-numbers-sizer",n.appendChild(i)),i.innerHTML="0",i.style.display="block";var s=i.getBoundingClientRect().height;return i.innerHTML="",{element:e,lines:r,lineHeights:[],oneLinerHeight:s,sizer:i}}}).filter(Boolean);n.forEach(function(e){var i=e.sizer,n=e.lines,r=e.lineHeights,s=e.oneLinerHeight;r[n.length-1]=void 0,n.forEach(function(e,n){if(e&&1= 0.6' 12 | resolution: 13 | integrity: sha1-63d99gEXI6OxTopywIBcjoZ0a9I= 14 | /array-flatten/1.1.1: 15 | dev: false 16 | resolution: 17 | integrity: sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= 18 | /body-parser/1.18.3: 19 | dependencies: 20 | bytes: 3.0.0 21 | content-type: 1.0.4 22 | debug: 2.6.9 23 | depd: 1.1.2 24 | http-errors: 1.6.3 25 | iconv-lite: 0.4.23 26 | on-finished: 2.3.0 27 | qs: 6.5.2 28 | raw-body: 2.3.3 29 | type-is: 1.6.16 30 | dev: false 31 | engines: 32 | node: '>= 0.8' 33 | resolution: 34 | integrity: sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ= 35 | /bytes/3.0.0: 36 | dev: false 37 | engines: 38 | node: '>= 0.8' 39 | resolution: 40 | integrity: sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg= 41 | /content-disposition/0.5.2: 42 | dev: false 43 | engines: 44 | node: '>= 0.6' 45 | resolution: 46 | integrity: sha1-DPaLud318r55YcOoUXjLhdunjLQ= 47 | /content-type/1.0.4: 48 | dev: false 49 | engines: 50 | node: '>= 0.6' 51 | resolution: 52 | integrity: sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== 53 | /cookie-signature/1.0.6: 54 | dev: false 55 | resolution: 56 | integrity: sha1-4wOogrNCzD7oylE6eZmXNNqzriw= 57 | /cookie/0.3.1: 58 | dev: false 59 | engines: 60 | node: '>= 0.6' 61 | resolution: 62 | integrity: sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s= 63 | /debug/2.6.9: 64 | dependencies: 65 | ms: 2.0.0 66 | dev: false 67 | resolution: 68 | integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== 69 | /depd/1.1.2: 70 | dev: false 71 | engines: 72 | node: '>= 0.6' 73 | resolution: 74 | integrity: sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= 75 | /destroy/1.0.4: 76 | dev: false 77 | resolution: 78 | integrity: sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= 79 | /ee-first/1.1.1: 80 | dev: false 81 | resolution: 82 | integrity: sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= 83 | /ejs/2.6.1: 84 | dev: false 85 | engines: 86 | node: '>=0.10.0' 87 | resolution: 88 | integrity: sha512-0xy4A/twfrRCnkhfk8ErDi5DqdAsAqeGxht4xkCUrsvhhbQNs7E+4jV0CN7+NKIY0aHE72+XvqtBIXzD31ZbXQ== 89 | /encodeurl/1.0.2: 90 | dev: false 91 | engines: 92 | node: '>= 0.8' 93 | resolution: 94 | integrity: sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= 95 | /escape-html/1.0.3: 96 | dev: false 97 | resolution: 98 | integrity: sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= 99 | /etag/1.8.1: 100 | dev: false 101 | engines: 102 | node: '>= 0.6' 103 | resolution: 104 | integrity: sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= 105 | /express/4.16.4: 106 | dependencies: 107 | accepts: 1.3.5 108 | array-flatten: 1.1.1 109 | body-parser: 1.18.3 110 | content-disposition: 0.5.2 111 | content-type: 1.0.4 112 | cookie: 0.3.1 113 | cookie-signature: 1.0.6 114 | debug: 2.6.9 115 | depd: 1.1.2 116 | encodeurl: 1.0.2 117 | escape-html: 1.0.3 118 | etag: 1.8.1 119 | finalhandler: 1.1.1 120 | fresh: 0.5.2 121 | merge-descriptors: 1.0.1 122 | methods: 1.1.2 123 | on-finished: 2.3.0 124 | parseurl: 1.3.2 125 | path-to-regexp: 0.1.7 126 | proxy-addr: 2.0.4 127 | qs: 6.5.2 128 | range-parser: 1.2.0 129 | safe-buffer: 5.1.2 130 | send: 0.16.2 131 | serve-static: 1.13.2 132 | setprototypeof: 1.1.0 133 | statuses: 1.4.0 134 | type-is: 1.6.16 135 | utils-merge: 1.0.1 136 | vary: 1.1.2 137 | dev: false 138 | engines: 139 | node: '>= 0.10.0' 140 | resolution: 141 | integrity: sha512-j12Uuyb4FMrd/qQAm6uCHAkPtO8FDTRJZBDd5D2KOL2eLaz1yUNdUB/NOIyq0iU4q4cFarsUCrnFDPBcnksuOg== 142 | /finalhandler/1.1.1: 143 | dependencies: 144 | debug: 2.6.9 145 | encodeurl: 1.0.2 146 | escape-html: 1.0.3 147 | on-finished: 2.3.0 148 | parseurl: 1.3.2 149 | statuses: 1.4.0 150 | unpipe: 1.0.0 151 | dev: false 152 | engines: 153 | node: '>= 0.8' 154 | resolution: 155 | integrity: sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg== 156 | /forwarded/0.1.2: 157 | dev: false 158 | engines: 159 | node: '>= 0.6' 160 | resolution: 161 | integrity: sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ= 162 | /fresh/0.5.2: 163 | dev: false 164 | engines: 165 | node: '>= 0.6' 166 | resolution: 167 | integrity: sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= 168 | /http-errors/1.6.3: 169 | dependencies: 170 | depd: 1.1.2 171 | inherits: 2.0.3 172 | setprototypeof: 1.1.0 173 | statuses: 1.5.0 174 | dev: false 175 | engines: 176 | node: '>= 0.6' 177 | resolution: 178 | integrity: sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0= 179 | /iconv-lite/0.4.23: 180 | dependencies: 181 | safer-buffer: 2.1.2 182 | dev: false 183 | engines: 184 | node: '>=0.10.0' 185 | resolution: 186 | integrity: sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA== 187 | /inherits/2.0.3: 188 | dev: false 189 | resolution: 190 | integrity: sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= 191 | /ipaddr.js/1.8.0: 192 | dev: false 193 | engines: 194 | node: '>= 0.10' 195 | resolution: 196 | integrity: sha1-6qM9bd16zo9/b+DJygRA5wZzix4= 197 | /media-typer/0.3.0: 198 | dev: false 199 | engines: 200 | node: '>= 0.6' 201 | resolution: 202 | integrity: sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= 203 | /merge-descriptors/1.0.1: 204 | dev: false 205 | resolution: 206 | integrity: sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= 207 | /methods/1.1.2: 208 | dev: false 209 | engines: 210 | node: '>= 0.6' 211 | resolution: 212 | integrity: sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= 213 | /mime-db/1.37.0: 214 | dev: false 215 | engines: 216 | node: '>= 0.6' 217 | resolution: 218 | integrity: sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg== 219 | /mime-types/2.1.21: 220 | dependencies: 221 | mime-db: 1.37.0 222 | dev: false 223 | engines: 224 | node: '>= 0.6' 225 | resolution: 226 | integrity: sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg== 227 | /mime/1.4.1: 228 | dev: false 229 | hasBin: true 230 | resolution: 231 | integrity: sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ== 232 | /ms/2.0.0: 233 | dev: false 234 | resolution: 235 | integrity: sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= 236 | /negotiator/0.6.1: 237 | dev: false 238 | engines: 239 | node: '>= 0.6' 240 | resolution: 241 | integrity: sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk= 242 | /on-finished/2.3.0: 243 | dependencies: 244 | ee-first: 1.1.1 245 | dev: false 246 | engines: 247 | node: '>= 0.8' 248 | resolution: 249 | integrity: sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= 250 | /parseurl/1.3.2: 251 | dev: false 252 | engines: 253 | node: '>= 0.8' 254 | resolution: 255 | integrity: sha1-/CidTtiZMRlGDBViUyYs3I3mW/M= 256 | /path-to-regexp/0.1.7: 257 | dev: false 258 | resolution: 259 | integrity: sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= 260 | /proxy-addr/2.0.4: 261 | dependencies: 262 | forwarded: 0.1.2 263 | ipaddr.js: 1.8.0 264 | dev: false 265 | engines: 266 | node: '>= 0.10' 267 | resolution: 268 | integrity: sha512-5erio2h9jp5CHGwcybmxmVqHmnCBZeewlfJ0pex+UW7Qny7OOZXTtH56TGNyBizkgiOwhJtMKrVzDTeKcySZwA== 269 | /qs/6.5.2: 270 | dev: false 271 | engines: 272 | node: '>=0.6' 273 | resolution: 274 | integrity: sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== 275 | /range-parser/1.2.0: 276 | dev: false 277 | engines: 278 | node: '>= 0.6' 279 | resolution: 280 | integrity: sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4= 281 | /raw-body/2.3.3: 282 | dependencies: 283 | bytes: 3.0.0 284 | http-errors: 1.6.3 285 | iconv-lite: 0.4.23 286 | unpipe: 1.0.0 287 | dev: false 288 | engines: 289 | node: '>= 0.8' 290 | resolution: 291 | integrity: sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw== 292 | /safe-buffer/5.1.2: 293 | dev: false 294 | resolution: 295 | integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== 296 | /safer-buffer/2.1.2: 297 | dev: false 298 | resolution: 299 | integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== 300 | /send/0.16.2: 301 | dependencies: 302 | debug: 2.6.9 303 | depd: 1.1.2 304 | destroy: 1.0.4 305 | encodeurl: 1.0.2 306 | escape-html: 1.0.3 307 | etag: 1.8.1 308 | fresh: 0.5.2 309 | http-errors: 1.6.3 310 | mime: 1.4.1 311 | ms: 2.0.0 312 | on-finished: 2.3.0 313 | range-parser: 1.2.0 314 | statuses: 1.4.0 315 | dev: false 316 | engines: 317 | node: '>= 0.8.0' 318 | resolution: 319 | integrity: sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw== 320 | /serve-static/1.13.2: 321 | dependencies: 322 | encodeurl: 1.0.2 323 | escape-html: 1.0.3 324 | parseurl: 1.3.2 325 | send: 0.16.2 326 | dev: false 327 | engines: 328 | node: '>= 0.8.0' 329 | resolution: 330 | integrity: sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw== 331 | /setprototypeof/1.1.0: 332 | dev: false 333 | resolution: 334 | integrity: sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== 335 | /statuses/1.4.0: 336 | dev: false 337 | engines: 338 | node: '>= 0.6' 339 | resolution: 340 | integrity: sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew== 341 | /statuses/1.5.0: 342 | dev: false 343 | engines: 344 | node: '>= 0.6' 345 | resolution: 346 | integrity: sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= 347 | /type-is/1.6.16: 348 | dependencies: 349 | media-typer: 0.3.0 350 | mime-types: 2.1.21 351 | dev: false 352 | engines: 353 | node: '>= 0.6' 354 | resolution: 355 | integrity: sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q== 356 | /unpipe/1.0.0: 357 | dev: false 358 | engines: 359 | node: '>= 0.8' 360 | resolution: 361 | integrity: sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= 362 | /utils-merge/1.0.1: 363 | dev: false 364 | engines: 365 | node: '>= 0.4.0' 366 | resolution: 367 | integrity: sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= 368 | /vary/1.1.2: 369 | dev: false 370 | engines: 371 | node: '>= 0.8' 372 | resolution: 373 | integrity: sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= 374 | registry: 'https://registry.npmjs.org/' 375 | shrinkwrapMinorVersion: 9 376 | shrinkwrapVersion: 3 377 | specifiers: 378 | ejs: ^2.6.1 379 | express: ^4.16.4 380 | -------------------------------------------------------------------------------- /views/index.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Interacting with Global Privacy Control 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 17 | 22 | 28 | 34 | 35 | 36 | Global Privacy Control — Interacting With The GPC Signal 37 | 41 | 45 | 46 | 47 | 48 | 49 | 50 | 54 | 58 | 59 | 60 | 61 | 62 | 63 | 67 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 |
82 |
83 |

84 | Interacting with Global Privacy Control 85 |

86 |
87 |
88 |
89 |
90 |
91 |
92 |

93 | Server-side detection 94 |

95 |

96 | A user agent's Global Privacy Control setting is attached to HTTP requests as the 97 | Sec-GPC request header. This header's value will be "1" 98 | if enabled, and not present otherwise. Interacting with this will vary depending 99 | on the application back-end. Example code is Node.js/Express. 100 | 101 |

102 | <%- include('partials/header-signal-status') %> 103 |
104 |
105 |
106 |
107 |             
108 | app.get("/", function(req, res) {
109 |   const gpcValue = req.header('Sec-GPC')
110 |   if (gpcValue === "1") {
111 |     // signal detected, do something
112 |   }
113 | })
114 |             
115 |           
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |

124 | Client-side detection 125 |

126 |

127 | The navigator.globalPrivacyControl property enables client-side script to determine 128 | a user agent's Global Privacy Control setting. This value mirrors the value sent in the 129 | Sec-GPC header: it will equal true if the Sec-GPC header sent 130 | is equal to "1", and false otherwise. 131 |

132 | <%- include('partials/dom-signal-status') %> 133 |
134 |
135 |
136 |
137 |             
138 | const gpcValue = navigator.globalPrivacyControl
139 | if (gpcValue) {
140 |   // signal detected, do something
141 | }
142 |             
143 |           
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |

152 | .well-known 153 |

154 |

155 | Businesses may host a .well-known/gpc.json resource that indicates to clients how 156 | they respond to a Global Privacy Control signal. This is a JSON file hosted at the 157 | .well-known/gpc.json endpoint. 158 |

159 | <%- include('partials/well-known-status') %> 160 |
161 |
162 |
163 |
164 |             
165 |           
166 |
167 |
168 |
169 | 174 | 175 | 176 | -------------------------------------------------------------------------------- /views/partials/dom-signal-status.ejs: -------------------------------------------------------------------------------- 1 | 14 | 21 | -------------------------------------------------------------------------------- /views/partials/footer.ejs: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | W3C 7 | 8 | 9 | 10 | 11 | 12 | Proposed specification 13 | 14 | 15 | 16 | View page source 17 | 18 | -------------------------------------------------------------------------------- /views/partials/header-signal-status.ejs: -------------------------------------------------------------------------------- 1 |

2 | <% if (globalPrivacyControlValue) { %> 3 | Header present 4 | 5 |
6 | Sec-GPC: "<%= globalPrivacyControlValue %>" 7 |
8 | <% } else { %> 9 | Header not present 10 | 11 | <% } %> 12 |

-------------------------------------------------------------------------------- /views/partials/well-known-status.ejs: -------------------------------------------------------------------------------- 1 |

2 | 3 | .well-known/gpc.json present 4 | 5 | 6 | 7 | .well-known/gpc.json not present 8 | 9 | 10 |

11 | --------------------------------------------------------------------------------