diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 55583d0..9e8de8c 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -7,25 +7,25 @@ assignees: '' --- -**Describe the bug** +**Describe the bug**: A clear and concise description of what the bug is. -**To Reproduce** +**To Reproduce**: Steps to reproduce the behavior: 1. Import '...' 2. Call '....' 3. See error -**Expected behavior** +**Expected behavior**: A clear and concise description of what you expected to happen. -**Screenshots** +**Screenshots**: If applicable, add screenshots to help explain your problem. **Desktop (please complete the following information):** - - OS: [e.g. linux] - - Python version [e.g. 3.12] - - Dependencies versions [e.g. pydantic 2.6.4] + - OS: `[e.g. linux]` + - Python version(s): `[e.g. 3.12]` + - Dependencies versions: `[e.g. pydantic 2.6.4]` -**Additional context** +**Additional context**: Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index e648b58..a52670b 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -7,14 +7,14 @@ assignees: '' --- -**Is your feature request related to a problem? Please describe** +**Is your feature request related to a problem? Please describe**: A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] -**Describe the solution you'd like** +**Describe the solution you'd like**: A clear and concise description of what you want to happen. -**Describe alternatives you've considered** +**Describe alternatives you've considered**: A clear and concise description of any alternative solutions or features you've considered. -**Additional context** +**Additional context**: Add any other context or screenshots about the feature request here. diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 7c9f312..4ce9f62 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -4,11 +4,11 @@ Explain with one or more sentences what this change is doing. ## Have you done? - [ ] Code tests - [ ] Update documentation -- [ ] Update [changelog](https://github.com/MAIF/arta/blob/main/CHANGELOG.md). +- [ ] Update [changelog](https://github.com/MAIF/arta/blob/main/CHANGELOG.md) -## Details to be checked (optional) +## Details to be checked: (optional) If needed, add some details here in order to verify the change (e.g., how to test). -## Linked issues (optional) +## Linked issues: (optional) - Close ... - Close ... \ No newline at end of file diff --git a/.github/workflows/ci-cd-docs.yml b/.github/workflows/ci-cd-docs.yml index 6fbf9d8..dfa5e1e 100644 --- a/.github/workflows/ci-cd-docs.yml +++ b/.github/workflows/ci-cd-docs.yml @@ -16,7 +16,7 @@ on: jobs: build: if: ${{ github.actor != 'dependabot[bot]' }} - name: Check docs build + name: Build doc runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -37,6 +37,7 @@ jobs: path: "docs/site/" publish: if: success() && startsWith(github.ref, 'refs/tags') + name: Publish doc needs: build permissions: pages: write diff --git a/CHANGELOG.md b/CHANGELOG.md index 9842d00..c016135 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.7.0] - April, 2024 +## [0.7.0b] - April, 2024 ### New Features -- Beta release implementing what you can find in its [documentation](https://pages.github.com/MAIF/arta). +- Beta release implementing what you can find in its [documentation](https://pages.github.com/MAIF/arta/home). diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 398186f..601ed7d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -7,7 +7,7 @@ We encourage changes that make it easier to achieve our goals in an efficient wa ## Codebase -explain the layout of your repo. +Explain the layout of your repo. ## Workflow @@ -22,7 +22,7 @@ We follow the standard GitHub [fork & pull](https://help.github.com/articles/usi - Please make sure to follow the general quality guidelines (specified below) when developing your patch. - Please write additional tests covering your feature and adjust existing ones if needed before submitting your pull request. 1. Once your feature is complete, prepare the commit with a good commit message, for example: `Adding canary mode support for services #42` (note the reference to the ticket it aimed to resolve). -1. If it's a new feature, or a change of behaviour, document it on the [Arta docs](https://github.com/MAIF/arta/tree/master/manual), remember, an undocumented feature is not a feature. +1. If it's a new feature, or a change of behaviour, document it on the [Arta docs](https://pages.github.com/MAIF/arta/home), remember, an undocumented feature is not a feature. 1. Now it's finally time to [submit the pull request](https://help.github.com/articles/using-pull-requests)! - Please make sure to include a reference to the issue you're solving *in the comment* for the Pull Request, this will cause the PR to be linked properly with the Issue. Examples of good phrases for this are: "Resolves #1234" or "Refs #1234". 1. Now both committers and interested people will review your code. This process is to ensure the code we merge is of the best possible quality, and that no silly mistakes slip through. You're expected to follow-up these comments by adding new commits to the same branch. The commit messages of those commits can be more loose, for example: `Removed debugging using printline`, as they all will be squashed into one commit before merging into the main branch. diff --git a/README.md b/README.md index 3b4c110..da04048 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,122 @@ -# Arta +
++ Make rule handling simple +
++ + + + + +
-![Alt CI](https://github.com/MAIF/arta/actions/workflows/ci-cd.yml/badge.svg?branch=main) -![Alt Python](https://img.shields.io/badge/Python-3.9_--_3.12-blue) +--- -[![Alt MAIF Logo](https://static.maif.fr/resources/img/logo-maif.svg)](https://www.maif.fr/) +**Documentation:** [https://pages.github.com/MAIF/arta/home](https://pages.github.com/MAIF/arta/home) + +**Repository:** [https://github.com/MAIF/arta](https://github.com/MAIF/arta) + +--- + +## Overview + +**Arta** is a simple python rules engine designed for python developers. + +### Goal + +There is one main reason for using **Arta** and it was the main goal of its development at *MAIF*: increase business rules maintainability. + +In other words, facilitate rules handling in our python apps. + +### Origins + +The need of a python *rules engine* emerged when we were working on a new major release of our internal use of [Melusine](https://github.com/maif/melusine) (i.e., email qualification pipeline with ML capabilities). + +We were looking for a python library to *centralize, manage and standardize* all the implemented **business rules** we had but didn't find the perfect fit. + +Therefore, we decided to create this package and by extension of the MAIF's values, we planned to share it to the community. + +### Features + +* Standardize the definition of a rule. All rules are defined the same way in a unique place. +* Rules are released from the code base, which is less error prone and increases clearness. +* Use **Arta** whatever your field is. +* Great combination with Machine Learning: groups all the deterministic rules of your ML projects. + +### A Simple Example + +Create the three following files and run the `main.py` script (`python main.py` or `python3 main.py`). -**Arta** is a very simple python rules engine designed for and by python developers. +`rules.yaml` : -## Reference Documentation +```yaml +--- +rules: + default_rule_set: + admission: + ADMITTED: + simple_condition: input.power=="strength" or input.power=="fly" + action: set_admission + action_parameters: + value: True + NOT_ADMITTED: + simple_condition: null + action: set_admission + action_parameters: + value: False -The reference documentation is available [here](https://solid-eureka-93ze9kn.pages.github.io/). +actions_source_modules: + - actions +``` + +`actions.py` : + +```python +def set_admission(value: bool, **kwargs: Any) -> dict[str, bool]: + """Return a dictionary containing the admission result.""" + return {"is_admitted": value} +``` + +`main.py` : + +```python +from arta import RulesEngine + +eng = RulesEngine(config_path=".") + +data = { + "id": 1, + "name": "Superman", + "civilian_name": "Clark Kent", + "age": None, + "city": "Metropolis", + "language": "english", + "power": "fly", + "favorite_meal": "Spinach", + "secret_weakness": "Kryptonite", + } + +result = eng.apply_rules(input_data=data) + +print(result) +``` + +You should get: `{"admission": {"is_admitted": True}}` + +Check the [A Simple Example](https://pages.github.com/MAIF/arta/a_simple_example/) section for more details. + +## Installation + +Install using `pip install -U arta`. See the [Install](https://pages.github.com/MAIF/arta/installation/) section in the documentation for more details. ## What's New Want to see last updates, check the [Release Notes](https://github.com/MAIF/arta/releases) or the [Changelog](./CHANGELOG.md). ## Community + You can discuss and ask *Arta* related questions: - Issue tracker: [![github: MAIF/arta/issues](https://img.shields.io/github/issues/MAIF/arta.svg)](https://github.com/MAIF/arta/issues) @@ -32,4 +133,7 @@ and general hints on how to prepare your pull request. You can also ask for clar ## License -This project is Open Source and available under the Apache 2 License. \ No newline at end of file +This project is Open Source and available under the Apache 2 License. + +[![Alt MAIF Logo](https://static.maif.fr/resources/img/logo-maif.svg)](https://www.maif.fr/) + diff --git a/docs/mkdocs.yaml b/docs/mkdocs.yaml index b99d3f1..e03c30a 100644 --- a/docs/mkdocs.yaml +++ b/docs/mkdocs.yaml @@ -1,16 +1,16 @@ site_name: Arta -site_url: https://pages.github.com/MAIF/arta +site_url: https://maif.github.io/arta repo_url: https://github.com/MAIF/arta repo_name: MAIF/arta site_author: OSSbyMAIF Team docs_dir: pages theme: name: 'material' - logo: https://static.maif.fr/resources/img/logo-maif.svg - favicon: https://static.maif.fr/resources/img/logo-maif.svg + logo: assets/img/arta-fond-clair.svg + favicon: assets/img/arta-git.svg palette: primary: white - accent: light green + accent: red font: text: 'Roboto' code: 'Roboto Mono' @@ -51,9 +51,9 @@ plugins: - mkdocstrings - search nav: - - Home: index.md + - Home: home.md - Get Started: - - In a nutshell: in_a_nutshell.md + - A Simple Example: a_simple_example.md - Installation: installation.md - Why use Arta?: why.md - User Guide: diff --git a/docs/pages/a_simple_example.md b/docs/pages/a_simple_example.md new file mode 100644 index 0000000..a063be4 --- /dev/null +++ b/docs/pages/a_simple_example.md @@ -0,0 +1,239 @@ +## Intro + +As we already mentioned: ***Arta** is a simple python rules engine*. + +But what do we mean by *rules engine*? + +* **rule** : a set of different conditions that can be `True` or `False` (i.e., we say *verified* or *not verified*) triggering an action (i.e., any python callable object). +* **engine** : some code used for combining and evaluating different rules on some input data. + +## The Superhero School :school: :superhero: + +Imagine the following use case: + +*Your are managing a superhero school and you want to use some school rules in your python app.* + +The rules (intentionally simple) are: + +!!! success "Admission rules" + + If the applicant has a school authorized power then he is admitted, + + Else he is not. + +!!! example "Course selection rules" + + If he is speaking french and his age is known then he must take the "french" course, + + Else if his age is unknown (e.g., it's a very old superhero), then he must take the "senior" course, + + Else if he is not speaking french, then he must take the "international" course. + +!!! info "Send favorite meal rules" + + If he is admitted and has a prefered dish, then we send an email to the school cook with the dish name. + +### Rules + +You can define above rules for **Arta** in one simple *YAML* file : + +```yaml +--- +rules: + default_rule_set: + admission: + ADMITTED: + simple_condition: input.power=="strength" or input.power=="fly" + action: set_admission + action_parameters: + value: True + NOT_ADMITTED: + simple_condition: null + action: set_admission + action_parameters: + value: False + course: + FRENCH: + simple_condition: input.language=="french" and input.age!=None + action: set_course + action_parameters: + value: french + SENIOR: + simple_condition: input.age==None + action: set_course + action_parameters: + value: senior + INTERNATIONAL: + simple_condition: input.language!="french" + action: set_course + action_parameters: + value: international + favorite_meal: + EMAIL: + simple_condition: input.favorite_meal!=None + action: send_email + action_parameters: + mail_to: cook@super-heroes.test + mail_content: "Thanks for preparing once a month the following dish:" + meal: input.favorite_meal + +actions_source_modules: + - my_folder.actions +``` + +!!! info "Simple Conditions" + + This configuration uses what we called *simple conditions*, you can find out more [here](how_to.md#simple-condition). + +### Actions + +An **action** is triggered when the conditions are verified (i.e., `True`). + +**Actions** are defined by the following *keys* in the previous YAML file: + +```yaml + action: set_admission # (1) + action_parameters: # (2) + value: True +``` + +1. Name of the *python callable object* used as an **action function**. +2. The **action function** arguments. + +The **action function**'s implementation has to be located in the configured module: + +```yaml +actions_source_modules: + - my_folder.actions +``` + +And could be for example (intentionally simple) in `actions.py`: + +```python +def set_admission(value: bool, **kwargs: Any) -> dict[str, bool]: + """Return a dictionary containing the admission result.""" + return {"is_admitted": value} + + +def set_course(course_id: str, **kwargs: Any) -> dict[str, str]: + """Return the course id as a dictionary.""" + return {"course_id": course_id} + + +def send_email(mail_to: str, mail_content: str, meal: str, **kwargs: Any) -> bool: + """Send an email.""" + result: str | None = None + + if meal is not None: + # API call here + result = "sent" + + return result +``` + +!!! warning "\*\*kwargs" + + **\*\*kwargs** is mandatory in *action functions*. + +### Engine + +The *rules engine* is responsible for evaluating the [configured rules](#rules-definition) against some *data* (usually named *"input data"*). + +In our use case, the input data could be a list of applicants: + +```python +applicants = [ + { + "id": 1, + "name": "Superman", + "civilian_name": "Clark Kent", + "age": None, + "city": "Metropolis", + "language": "english", + "power": "fly", + "favorite_meal": "Spinach", + "secret_weakness": "Kryptonite", + "weapons": [], + }, + { + "id": 2, + "name": "Batman", + "civilian_name": "Bruce Wayne", + "age": 33, + "city": "Gotham City", + "language": "english", + "power": "strength", + "favorite_meal": None, + "secret_weakness": "Feel alone", + "weapons": ["Hands", "Batarang"], + }, + { + "id": 3, + "name": "Wonder Woman", + "civilian_name": "Diana Prince", + "age": 5000, + "city": "Island of Themyscira", + "language": "french", + "power": "strength", + "favorite_meal": None, + "secret_weakness": "Lost faith in humanity", + "weapons": ["Magic lasso", "Bulletproof bracelets", "Sword", "Shield"], + }, +] +``` + +Now, let's apply the **rules** on a single applicant: + +```python +from arta import RulesEngine + +eng = RulesEngine(config_path="/to/my/config/dir") # (1) + +result = eng.apply_rules(input_data=applicants[0]) + +print(result) # (2) +# { +# "admission": {"is_admitted": True}, +# "course": {"course_id": "senior"}, +# "favorite_meal": "sent" +# } +``` + +1. Many possibilites for instanciation, we will explain them later. +2. Print a single result for the first applicant. + +In the **rules engine** result, we have 3 outputs: + +* `"admission": {"is_admitted": True},` +* `"course": {"course_id": "senior"},` +* `"favorite_meal": "sent"` + +Each corresponds to one of these [rules](#quick-example-the-superhero-school). + +Here, we can apply the rules to all the **data set** (3 applicants) with a simple dictionary comprehension: + +```python +from arta import RulesEngine + +results = {applicant["name"]: eng.apply_rules(applicant) for applicant in applicants} + +print(results) +# { +# "Superman": { +# "admission": {"is_admitted": True}, +# "course": {"course_id": "senior"}, +# "favorite_meal": "sent"}, +# "Batman": { +# "admission": {"is_admitted": True}, +# "course": {"course_id": "international"}, +# "favorite_meal": None, +# }, +# "Wonder Woman": { +# "admission": {"is_admitted": True}, +# "course": {"course_id": "french"}, +# "favorite_meal": None, +# } +# } +``` + +It is the end of this **Arta**'s overview. If you want now to go deeper in how to use **Arta**, click [here](how_to.md). \ No newline at end of file diff --git a/docs/pages/assets/css/style.css b/docs/pages/assets/css/style.css new file mode 100644 index 0000000..c3acb8f --- /dev/null +++ b/docs/pages/assets/css/style.css @@ -0,0 +1,343 @@ +body { + font-family: 'Arvo', serif; + background-color: #2E3031; +} + +.otoColor { + background-color: #CF363B; +} + +a { + color: #FFF; + text-decoration: underline; +} + +a:hover { + color: #CF363B; +} + +.home { + position: fixed; + z-index: 1001; + margin-left: 10px; + margin-top: 10px; +} + +.home a { + color: #2E3031; +} + +.home a:hover { + color: #af8900; +} + +.tagN2 { + width: 20%; + display: block; + margin: 20px auto; +} + +.contentN2 { + padding-top: 30px; +} + +.contentN2 .col-md-6 { + padding-top: 70px; +} + +.colDashRight { + border-right: 1px dashed #F2F2F2; + padding-right: 60px; +} + +.titleOnLine { + color: #fff; + font-size: 36px; + text-transform: uppercase; + padding-left: 0px; +} + +.titleOnLine li { + list-style-type: none; +} + +.titleOnLine li:nth-child(even) { + color: #CF363B; +} + +h1 { + font-size: 24px; +} + +h2 { + color: #fff; + font-size: 21px; + text-transform: uppercase; +} + +.manifesto { + border: 0; + position: fixed; + right: 0; + top: 0; + z-index: 9000; +} + +.intro { + font-family: 'Roboto', serif; + font-size: 18px; + color: #fff; +} + +.details { + font-family: 'Roboto', serif; + font-size: 14px; + font-weight: 300; + color: #fff; + margin-top: 40px; +} + +.details ul { + padding-left: 20px +} + +.more-details { + text-align: center; + color: #fff; + padding-left: 60px; +} + +.more-details .pictoPortrait { + height: 50px; +} + +.youtube_player { + margin-bottom: 20px; +} + +.youtube_player { + position: relative; + padding-bottom: 56.25%; + padding-top: 30px; + height: 0; + overflow: hidden; +} + +.youtube_player iframe, +.youtube_player object, +.youtube_player embed { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; +} + +.youtube_player .tac_activate { + background: #2E3031; +} + +.more-details .pictoPaysage { + margin-top: 20px; + width: 70px +} + +.outer-circle { + height: 100px; + width: 100px; + position: relative; + border: 3px solid #CF363B; + border-radius: 50%; + margin: auto; + margin-top: 50px; +} + +.inner-circle { + position: absolute; + background: #CF363B; + border-radius: 50%; + height: 90px; + width: 90px; + top: 50%; + left: 50%; + margin: -45px 0px 0px -45px; + color: #2E3031; +} + +.inner-circle p { + margin-top: 40%; +} + +.inner-circle--lowerText { + font-size: 13px; +} + +.sidebar { + background: linear-gradient(90deg, #CF363B 50%, #2E3031 50%); + position: fixed; + top: 0; + bottom: 0; + left: 0; + z-index: 1000; + display: block; + overflow-x: hidden; + overflow-y: auto; + border-right: none; +} + +.sidebar-container { + display: flex; + height: 100%; + flex-direction: column; + justify-content: space-between; +} + +.sidebar-content { + flex-grow: 1; + padding-top: 20px; +} + +.footer-content { + width: 300%; + margin-left: -100%; + overflow: hidden; + bottom: 0; +} + +.footer-contentN2 { + position: relative; + width: 50%; + z-index: 1000; + margin-left: -5%; +} + +@media screen and (max-width: 991px) { + .intro { + font-size: 16px; + } + + .colDashRight { + border: none; + padding-right: 15px; + } + + .titleOnLine { + font-size: 26px; + } + + .titleOnLine li { + text-align: center; + } + + .details li, + .details { + list-style-type: none; + text-align: center; + } + + .more-details { + padding-left: 15px; + } +} + +@media screen and (max-width: 770px) { + .home { + position: absolute; + } + + .home .fa-home { + font-size: 1.5em; + } + + .sidebar-content { + width: 200px; + padding-left: 30px; + } + + .contentN2 { + padding-left: 30px; + } + + .sidebar-container { + flex-direction: column; + } + + .sidebar { + background: linear-gradient(180deg, #CF363B 50%, #2E3031 50%); + position: inherit; + } + + .footer-contentN2 { + margin-left: 0px; + margin-top: 20px; + width: 100%; + background-color: #CF363B; + } + + .intro { + text-align: left; + } + + .titleOnLine { + text-align: left; + } + + .titleOnLine li { + display: inline-block; + } + + .more-details { + text-align: left; + } + + .contentCircle { + margin-right: 20px; + } + + .tagN2 { + margin-top: 10px; + } + + .titleOnLine li { + text-align: left; + } + + .details li, + .details { + text-align: left; + } + + .details ul { + padding-left: 0px; + } + + .outer-circle { + margin-left: 0px; + text-align: center; + } + + .linkN2 { + padding-left: 20px; + } +} + +@media screen and (max-width: 400px) { + .outer-circle { + height: 80px; + width: 80px; + } + + .inner-circle { + height: 70px; + width: 70px; + margin: -35px 0px 0px -35px; + } + + .inner-circle p { + font-size: 12px; + } + + .inner-circle p.inner-circle--lowerText { + font-size: 10px; + } +} \ No newline at end of file diff --git a/docs/pages/assets/img/arta-fond-clair.svg b/docs/pages/assets/img/arta-fond-clair.svg new file mode 100644 index 0000000..89ad589 --- /dev/null +++ b/docs/pages/assets/img/arta-fond-clair.svg @@ -0,0 +1,96 @@ + + \ No newline at end of file diff --git a/docs/pages/assets/img/arta-git.svg b/docs/pages/assets/img/arta-git.svg new file mode 100644 index 0000000..b8d47fb --- /dev/null +++ b/docs/pages/assets/img/arta-git.svg @@ -0,0 +1,82 @@ + + \ No newline at end of file diff --git a/docs/pages/assets/img/etiquette.svg b/docs/pages/assets/img/etiquette.svg new file mode 100644 index 0000000..608bbbc --- /dev/null +++ b/docs/pages/assets/img/etiquette.svg @@ -0,0 +1,14 @@ + + + diff --git a/docs/pages/assets/img/footer.svg b/docs/pages/assets/img/footer.svg new file mode 100644 index 0000000..0a9fab1 --- /dev/null +++ b/docs/pages/assets/img/footer.svg @@ -0,0 +1,237 @@ + + + diff --git a/docs/pages/assets/js/tarteaucitron/LICENSE b/docs/pages/assets/js/tarteaucitron/LICENSE new file mode 100755 index 0000000..adde226 --- /dev/null +++ b/docs/pages/assets/js/tarteaucitron/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 AmauriC + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/docs/pages/assets/js/tarteaucitron/README.md b/docs/pages/assets/js/tarteaucitron/README.md new file mode 100755 index 0000000..2cbfb3a --- /dev/null +++ b/docs/pages/assets/js/tarteaucitron/README.md @@ -0,0 +1,101 @@ +[![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.me/SASAICAGENCY) + + +tarteaucitron.js +================ +Comply to the european cookie law is simple with the french *tarte au citron*. + +# What is this script? +The european cookie law regulates the management of cookies and you should ask your visitors their consent before exposing them to third party services. + +Clearly this script will: +- Disable all services by default, +- Display a banner on the first page view and a small one on other pages, +- Display a panel to allow or deny each services one by one, +- Activate services on the second page view if not denied, +- Store the consent in a cookie for 365 days. + +Bonus: +- Load service when user click on Allow (without reload of the page), +- Incorporate a fallback system (display a link instead of social button and a static banner instead of advertising). + +## Supported services +* Advertising network + * Amazon + * Clicmanager + * Criteo + * FERank (pub) + * Google Adsense + * Google Adsense Search (form) + * Google Adsense Search (result) + * Google Adwords (conversion) + * Google Adwords (remarketing) + * Pubdirecte + * Twenga + * vShop + +* APIs + * Google jsapi + * Google Maps + * Google Tag Manager + * Timeline JS + * Typekit (adobe) + +* Audience measurement + * Alexa + * Clicky + * Crazyegg + * FERank + * Get+ + * Google Analytics (ga.js) + * Google Analytics (universal) + * StatCounter + * VisualRevenue + * Xiti + +* Comment + * Disqus + * Facebook (commentaire) + +* Social network + * AddThis + * AddToAny (feed) + * AddToAny (share) + * eKomi + * Facebook + * Facebook (like box) + * Google+ + * Google+ (badge) + * Linkedin + * Pinterest + * Shareaholic + * ShareThis + * Twitter + * Twitter (cards) + * Twitter (timelines) + +* Support + * UserVoice + * Zopim + +* Video + * Calameo + * Dailymotion + * Prezi + * SlideShare + * Vimeo + * YouTube + + +## Visitors outside the EU +In PHP for example, you can bypass all the script by setting this var `tarteaucitron.user.bypass = true;` if the visitor is not in the EU. + +## Tested on +- IE 6+ +- FF 3+ +- Safari 4+ +- Chrome 14+ +- Opera 10+ + +# Installation guide +[Visit opt-out.ferank.eu](https://opt-out.ferank.eu/) diff --git a/docs/pages/assets/js/tarteaucitron/advertising.js b/docs/pages/assets/js/tarteaucitron/advertising.js new file mode 100755 index 0000000..813e11b --- /dev/null +++ b/docs/pages/assets/js/tarteaucitron/advertising.js @@ -0,0 +1 @@ +tarteaucitronNoAdBlocker = true; \ No newline at end of file diff --git a/docs/pages/assets/js/tarteaucitron/css/tarteaucitron.css b/docs/pages/assets/js/tarteaucitron/css/tarteaucitron.css new file mode 100755 index 0000000..d0f24c8 --- /dev/null +++ b/docs/pages/assets/js/tarteaucitron/css/tarteaucitron.css @@ -0,0 +1,545 @@ +/*** + * Responsive layout for the control panel + */ +@media screen and (max-width:479px) { + #tarteaucitron .tarteaucitronLine .tarteaucitronName { + width: 90% !important; + } + + #tarteaucitron .tarteaucitronLine .tarteaucitronAsk { + float: left !important; + margin: 10px 15px 5px; + } +} + +@media screen and (max-width:767px) { + #tarteaucitronAlertSmall #tarteaucitronCookiesListContainer, #tarteaucitron { + background: #fff; + border: 0 !important; + bottom: 0 !important; + height: 100% !important; + left: 0 !important; + margin: 0 !important; + max-height: 100% !important; + max-width: 100% !important; + top: 0 !important; + width: 100% !important; + } + + #tarteaucitron .tarteaucitronBorder { + border: 0 !important; + } + + #tarteaucitronAlertSmall #tarteaucitronCookiesListContainer #tarteaucitronCookiesList { + border: 0 !important; + } + + #tarteaucitron #tarteaucitronServices .tarteaucitronTitle { + text-align: left !important; + } +} + +@media screen and (min-width:768px) and (max-width:991px) { + #tarteaucitron { + border: 0 !important; + left: 0 !important; + margin: 0 5% !important; + max-height: 80% !important; + width: 90% !important; + } +} + +/*** + * Common value + */ +#tarteaucitron * { + zoom: 1; +} + +#tarteaucitron .clear { + clear: both; +} + +#tarteaucitron a { + color: rgb(66, 66, 66); + font-size: 11px; + font-weight: 700; + text-decoration: none; +} + +#tarteaucitronAlertBig a, #tarteaucitronAlertSmall a { + color: #fff; +} + +#tarteaucitron b { + font-size: 22px; + font-weight: 500; +} + +/*** + * Root div added just before + ++ It's a simple python rules engine designed for python developers. + There is one main reason for using Arta and it was the main goal of its development + at MAIF: increase business rules maintainability. + + + In other words, facilitate rules handling in a python app. +
+Configure your rules in YAML files
+ +Organize your rules like you want, create new conditions
+ +Easy to read, easy to maintain
+ +Things are in the right place
+(deterministic VS probabilistic)
+DOC
++ */ +#tarteaucitronRoot { + left: 0; + position: absolute; + right: 0; + top: 0; + width: 100%; +} + +#tarteaucitronRoot * { + box-sizing: initial; + color: #333; + font-family: sans-serif !important; + font-size: 14px; + line-height: normal; + vertical-align: initial; +} + +/*** + * Control panel + */ +#tarteaucitronBack { + background: #fff; + display: none; + height: 100%; + left: 0; + opacity: 0.7; + position: fixed; + top: 0; + width: 100%; + z-index: 2147483646; +} + +#tarteaucitron { + display: none; + max-height: 80%; + left: 50%; + margin: 0 auto 0 -430px; + padding: 0; + position: fixed; + top: 6%; + width: 860px; + z-index: 2147483647; +} + +#tarteaucitron .tarteaucitronBorder { + background: #fff; + border: 2px solid #333; + border-top: 0; + height: auto; + overflow: auto; +} + +#tarteaucitronAlertSmall #tarteaucitronCookiesListContainer #tarteaucitronClosePanelCookie, +#tarteaucitron #tarteaucitronClosePanel { + background: #333333; + color: #fff; + cursor: pointer; + font-size: 12px; + font-weight: 700; + text-decoration: none; + padding: 4px 0; + position: absolute; + right: 0; + text-align: center; + width: 70px; +} + +#tarteaucitron #tarteaucitronDisclaimer { + color: #555; + font-size: 12px; + margin: 15px auto 0; + width: 80%; +} + +#tarteaucitronAlertSmall #tarteaucitronCookiesListContainer #tarteaucitronCookiesList .tarteaucitronHidden, +#tarteaucitron #tarteaucitronServices .tarteaucitronHidden { + background: rgba(51, 51, 51, 0.07); +} + +#tarteaucitron #tarteaucitronServices .tarteaucitronHidden { + display: none; + position: relative; +} + +#tarteaucitronAlertSmall #tarteaucitronCookiesListContainer #tarteaucitronCookiesList .tarteaucitronTitle, +#tarteaucitron #tarteaucitronServices .tarteaucitronTitle, +#tarteaucitron #tarteaucitronInfo, +#tarteaucitron #tarteaucitronServices .tarteaucitronDetails { + background: #333; + color: #fff; + display: inline-block; + font-size: 14px; + font-weight: 700; + margin: 20px 0px 0px; + padding: 5px 20px; + text-align: left; + width: auto; +} + +#tarteaucitron #tarteaucitronServices .tarteaucitronMainLine .tarteaucitronName a, +#tarteaucitron #tarteaucitronServices .tarteaucitronTitle a { + color: #fff; + font-weight: 500; +} + +#tarteaucitron #tarteaucitronServices .tarteaucitronMainLine .tarteaucitronName a:hover, +#tarteaucitron #tarteaucitronServices .tarteaucitronTitle a:hover { + text-decoration: none !important; +} + +#tarteaucitron #tarteaucitronServices .tarteaucitronMainLine .tarteaucitronName a { + font-size: 22px; +} + +#tarteaucitron #tarteaucitronServices .tarteaucitronTitle a { + font-size: 14px; +} + +#tarteaucitronAlertSmall #tarteaucitronCookiesListContainer #tarteaucitronCookiesList .tarteaucitronTitle { + padding: 5px 10px; +} + +#tarteaucitron #tarteaucitronInfo, +#tarteaucitron #tarteaucitronServices .tarteaucitronDetails { + color: #fff; + display: none; + font-size: 12px; + font-weight: 500; + margin-top: 0; + max-width: 270px; + padding: 20px; + position: absolute; + z-index: 2147483647; +} + +#tarteaucitron #tarteaucitronInfo a { + color: #fff; + text-decoration: underline; +} + +#tarteaucitron #tarteaucitronServices .tarteaucitronLine:hover { + background: rgba(51, 51, 51, 0.2); +} + +#tarteaucitron #tarteaucitronServices .tarteaucitronLine { + background: rgba(51, 51, 51, 0.1); + border-left: 5px solid transparent; + margin: 0; + overflow: hidden; + padding: 15px 5px; +} + +#tarteaucitron #tarteaucitronServices .tarteaucitronMainLine { + background: #333; + border: 3px solid #333; + border-left: 9px solid #333; + border-top: 5px solid #333; + margin-bottom: 0; + margin-top: 21px; + position: relative; +} + +#tarteaucitron #tarteaucitronServices .tarteaucitronMainLine:hover { + background: #333; +} + +#tarteaucitron #tarteaucitronServices .tarteaucitronMainLine .tarteaucitronName { + margin-left: 15px; + margin-top: 2px; +} + +#tarteaucitron #tarteaucitronServices .tarteaucitronMainLine .tarteaucitronName b { + color: #fff; +} + +#tarteaucitron #tarteaucitronServices .tarteaucitronMainLine .tarteaucitronAsk { + margin-top: 0px !important; +} + +#tarteaucitron #tarteaucitronServices .tarteaucitronLine .tarteaucitronName { + display: inline-block; + float: left; + margin-left: 10px; + text-align: left; + width: 50%; +} + +#tarteaucitron #tarteaucitronServices .tarteaucitronLine .tarteaucitronName a:hover { + text-decoration: underline; +} + +#tarteaucitron #tarteaucitronServices .tarteaucitronLine .tarteaucitronAsk { + display: inline-block; + float: right; + margin: 7px 15px 0; + text-align: right; +} + +#tarteaucitron #tarteaucitronServices .tarteaucitronLine .tarteaucitronAsk .tarteaucitronAllow, +#tarteaucitron #tarteaucitronServices .tarteaucitronLine .tarteaucitronAsk .tarteaucitronDeny, +.tac_activate .tarteaucitronAllow { + background: gray; + border-radius: 4px; + color: #fff; + cursor: pointer; + display: inline-block; + padding: 6px 10px; + text-align: center; + text-decoration: none; + width: auto; +} + +#tarteaucitron #tarteaucitronServices .tarteaucitronLine .tarteaucitronName .tarteaucitronListCookies { + color: #333; + font-size: 12px; +} + +/*** + * Big alert + */ +.tarteaucitronAlertBigTop { + top: 0; +} + +.tarteaucitronAlertBigBottom { + bottom: 0; +} + +#tarteaucitronAlertBig { + background: #333; + color: #fff; + display: none; + font-size: 15px !important; + left: 0; + padding: 5px 5%; + position: fixed; + text-align: center; + width: 90%; + box-sizing: content-box; + z-index: 2147483645; +} + +#tarteaucitronAlertBig #tarteaucitronDisclaimerAlert, +#tarteaucitronAlertBig #tarteaucitronDisclaimerAlert b { + font: 15px verdana; + color: #fff; +} + +#tarteaucitronAlertBig #tarteaucitronDisclaimerAlert b { + font-weight: 700; +} + +#tarteaucitronAlertBig #tarteaucitronCloseAlert, #tarteaucitronAlertBig #tarteaucitronPersonalize { + background: #008300; + color: #fff; + cursor: pointer; + display: inline-block; + font-size: 16px; + padding: 5px 10px; + text-decoration: none; + margin-left: 7px; +} + +#tarteaucitronAlertBig #tarteaucitronCloseAlert { + background: #fff; + color: #333; + font-size: 13px; + margin-bottom: 3px; + margin-left: 7px; + padding: 4px 10px; +} + +#tarteaucitronPercentage { + background: #0A0; + box-shadow: 0 0 2px #fff, 0 1px 2px #555; + height: 5px; + left: 0; + position: fixed; + width: 0; + z-index: 2147483644; +} + +/*** + * Small alert + */ +#tarteaucitronAlertSmall { + background: #333; + bottom: 0; + display: none; + padding: 0; + position: fixed; + right: 0; + text-align: center; + width: auto; + z-index: 2147483646; +} + +#tarteaucitronAlertSmall #tarteaucitronManager { + color: #fff; + cursor: pointer; + display: inline-block; + font-size: 11px !important; + padding: 8px 10px 8px; +} + +#tarteaucitronAlertSmall #tarteaucitronManager:hover { + background: rgba(255, 255, 255, 0.05); +} + +#tarteaucitronAlertSmall #tarteaucitronManager #tarteaucitronDot { + background-color: gray; + border-radius: 5px; + display: block; + height: 8px; + margin-bottom: 1px; + margin-top: 5px; + overflow: hidden; + width: 100%; +} + +#tarteaucitronAlertSmall #tarteaucitronManager #tarteaucitronDot #tarteaucitronDotGreen, +#tarteaucitronAlertSmall #tarteaucitronManager #tarteaucitronDot #tarteaucitronDotYellow, +#tarteaucitronAlertSmall #tarteaucitronManager #tarteaucitronDot #tarteaucitronDotRed { + display: block; + float: left; + height: 100%; + width: 0%; +} + +#tarteaucitronAlertSmall #tarteaucitronManager #tarteaucitronDot #tarteaucitronDotGreen { + background-color: #1B870B; +} + +#tarteaucitronAlertSmall #tarteaucitronManager #tarteaucitronDot #tarteaucitronDotYellow { + background-color: #FBDA26; +} + +#tarteaucitronAlertSmall #tarteaucitronManager #tarteaucitronDot #tarteaucitronDotRed { + background-color: #9C1A1A; +} + +#tarteaucitronAlertSmall #tarteaucitronCookiesNumber { + background: rgba(255, 255, 255, 0.2); + color: #fff; + cursor: pointer; + display: inline-block; + font-size: 30px; + padding: 0px 10px; + vertical-align: top; +} + +#tarteaucitronAlertSmall #tarteaucitronCookiesNumber:hover { + background: rgba(255, 255, 255, 0.3); +} + +#tarteaucitronAlertSmall #tarteaucitronCookiesListContainer { + display: none; + max-height: 70%; + max-width: 500px; + position: fixed; + right: 0; + width: 100%; +} + +#tarteaucitronAlertSmall #tarteaucitronCookiesListContainer #tarteaucitronCookiesList { + background: #fff; + border: 2px solid #333; + color: #333; + font-size: 11px; + height: auto; + overflow: auto; + text-align: left; +} + +#tarteaucitronAlertSmall #tarteaucitronCookiesListContainer #tarteaucitronCookiesList b { + color: #333; +} + +#tarteaucitronAlertSmall #tarteaucitronCookiesListContainer #tarteaucitronCookiesTitle { + background: #333; + margin-top: 21px; + padding: 13px 0 9px 13px; + text-align: left; +} + +#tarteaucitronAlertSmall #tarteaucitronCookiesListContainer #tarteaucitronCookiesTitle b { + color: #fff; + font-size: 16px; +} + +#tarteaucitronAlertSmall #tarteaucitronCookiesListContainer #tarteaucitronCookiesList .tarteaucitronCookiesListMain { + background: rgba(51, 51, 51, 0.1); + padding: 7px 5px 10px; + word-wrap: break-word; +} + +#tarteaucitronAlertSmall #tarteaucitronCookiesListContainer #tarteaucitronCookiesList .tarteaucitronCookiesListMain:hover { + background: rgba(51, 51, 51, 0.2); +} + +#tarteaucitronAlertSmall #tarteaucitronCookiesListContainer #tarteaucitronCookiesList .tarteaucitronCookiesListMain a { + color: #333; + text-decoration: none; +} + +#tarteaucitronAlertSmall #tarteaucitronCookiesListContainer #tarteaucitronCookiesList .tarteaucitronCookiesListMain .tarteaucitronCookiesListLeft { + display: inline-block; + width: 50%; +} + +#tarteaucitronAlertSmall #tarteaucitronCookiesListContainer #tarteaucitronCookiesList .tarteaucitronCookiesListMain .tarteaucitronCookiesListLeft a b { + color: darkred; +} + +#tarteaucitronAlertSmall #tarteaucitronCookiesListContainer #tarteaucitronCookiesList .tarteaucitronCookiesListMain .tarteaucitronCookiesListRight { + color: #333; + display: inline-block; + font-size: 11px; + margin-left: 10%; + vertical-align: top; + width: 30%; +} + +/*** + * Fallback activate link + */ +.tac_activate { + background: #333; + color: #fff; + display: table; + font-size: 12px; + height: 100%; + line-height: initial; + margin: auto; + text-align: center; + width: 100%; +} + +.tac_float { + display: table-cell; + text-align: center; + vertical-align: middle; +} + +.tac_activate .tac_float b { + color: #fff; +} + +.tac_activate .tac_float .tarteaucitronAllow { + background-color: #1B870B; + display: inline-block; +} + +/*** + * CSS for services + */ +ins.ferank-publicite, ins.adsbygoogle { + text-decoration: none; +} + +div.amazon_product { + height:240px; + width:120px; +} \ No newline at end of file diff --git a/docs/pages/assets/js/tarteaucitron/lang/tarteaucitron.cs.js b/docs/pages/assets/js/tarteaucitron/lang/tarteaucitron.cs.js new file mode 100755 index 0000000..057d71f --- /dev/null +++ b/docs/pages/assets/js/tarteaucitron/lang/tarteaucitron.cs.js @@ -0,0 +1,65 @@ +/*global tarteaucitron */ +tarteaucitron.lang = { + "adblock": "Ahoj! Tato stránka je transparetní a umožňuje ti si přímo vybrat, jaké služby třetích stran chceš povolit.", + "adblock_call": "Pro úpravu osobních preferencí si, prosím, vypni adblock.", + "reload": "Načíst stránku znovu", + + "alertBigScroll": "Pokračováním ve scrollování,", + "alertBigClick": "Pokud pokračujete v brouzdání našich stránek,", + "alertBig": "povolujete všechny služby třetích stran.", + + "alertBigPrivacy": "Tato stránka využívá cookies a dává ti na výběr, co chceš aktivovat", + "alertSmall": "Spravovat služby", + "personalize": "Přizpůsobit", + "acceptAll": "OK, přijmout vše", + "close": "Zavřít", + + "all": "Nastavení všech služeb", + + "info": "Chrání tvé soukromí", + "disclaimer": "Povolením těchto služeb třetích stran, přijímáš jejich cookies, jež jsou nezbytné pro řádné fungování jejich technologií.", + "allow": "Povolit", + "deny": "Zamítnout", + "noCookie": "Tato služba nepoužívá cookies.", + "useCookie": "Tato služba může nainstalovat", + "useCookieCurrent": "Tato služba nainstalovala", + "useNoCookie": "Tato služba nenainstalovala žádné cookies.", + "more": "Dozvědět se více", + "source": "Zobrazit oficiální stránku", + "credit": "Správce cookies od tarteaucitron.js", + + "fallback": "je vypnutý.", + + "ads": { + "title": "Reklamní síť", + "details": "Prodejem reklamních ploch na této stránce mohou reklamní sítě vydělávat peníze." + }, + "analytic": { + "title": "Statistika návštěvnosti", + "details": "Služby pro analýzu návštěvníků slouží k vytvoření užitečných statistik návštěvnosti. Ty zase slouží ke zlepšení stránky." + }, + "social": { + "title": "Sociální sítě", + "details": "Sociální sítě mohou usnadnit práci se stránkou a pomáhají jí prosadit se pomocí sdílení." + }, + "video": { + "title": "Videa", + "details": "Video-hostingové služby pomáhají přidat na stránku bohaté mediální prvky." + }, + "comment": { + "title": "Komentáře", + "details": "Správce komentářů zajišťují vyplňování komentářů a bojují proti šíření spamu." + }, + "support": { + "title": "Podpora", + "details": "Služby podpory ti pomáhají spojit se s týmem stojícím za stránkou a umožňují ti vyjádřit se k jejím nedostatkům." + }, + "api": { + "title": "API", + "details": "API slouží k načtění skriptů: geolokace, vyhledávačů, překladů, ..." + }, + "other": { + "title": "Jiný", + "details": "Služby pro zobrazení webového obsahu." + } +}; diff --git a/docs/pages/assets/js/tarteaucitron/lang/tarteaucitron.de.js b/docs/pages/assets/js/tarteaucitron/lang/tarteaucitron.de.js new file mode 100755 index 0000000..23cdc5f --- /dev/null +++ b/docs/pages/assets/js/tarteaucitron/lang/tarteaucitron.de.js @@ -0,0 +1,65 @@ +/*global tarteaucitron */ +tarteaucitron.lang = { + "adblock": "Hallo! Diese Seite ist transparent und lässt Ihnen die Wahl der externen Services, die aktiviert werden dürfen.", + "adblock_call": "Bitte deaktivieren Sie Ihren 'Werbeblocker' um Konfigurieren zu können.", + "reload": "Seite neu laden", + + "alertBigScroll": "Durch die fortgesetzte blättern,", + "alertBigClick": "Wenn Sie diese Webseite benutzen,", + "alertBig": "stimmen Sie der Benutzung von externen Diensten zu", + + "alertBigPrivacy": "Diese Webseite verwendet 'Cookies' und ermöglicht dadurch Kontrolle, welche Dienste benutzt werden dürfen", + "alertSmall": "Service-Kontrolle", + "personalize": "Personalisieren", + "acceptAll": "OK, akzeptiere alles", + "close": "Beenden", + + "all": "Präferenz für alle Dienste", + + "info": "Schutz der Privatsphäre", + "disclaimer": "Wenn Sie diese Dienste nutzen, erlauben Sie deren 'Cookies' und Tracking-Funktionen, die zu ihrer ordnungsgemäßen Funktion notwendig sind.", + "allow": "Erlauben", + "deny": "Ablehnen", + "noCookie": "Dieser Dienst nutzt keine 'Cookies'.", + "useCookie": "Dieser Dienst kann installieren", + "useCookieCurrent": "Dieser Dienst hat installiert", + "useNoCookie": "Dieser Dienst hat keine 'Cookies' installiert.", + "more": "Weiter lesen", + "source": "Zur offiziellen Webseite", + "credit": "Cookies manager von tarteaucitron.js", + + "fallback": "ist deaktiviert.", + + "ads": { + "title": "Anzeigen Netzwerke", + "details": "Anzeigen Netzwerke können mit dem Verkauf von Werbeplatzierungen auf der Seite Einnahmen erhalten." + }, + "analytic": { + "title": "Besucher Zähldienste", + "details": "Die verwendeten Besucher Zähldienste generieren Statistiken die dabei helfen, die Seite zu verbessern." + }, + "social": { + "title": "Soziale Netzwerke", + "details": "Soziale Netzwerke können die Benutzbarkeit der Seite verbessern und ihren Bekanntheitsgrad erhöhen." + }, + "video": { + "title": "Videos", + "details": "Video Platformen erlauben Videoinhalte einzublenden und die Sichtbarkeit der Seite zu erhöhen." + }, + "comment": { + "title": "Kommentare", + "details": "Kommentar Manager erleichtern die Organisation von Kommentaren und helfen dabei Spam zu verhindern." + }, + "support": { + "title": "Support", + "details": "Support Dienste erlauben es die Urheber der Seite zu kontaktieren und sie zu verbessern." + }, + "api": { + "title": "APIs", + "details": "APIs werden benutzt um Skripte zu laden, wie: Geolokalisation, Suchmaschinen, Übersetzungen, ..." + }, + "other": { + "title": "Andere", + "details": "Dienste zum Anzeigen von Web-Inhalten." + } +}; diff --git a/docs/pages/assets/js/tarteaucitron/lang/tarteaucitron.en.js b/docs/pages/assets/js/tarteaucitron/lang/tarteaucitron.en.js new file mode 100755 index 0000000..90c8ebb --- /dev/null +++ b/docs/pages/assets/js/tarteaucitron/lang/tarteaucitron.en.js @@ -0,0 +1,65 @@ +/*global tarteaucitron */ +tarteaucitron.lang = { + "adblock": "Hello! This site is transparent and lets you chose the 3rd party services you want to allow.", + "adblock_call": "Please disable your adblocker to start customizing.", + "reload": "Refresh the page", + + "alertBigScroll": "By continuing to scroll,", + "alertBigClick": "If you continue to browse this website,", + "alertBig": "you are allowing all third-party services", + + "alertBigPrivacy": "This site uses cookies and gives you control over what you want to activate", + "alertSmall": "Manage services", + "personalize": "Personalize", + "acceptAll": "OK, accept all", + "close": "Close", + + "all": "Preference for all services", + + "info": "Protecting your privacy", + "disclaimer": "By allowing these third party services, you accept their cookies and the use of tracking technologies necessary for their proper functioning.", + "allow": "Allow", + "deny": "Deny", + "noCookie": "This service does not use cookie.", + "useCookie": "This service can install", + "useCookieCurrent": "This service has installed", + "useNoCookie": "This service has not installed any cookie.", + "more": "Read more", + "source": "View the official website", + "credit": "Cookies manager by tarteaucitron.js", + + "fallback": "is disabled.", + + "ads": { + "title": "Advertising network", + "details": "Ad networks can generate revenue by selling advertising space on the site." + }, + "analytic": { + "title": "Audience measurement", + "details": "The audience measurement services used to generate useful statistics attendance to improve the site." + }, + "social": { + "title": "Social networks", + "details": "Social networks can improve the usability of the site and help to promote it via the shares." + }, + "video": { + "title": "Videos", + "details": "Video sharing services help to add rich media on the site and increase its visibility." + }, + "comment": { + "title": "Comments", + "details": "Comments managers facilitate the filing of comments and fight against spam." + }, + "support": { + "title": "Support", + "details": "Support services allow you to get in touch with the site team and help to improve it." + }, + "api": { + "title": "APIs", + "details": "APIs are used to load scripts: geolocation, search engines, translations, ..." + }, + "other": { + "title": "Other", + "details": "Services to display web content." + } +}; diff --git a/docs/pages/assets/js/tarteaucitron/lang/tarteaucitron.es.js b/docs/pages/assets/js/tarteaucitron/lang/tarteaucitron.es.js new file mode 100755 index 0000000..65e5f9b --- /dev/null +++ b/docs/pages/assets/js/tarteaucitron/lang/tarteaucitron.es.js @@ -0,0 +1,65 @@ +/*global tarteaucitron */ +tarteaucitron.lang = { + "adblock": "Hola! Este sitio web es transparente y le da la opción de activar los servicios de terceros.", + "adblock_call": "Por favor deshabilite su AdBlocker para comenzar a personalizar.", + "reload": "Actualizar esta página", + + "alertBigScroll": "Al continuar para desplazarse,", + "alertBigClick": "Si continuas navegando por este sitio web,", + "alertBig": "estar permitiendo servicios terceros", + + "alertBigPrivacy": "Este sitio web usa cookies y te permite controlar lo que deseas activar", + "alertSmall": "Gestionar servicios", + "personalize": "Personalizar", + "acceptAll": "OK, aceptar todas", + "close": "Cerrar", + + "all": "Preference for all services", + + "info": "Protegiendo tu privacidad", + "disclaimer": "Aceptando estos servicios terceros, estas aceptando sus cookies y el uso de tecnologías de rastreo necesarias para su correcto funcionamiento.", + "allow": "Permitir", + "deny": "Denegar", + "noCookie": "Este servicio no usa cookie.", + "useCookie": "Este servicio puede instalar", + "useCookieCurrent": "Este servicio ha instalado", + "useNoCookie": "Este servicio no ha instalado ninguna cookie.", + "more": "Leer más", + "source": "Ver sitio web oficial", + "credit": "Gestor de cookies realizada por tarteaucitron.js", + + "fallback": "esta deshabilitado.", + + "ads": { + "title": "Red de publicidad", + "details": "Las redes publicitarias pueden generar ingresos mediante la venta de espacios publicitarios en el sitio." + }, + "analytic": { + "title": "Mediciión de audiencia", + "details": "Los servicios de medición de audiencia se usan para generar asistencia estadísticas útiles para mejorar el sitio." + }, + "social": { + "title": "Redes sociales", + "details": "Las redes sociales pueden aumentar la usabilidad del sitio web y ayudar a promoverlo a través de la contribución." + }, + "video": { + "title": "Videos", + "details": "Los servicios para compartir videos ayudan a añadir contenido enriquecido en el sitio web y aumentar su visibilidad." + }, + "comment": { + "title": "Comentarios", + "details": "El gestor de comentarios facilita la clasificación de comentarios y luchar contra spam." + }, + "support": { + "title": "Soporte", + "details": "Los servicios de soporte te permiten contactar con el sitio web y ayudar a mejorarlo." + }, + "api": { + "title": "APIs", + "details": "APIs se utilizan para cargar scripts: geolocalización, motor de búsqueda, traducciones, ..." + }, + "other": { + "title": "Otro", + "details": "Servicios para mostrar contenido web." + } +}; diff --git a/docs/pages/assets/js/tarteaucitron/lang/tarteaucitron.fr.js b/docs/pages/assets/js/tarteaucitron/lang/tarteaucitron.fr.js new file mode 100755 index 0000000..6512403 --- /dev/null +++ b/docs/pages/assets/js/tarteaucitron/lang/tarteaucitron.fr.js @@ -0,0 +1,65 @@ +/*global tarteaucitron */ +tarteaucitron.lang = { + "adblock": "Bonjour! Ce site joue la transparence et vous donne le choix des services tiers à activer.", + "adblock_call": "Merci de désactiver votre adblocker pour commencer la personnalisation.", + "reload": "Recharger la page", + + "alertBigScroll": "En continuant de défiler,", + "alertBigClick": "En poursuivant votre navigation,", + "alertBig": "vous acceptez l'utilisation de services tiers pouvant installer des cookies", + + "alertBigPrivacy": "Ce site utilise des cookies et vous donne le contrôle sur ce que vous souhaitez activer", + "alertSmall": "Gestion des services", + "acceptAll": "OK, tout accepter", + "personalize": "Personnaliser", + "close": "Fermer", + + "all": "Préférence pour tous les services", + + "info": "Protection de votre vie privée", + "disclaimer": "En autorisant ces services tiers, vous acceptez le dépôt et la lecture de cookies et l'utilisation de technologies de suivi nécessaires à leur bon fonctionnement.", + "allow": "Autoriser", + "deny": "Interdire", + "noCookie": "Ce service ne dépose aucun cookie.", + "useCookie": "Ce service peut déposer", + "useCookieCurrent": "Ce service a déposé", + "useNoCookie": "Ce service n'a déposé aucun cookie.", + "more": "En savoir plus", + "source": "Voir le site officiel", + "credit": "Gestion des cookies par tarteaucitron.js", + + "fallback": "est désactivé.", + + "ads": { + "title": "Régies publicitaires", + "details": "Les régies publicitaires permettent de générer des revenus en commercialisant les espaces publicitaires du site." + }, + "analytic": { + "title": "Mesure d'audience", + "details": "Les services de mesure d'audience permettent de générer des statistiques de fréquentation utiles à l'amélioration du site." + }, + "social": { + "title": "Réseaux sociaux", + "details": "Les réseaux sociaux permettent d'améliorer la convivialité du site et aident à sa promotion via les partages." + }, + "video": { + "title": "Vidéos", + "details": "Les services de partage de vidéo permettent d'enrichir le site de contenu multimédia et augmentent sa visibilité." + }, + "comment": { + "title": "Commentaires", + "details": "Les gestionnaires de commentaires facilitent le dépôt de vos commentaires et luttent contre le spam." + }, + "support": { + "title": "Support", + "details": "Les services de support vous permettent d'entrer en contact avec l'équipe du site et d'aider à son amélioration." + }, + "api": { + "title": "APIs", + "details": "Les APIs permettent de charger des scripts : géolocalisation, moteurs de recherche, traductions, ..." + }, + "other": { + "title": "Autre", + "details": "Services visant à afficher du contenu web." + } +}; diff --git a/docs/pages/assets/js/tarteaucitron/lang/tarteaucitron.it.js b/docs/pages/assets/js/tarteaucitron/lang/tarteaucitron.it.js new file mode 100755 index 0000000..8b2faf1 --- /dev/null +++ b/docs/pages/assets/js/tarteaucitron/lang/tarteaucitron.it.js @@ -0,0 +1,65 @@ +/*global tarteaucitron */ +tarteaucitron.lang = { + "adblock": "Benvenuto! Questo sito ti permette di attivare i servizi di terzi di tua scelta.", + "adblock_call": "Disabilita il tuo adblocker per iniziare la navigazione.", + "reload": "Aggiorna la pagina", + + "alertBigScroll": "Continuando a scorrere,", + "alertBigClick": "Continuando a navigare nel sito,", + "alertBig": "autorizzi l’utilizzo dei cookies inviati da domini di terze parti", + + "alertBigPrivacy": "Questo sito fa uso di cookies e ti consente di decidere se accettarli o rifiutarli", + "alertSmall": "Gestione dei servizi", + "acceptAll": "Ok, accetta tutto", + "personalize": "Personalizza", + "close": "Chiudi", + + "all": "Preferenze per tutti i servizi", + + "info": "Tutela della privacy", + "disclaimer": "Abilitando l'uso dei servizi di terze parti, accetti la ricezione dei cookies e l'uso delle tecnologie analitici necessarie al loro funzionamento.", + "allow": "Consenti", + "deny": "Blocca", + "noCookie": "Questo servizio non invia nessun cookie", + "useCookie": "Questo servizio puo' inviare", + "useCookieCurrent": "Questo servizio ha inviato", + "useNoCookie": "Questo servizio non ha inviato nessun cookie", + "more": "Saperne di più", + "source": "Vai al sito ufficiale", + "credit": "Gestione dei cookies da tarteaucitron.js", + + "fallback": "è disattivato", + + "ads": { + "title": "Regie pubblicitarie", + "details": "Le regie pubblicitarie producono redditi gestendo la commercializzazione degli spazi del sito dedicati alle campagne pubblicitarie" + }, + "analytic": { + "title": "Misura del pubblico", + "details": "I servizi di misura del pubblico permettono di raccogliere le statistiche utili al miglioramento del sito" + }, + "social": { + "title": "Reti sociali", + "details": "Le reti sociali permettono di migliorare l'aspetto conviviale del sito e di sviluppare la condivisione dei contenuti da parte degli utenti a fini promozionali." + }, + "video": { + "title": "Video", + "details": "I servizi di condivisione di video permettono di arricchire il sito di contenuti multimediali e di aumentare la sua visibilità" + }, + "comment": { + "title": "Commenti", + "details": "La gestione dei commenti utente aiuta a gestire la pubblicazione dei commenti e a lottare contro lo spamming" + }, + "support": { + "title": "Supporto", + "details": "I servizi di supporto ti consentono di contattare la team del sito e di contribuire al suo miglioramento" + }, + "api": { + "title": "API", + "details": "Le API permettono di implementare script diversi : geolocalizzazione, motori di ricerca, traduttori..." + }, + "other": { + "title": "Altro", + "details": "Servizi per visualizzare contenuti web." + } +}; diff --git a/docs/pages/assets/js/tarteaucitron/lang/tarteaucitron.pl.js b/docs/pages/assets/js/tarteaucitron/lang/tarteaucitron.pl.js new file mode 100755 index 0000000..6fe5b8e --- /dev/null +++ b/docs/pages/assets/js/tarteaucitron/lang/tarteaucitron.pl.js @@ -0,0 +1,66 @@ +/*global tarteaucitron */ +tarteaucitron.lang = { + "adblock": "Witaj! Ta witryna oferuje przejrzystosc i daje mozliwosc wyboru aktywacji uslug zewnetrznych.", + "adblock_call": "Prosze wylaczyc adblocker aby rozpoczac dostosowanie do potrzeb uzytkownika.", + "reload": "Odswiez strone", + + "alertBigScroll": "Poprzez kontynuowanie przewijania,", + "alertBigClick": "Pozostajac na tej stronie", + "alertBig": "zgadzasz sie na korzystanie ze wszystkich zewnetrzynych uslug", + + "alertBigPrivacy": "Ta witryna używa plików cookie i pozwala kontrolować ich aktywacje", + "alertSmall": "Zarządzanie usługami", + "personalize": "Personalizacja", + "acceptAll": "OK, akceptuję wszystko", + "close": "zamknij", + + "all": "Preferencja dla wszystkich usług", + + "info": "Ochrona prywatności", + "disclaimer": "Zgadzajac sie na korzystanie z uslug zewnetrznych , akceptuje ich pliki cookies oraz wykorzystanie technologii niezbędnych do ich funkcjonowania.", + "allow": "Zezwalaj", + "deny": "Odmów", + "noCookie": "Ta usługa nie korzysta z plików cookie.", + "useCookie": "Ta usługa może zainstalować pliki cookie", + "useCookieCurrent": "Ta usługa zainstalowala plikie cookie", + "useNoCookie": "Ta usługa nie zainstalowala żadnego pliku cookie.", + "more": "Więcej informacji", + "source": "Zobacz oficjalną stronę internetowa", + "credit": "Cookies menadżer z tarteaucitron.js", + + "fallback": "jest nieaktywna.", + + "ads": { + "title": "Sieć reklamowa", + "details": "Sieci reklamowe mogą generować przychody ze sprzedaży powierzchni reklamowej na stronie." + }, + "analytic": { + "title": "Pomiar ogladalnosci", + "details": "Usługi pomiaru oglądalności wykorzystywane sa do generowania przydatnych statystyk potrzebnych w doskonaleniu strony." + }, + "social": { + "title": "Portale społecznościowe", + "details": "Sieci społecznościowe mogą poprawić użyteczność serwisu i pomóc w promocji za pośrednictwem propagacji strony." + }, + "video": { + "title": "Filmy", + "details": "Usługa udostępniania wideo pomoże dodać multimedia do strony i zwiększyć jej ogladalność." + }, + "comment": { + "title": "Komentarze", + "details": "Zarządzanie komentarzami ułatwia komentowanie i zwalcza spam." + }, + "support": { + "title": "Pomoc", + "details": "Usługa pomocy technicznej pozwala, skontaktować się z administratorem witryny i pomaga ją udoskonalić." + }, + "api": { + "title": "APIs", + "details": "APIs służą do ładowania skryptów: geolokalizacji, wyszukiwarek, tłumaczenia, ..." + }, + "other": { + "title": "Inny", + "details": "Usługi do wyświetlania treści internetowych." + } + +}; diff --git a/docs/pages/assets/js/tarteaucitron/lang/tarteaucitron.pt.js b/docs/pages/assets/js/tarteaucitron/lang/tarteaucitron.pt.js new file mode 100755 index 0000000..690fd20 --- /dev/null +++ b/docs/pages/assets/js/tarteaucitron/lang/tarteaucitron.pt.js @@ -0,0 +1,61 @@ +/*global tarteaucitron */ +tarteaucitron.lang = { + "adblock": "Olá! Em uma açao de transparencia, este site lhe dá a opção de quais serviços terceiros deseje ativar.", + "adblock_call": "Por favor, desative seu bloqueador de publicidades para poder customizar.", + "reload": "Atualizar esta página", + + "alertBigScroll": "Ao continuar a rolar,", + "alertBigClick": "Se você continuar a navegaçao neste site,", + "alertBig": "você estará aceitando todos os serviços terceiros", + + "alertBigPrivacy": "Esse site utiliza cookies and lhe dá controle sobre o que você quer ativar", + "alertSmall": "Gerenciar serviços", + "personalize": "Personalizar", + "acceptAll": "OK, aceitar tudo", + "close": "Fechar", + "all": "Definições dos serviços", + "info": "Proteger sua privacidade", + "disclaimer": "Ao aceitar os serviços terceiros, você aceita o uso de cookies em conjunto de tecnologias de rastreamento que lhe são necessárias para funcionar", + "allow": "Autorizar", + "deny": "Recusar", + "noCookie": "Este serviço não usa cookies.", + "useCookie": "Este serviço pode instalar", + "useCookieCurrent": "Este serviço instalou", + "useNoCookie": "Este serviço não instalou nenhum cookie.", + "more": "Ler mais", + "source": "Ver o site oficial", + "credit": "Gerenciador de cookies por tarteaucitron.js", + "fallback": "está desativado.", + "ads": { + "title": "Rede de anúncios", + "details": "As redes de anúncios podem gerar receitas com a venda de espaço publicitário no site." + }, + "analytic": { + "title": "Medição de audiência", + "details": "Serviços de medição de audiência usados para gerar estatísticas no intuito de melhorar o site." + }, + "social": { + "title": "Rede sociais", + "details": "Rede sociais podem ameliorar o utilização do site e ajudar a promove-lo via compartilhamentos." + }, + "video": { + "title": "Vídeos", + "details": "Video sharing services help to add rich media on the site and increase its visibility." + }, + "comment": { + "title": "Comentários", + "details": "Gerenciadores de comentários facilitam o sistema de comentários e lutam contra o spam." + }, + "support": { + "title": "Suporte", + "details": "Serviços de suporte lhe ajudam a entrar em contato com a equipe de suporte." + }, + "api": { + "title": "APIs", + "details": "APIs são usadas para carregar scripts: geolocalização, motores de pesquisa, traduções, ..." + }, + "other": { + "title": "De outros", + "details": "Serviços para exibir conteúdo da web." + } +}; diff --git a/docs/pages/assets/js/tarteaucitron/lang/tarteaucitron.ru.js b/docs/pages/assets/js/tarteaucitron/lang/tarteaucitron.ru.js new file mode 100755 index 0000000..d99370c --- /dev/null +++ b/docs/pages/assets/js/tarteaucitron/lang/tarteaucitron.ru.js @@ -0,0 +1,65 @@ +/*global tarteaucitron */ +tarteaucitron.lang = { + "adblock": "Привет! Этот сайт совершенно открытый и позволяет вам выбрать сервисы третьих лиц, которым вы хотите дать доступ.", + "adblock_call": "Пожалуйста дезактивируйте АдБлокер чтобы начать настройку.", + "reload": "Перезагрузите страницу", + + "alertBigScroll": "Продолжая прокрутки", + "alertBigClick": "Если вы продолжаете использовать сайт", + "alertBig": "вы позволяете сервисы третьих лиц", + + "alertBigPrivacy": "Этот сайт использует кукис и позволяет вам контролировать сервисы которые вы хотите активировать", + "alertSmall": "Настройка сервисов", + "personalize": "Персонализировать", + "acceptAll": "Ок, все активировать", + "close": "Закрыть", + + "all": "Преференция всем сервисам", + + "info": "Защитить вашу конфиденциальность", + "disclaimer": "Активирование сервисов третьих лиц позволяет использование их кукис и технолоний отслеживания необходимых для их функционирования", + "allow": "Позролить", + "deny": "Не позволить", + "noCookie": "Этот сервис не использует кукис.", + "useCookie": "Этот сервис может быть инсталирован", + "useCookieCurrent": "Этот сервис инсталирован", + "useNoCookie": "Этот сервис не использует кукис.", + "more": "Подробнее", + "source": "Посетите официальный сайт", + "credit": "Кукис манаджер tarteaucitron.js", + + "fallback": "Деактивирован.", + + "ads": { + "title": "Рекламная сеть", + "details": "Мы позволяем вам аренду нашей рекламной сети." + }, + "analytic": { + "title": "Измерение аудиенции", + "details": "Измерение аудиенции сайта для статистики помогают улучшить предлагаемый сервис." + }, + "social": { + "title": "Социальная сеть", + "details": "Социальная сеть сайтов помогает улучшить предлагаемый сервис через обмен информации." + }, + "video": { + "title": "Видео", + "details": "Обмен видео информации позволяет улучшить сервис и увеличит траффик сайта." + }, + "comment": { + "title": "Комментарии", + "details": "Манаджер комментариев позволяет обмен информации и борьбу со спамом." + }, + "support": { + "title": "Помощь", + "details": "Помощь позволяет вам контактировать напрямую сайт манаджер и улучшить предлагаемый сервис." + }, + "api": { + "title": "АПИ", + "details": "АПИ используются для загрузки скриптов; геолокация, поисковый мотор и переводы..." + }, + "other": { + "title": "Другие", + "details": "Службы для отображения веб-контента." + } +}; diff --git a/docs/pages/assets/js/tarteaucitron/tarteaucitron.js b/docs/pages/assets/js/tarteaucitron/tarteaucitron.js new file mode 100755 index 0000000..88cd673 --- /dev/null +++ b/docs/pages/assets/js/tarteaucitron/tarteaucitron.js @@ -0,0 +1,1265 @@ +/*jslint browser: true, evil: true */ + +// define correct path for files inclusion +var scripts = document.getElementsByTagName('script'), + path = scripts[scripts.length - 1].src.split('?')[0], + cdn = path.split('/').slice(0, -1).join('/') + '/', + alreadyLaunch = (alreadyLaunch === undefined) ? 0 : alreadyLaunch, + tarteaucitronForceLanguage = (tarteaucitronForceLanguage === undefined) ? '' : tarteaucitronForceLanguage, + tarteaucitronProLoadServices, + tarteaucitronNoAdBlocker = false; + +var tarteaucitron = { + "version": 323, + "cdn": cdn, + "user": {}, + "lang": {}, + "services": {}, + "added": [], + "idprocessed": [], + "state": [], + "launch": [], + "parameters": {}, + "isAjax": false, + "reloadThePage": false, + "init": function (params) { + "use strict"; + var origOpen; + + tarteaucitron.parameters = params; + if (alreadyLaunch === 0) { + alreadyLaunch = 1; + if (window.addEventListener) { + window.addEventListener("load", function () { + tarteaucitron.load(); + tarteaucitron.fallback(['tarteaucitronOpenPanel'], function (elem) { + elem.addEventListener("click", function (event) { + tarteaucitron.userInterface.openPanel(); + event.preventDefault(); + }, false); + }, true); + }, false); + window.addEventListener("scroll", function () { + var scrollPos = window.pageYOffset || document.documentElement.scrollTop, + heightPosition; + if (document.getElementById('tarteaucitronAlertBig') !== null && !tarteaucitron.highPrivacy) { + if (document.getElementById('tarteaucitronAlertBig').style.display === 'block') { + heightPosition = document.getElementById('tarteaucitronAlertBig').offsetHeight + 'px'; + + if (scrollPos > (screen.height * 2)) { + tarteaucitron.userInterface.respondAll(true); + } else if (scrollPos > (screen.height / 2)) { + document.getElementById('tarteaucitronDisclaimerAlert').innerHTML = '' + tarteaucitron.lang.alertBigScroll + ' ' + tarteaucitron.lang.alertBig; + } + + if (tarteaucitron.orientation === 'top') { + document.getElementById('tarteaucitronPercentage').style.top = heightPosition; + } else { + document.getElementById('tarteaucitronPercentage').style.bottom = heightPosition; + } + document.getElementById('tarteaucitronPercentage').style.width = ((100 / (screen.height * 2)) * scrollPos) + '%'; + } + } + }, false); + window.addEventListener("keydown", function (evt) { + if (evt.keyCode === 27) { + tarteaucitron.userInterface.closePanel(); + } + }, false); + window.addEventListener("hashchange", function () { + if (document.location.hash === tarteaucitron.hashtag && tarteaucitron.hashtag !== '') { + tarteaucitron.userInterface.openPanel(); + } + }, false); + window.addEventListener("resize", function () { + if (document.getElementById('tarteaucitron') !== null) { + if (document.getElementById('tarteaucitron').style.display === 'block') { + tarteaucitron.userInterface.jsSizing('main'); + } + } + + if (document.getElementById('tarteaucitronCookiesListContainer') !== null) { + if (document.getElementById('tarteaucitronCookiesListContainer').style.display === 'block') { + tarteaucitron.userInterface.jsSizing('cookie'); + } + } + }, false); + } else { + window.attachEvent("onload", function () { + tarteaucitron.load(); + tarteaucitron.fallback(['tarteaucitronOpenPanel'], function (elem) { + elem.attachEvent("onclick", function (event) { + tarteaucitron.userInterface.openPanel(); + event.preventDefault(); + }); + }, true); + }); + window.attachEvent("onscroll", function () { + var scrollPos = window.pageYOffset || document.documentElement.scrollTop, + heightPosition; + if (document.getElementById('tarteaucitronAlertBig') !== null && !tarteaucitron.highPrivacy) { + if (document.getElementById('tarteaucitronAlertBig').style.display === 'block') { + heightPosition = document.getElementById('tarteaucitronAlertBig').offsetHeight + 'px'; + + if (scrollPos > (screen.height * 2)) { + tarteaucitron.userInterface.respondAll(true); + } else if (scrollPos > (screen.height / 2)) { + document.getElementById('tarteaucitronDisclaimerAlert').innerHTML = '' + tarteaucitron.lang.alertBigScroll + ' ' + tarteaucitron.lang.alertBig; + } + if (tarteaucitron.orientation === 'top') { + document.getElementById('tarteaucitronPercentage').style.top = heightPosition; + } else { + document.getElementById('tarteaucitronPercentage').style.bottom = heightPosition; + } + document.getElementById('tarteaucitronPercentage').style.width = ((100 / (screen.height * 2)) * scrollPos) + '%'; + } + } + }); + window.attachEvent("onkeydown", function (evt) { + if (evt.keyCode === 27) { + tarteaucitron.userInterface.closePanel(); + } + }); + window.attachEvent("onhashchange", function () { + if (document.location.hash === tarteaucitron.hashtag && tarteaucitron.hashtag !== '') { + tarteaucitron.userInterface.openPanel(); + } + }); + window.attachEvent("onresize", function () { + if (document.getElementById('tarteaucitron') !== null) { + if (document.getElementById('tarteaucitron').style.display === 'block') { + tarteaucitron.userInterface.jsSizing('main'); + } + } + + if (document.getElementById('tarteaucitronCookiesListContainer') !== null) { + if (document.getElementById('tarteaucitronCookiesListContainer').style.display === 'block') { + tarteaucitron.userInterface.jsSizing('cookie'); + } + } + }); + } + + if (typeof XMLHttpRequest !== 'undefined') { + origOpen = XMLHttpRequest.prototype.open; + XMLHttpRequest.prototype.open = function () { + + if (window.addEventListener) { + this.addEventListener("load", function () { + if (typeof tarteaucitronProLoadServices === 'function') { + tarteaucitronProLoadServices(); + } + }, false); + } else if (typeof this.attachEvent !== 'undefined') { + this.attachEvent("onload", function () { + if (typeof tarteaucitronProLoadServices === 'function') { + tarteaucitronProLoadServices(); + } + }); + } else { + if (typeof tarteaucitronProLoadServices === 'function') { + setTimeout(tarteaucitronProLoadServices, 1000); + } + } + + try { + origOpen.apply(this, arguments); + } catch (err) {} + }; + } + } + }, + "load": function () { + "use strict"; + var cdn = tarteaucitron.cdn, + language = tarteaucitron.getLanguage(), + pathToLang = cdn + 'lang/tarteaucitron.' + language + '.js?v=' + tarteaucitron.version, + pathToServices = cdn + 'tarteaucitron.services.js?v=' + tarteaucitron.version, + linkElement = document.createElement('link'), + defaults = { + "adblocker": false, + "hashtag": '#tarteaucitron', + "highPrivacy": false, + "orientation": "top", + "removeCredit": false, + "showAlertSmall": true, + "cookieslist": true + }, + params = tarteaucitron.parameters; + + // Step 0: get params + if (params !== undefined) { + tarteaucitron.extend(defaults, params); + } + + // global + tarteaucitron.orientation = defaults.orientation; + tarteaucitron.hashtag = defaults.hashtag; + tarteaucitron.highPrivacy = defaults.highPrivacy; + + // Step 1: load css + linkElement.rel = 'stylesheet'; + linkElement.type = 'text/css'; + linkElement.href = cdn + 'css/tarteaucitron.css?v=' + tarteaucitron.version; + document.getElementsByTagName('head')[0].appendChild(linkElement); + + // Step 2: load language and services + tarteaucitron.addScript(pathToLang, '', function () { + tarteaucitron.addScript(pathToServices, '', function () { + + var body = document.body, + div = document.createElement('div'), + html = '', + index, + orientation = 'Top', + cat = ['ads', 'analytic', 'api', 'comment', 'social', 'support', 'video', 'other'], + i; + + cat = cat.sort(function (a, b) { + if (tarteaucitron.lang[a].title > tarteaucitron.lang[b].title) { return 1; } + if (tarteaucitron.lang[a].title < tarteaucitron.lang[b].title) { return -1; } + return 0; + }); + + // Step 3: prepare the html + html += '
'; + html += '
'; + html += '
'; + + if (defaults.orientation === 'bottom') { + orientation = 'Bottom'; + } + + if (defaults.highPrivacy) { + html += '
'; + } else { + html += '
'; + html += '
'; + } + + if (defaults.showAlertSmall === true) { + html += '
'; + } + html += ''; + } + + tarteaucitron.addScript(tarteaucitron.cdn + 'advertising.js?v=' + tarteaucitron.version, '', function () { + if (tarteaucitronNoAdBlocker === true || defaults.adblocker === false) { + div.id = 'tarteaucitronRoot'; + body.appendChild(div, body); + div.innerHTML = html; + + if (tarteaucitron.job !== undefined) { + tarteaucitron.job = tarteaucitron.cleanArray(tarteaucitron.job); + for (index = 0; index < tarteaucitron.job.length; index += 1) { + tarteaucitron.addService(tarteaucitron.job[index]); + } + } + + tarteaucitron.isAjax = true; + tarteaucitron.job.push = function (id) { + + // ie <9 hack + if (typeof tarteaucitron.job.indexOf === 'undefined') { + tarteaucitron.job.indexOf = function (obj, start) { + var i, + j = this.length; + for (i = (start || 0); i < j; i += 1) { + if (this[i] === obj) { return i; } + } + return -1; + }; + } + + if (tarteaucitron.job.indexOf(id) === -1) { + Array.prototype.push.call(this, id); + } + tarteaucitron.launch[id] = false; + tarteaucitron.addService(id); + }; + + if (document.location.hash === tarteaucitron.hashtag && tarteaucitron.hashtag !== '') { + tarteaucitron.userInterface.openPanel(); + } + + tarteaucitron.cookie.number(); + setInterval(tarteaucitron.cookie.number, 60000); + } + }, defaults.adblocker); + + if (defaults.adblocker === true) { + setTimeout(function () { + if (tarteaucitronNoAdBlocker === false) { + html = '
'; + html += '
'; + div.id = 'tarteaucitronRoot'; + body.appendChild(div, body); + div.innerHTML = html; + tarteaucitron.pro('!adblocker=true'); + } else { + tarteaucitron.pro('!adblocker=false'); + } + }, 1500); + } + }); + }); + }, + "addService": function (serviceId) { + "use strict"; + var html = '', + s = tarteaucitron.services, + service = s[serviceId], + cookie = tarteaucitron.cookie.read(), + hostname = document.location.hostname, + hostRef = document.referrer.split('/')[2], + isNavigating = (hostRef === hostname) ? true : false, + isAutostart = (!service.needConsent) ? true : false, + isWaiting = (cookie.indexOf(service.key + '=wait') >= 0) ? true : false, + isDenied = (cookie.indexOf(service.key + '=false') >= 0) ? true : false, + isAllowed = (cookie.indexOf(service.key + '=true') >= 0) ? true : false, + isResponded = (cookie.indexOf(service.key + '=false') >= 0 || cookie.indexOf(service.key + '=true') >= 0) ? true : false; + + if (tarteaucitron.added[service.key] !== true) { + tarteaucitron.added[service.key] = true; + + html += '
'; + + tarteaucitron.userInterface.css('tarteaucitronServicesTitle_' + service.type, 'display', 'block'); + + if (document.getElementById('tarteaucitronServices_' + service.type) !== null) { + document.getElementById('tarteaucitronServices_' + service.type).innerHTML += html; + } + + tarteaucitron.userInterface.order(service.type); + } + + // allow by default for non EU + if (isResponded === false && tarteaucitron.user.bypass === true) { + isAllowed = true; + tarteaucitron.cookie.create(service.key, true); + } + + if ((!isResponded && (isAutostart || (isNavigating && isWaiting)) && !tarteaucitron.highPrivacy) || isAllowed) { + if (!isAllowed) { + tarteaucitron.cookie.create(service.key, true); + } + if (tarteaucitron.launch[service.key] !== true) { + tarteaucitron.launch[service.key] = true; + service.js(); + } + tarteaucitron.state[service.key] = true; + tarteaucitron.userInterface.color(service.key, true); + } else if (isDenied) { + if (typeof service.fallback === 'function') { + service.fallback(); + } + tarteaucitron.state[service.key] = false; + tarteaucitron.userInterface.color(service.key, false); + } else if (!isResponded) { + tarteaucitron.cookie.create(service.key, 'wait'); + if (typeof service.fallback === 'function') { + service.fallback(); + } + tarteaucitron.userInterface.color(service.key, 'wait'); + tarteaucitron.userInterface.openAlert(); + } + + tarteaucitron.cookie.checkCount(service.key); + }, + "cleanArray": function cleanArray(arr) { + "use strict"; + var i, + len = arr.length, + out = [], + obj = {}, + s = tarteaucitron.services; + + for (i = 0; i < len; i += 1) { + if (!obj[arr[i]]) { + obj[arr[i]] = {}; + if (tarteaucitron.services[arr[i]] !== undefined) { + out.push(arr[i]); + } + } + } + + out = out.sort(function (a, b) { + if (s[a].type + s[a].key > s[b].type + s[b].key) { return 1; } + if (s[a].type + s[a].key < s[b].type + s[b].key) { return -1; } + return 0; + }); + + return out; + }, + "userInterface": { + "css": function (id, property, value) { + "use strict"; + if (document.getElementById(id) !== null) { + document.getElementById(id).style[property] = value; + } + }, + "respondAll": function (status) { + "use strict"; + var s = tarteaucitron.services, + service, + key, + index = 0; + + for (index = 0; index < tarteaucitron.job.length; index += 1) { + service = s[tarteaucitron.job[index]]; + key = service.key; + if (tarteaucitron.state[key] !== status) { + if (status === false && tarteaucitron.launch[key] === true) { + tarteaucitron.reloadThePage = true; + } + if (tarteaucitron.launch[key] !== true && status === true) { + tarteaucitron.launch[key] = true; + tarteaucitron.services[key].js(); + } + tarteaucitron.state[key] = status; + tarteaucitron.cookie.create(key, status); + tarteaucitron.userInterface.color(key, status); + } + } + }, + "respond": function (el, status) { + "use strict"; + var key = el.id.replace(new RegExp("(Eng[0-9]+|Allow|Deni)ed", "g"), ''); + + // return if same state + if (tarteaucitron.state[key] === status) { + return; + } + + if (status === false && tarteaucitron.launch[key] === true) { + tarteaucitron.reloadThePage = true; + } + + // if not already launched... launch the service + if (status === true) { + if (tarteaucitron.launch[key] !== true) { + tarteaucitron.launch[key] = true; + tarteaucitron.services[key].js(); + } + } + tarteaucitron.state[key] = status; + tarteaucitron.cookie.create(key, status); + tarteaucitron.userInterface.color(key, status); + }, + "color": function (key, status) { + "use strict"; + var gray = '#808080', + greenDark = '#1B870B', + greenLight = '#E6FFE2', + redDark = '#9C1A1A', + redLight = '#FFE2E2', + yellowDark = '#FBDA26', + c = 'tarteaucitron', + nbDenied = 0, + nbPending = 0, + nbAllowed = 0, + sum = tarteaucitron.job.length, + index; + + if (status === true) { + tarteaucitron.userInterface.css(key + 'Line', 'borderLeft', '5px solid ' + greenDark); + tarteaucitron.userInterface.css(key + 'Allowed', 'backgroundColor', greenDark); + tarteaucitron.userInterface.css(key + 'Denied', 'backgroundColor', gray); + } else if (status === false) { + tarteaucitron.userInterface.css(key + 'Line', 'borderLeft', '5px solid ' + redDark); + tarteaucitron.userInterface.css(key + 'Allowed', 'backgroundColor', gray); + tarteaucitron.userInterface.css(key + 'Denied', 'backgroundColor', redDark); + } + + // check if all services are allowed + for (index = 0; index < sum; index += 1) { + if (tarteaucitron.state[tarteaucitron.job[index]] === false) { + nbDenied += 1; + } else if (tarteaucitron.state[tarteaucitron.job[index]] === undefined) { + nbPending += 1; + } else if (tarteaucitron.state[tarteaucitron.job[index]] === true) { + nbAllowed += 1; + } + } + + tarteaucitron.userInterface.css(c + 'DotGreen', 'width', ((100 / sum) * nbAllowed) + '%'); + tarteaucitron.userInterface.css(c + 'DotYellow', 'width', ((100 / sum) * nbPending) + '%'); + tarteaucitron.userInterface.css(c + 'DotRed', 'width', ((100 / sum) * nbDenied) + '%'); + + if (nbDenied === 0 && nbPending === 0) { + tarteaucitron.userInterface.css(c + 'AllAllowed', 'backgroundColor', greenDark); + tarteaucitron.userInterface.css(c + 'AllDenied', 'backgroundColor', gray); + } else if (nbAllowed === 0 && nbPending === 0) { + tarteaucitron.userInterface.css(c + 'AllAllowed', 'backgroundColor', gray); + tarteaucitron.userInterface.css(c + 'AllDenied', 'backgroundColor', redDark); + } else { + tarteaucitron.userInterface.css(c + 'AllAllowed', 'backgroundColor', gray); + tarteaucitron.userInterface.css(c + 'AllDenied', 'backgroundColor', gray); + } + + // close the alert if all service have been reviewed + if (nbPending === 0) { + tarteaucitron.userInterface.closeAlert(); + } + + if (tarteaucitron.services[key].cookies.length > 0 && status === false) { + tarteaucitron.cookie.purge(tarteaucitron.services[key].cookies); + } + + if (status === true) { + if (document.getElementById('tacCL' + key) !== null) { + document.getElementById('tacCL' + key).innerHTML = '...'; + } + setTimeout(function () { + tarteaucitron.cookie.checkCount(key); + }, 2500); + } else { + tarteaucitron.cookie.checkCount(key); + } + }, + "openPanel": function () { + "use strict"; + tarteaucitron.userInterface.css('tarteaucitron', 'display', 'block'); + tarteaucitron.userInterface.css('tarteaucitronBack', 'display', 'block'); + tarteaucitron.userInterface.css('tarteaucitronCookiesListContainer', 'display', 'none'); + tarteaucitron.userInterface.jsSizing('main'); + }, + "closePanel": function () { + "use strict"; + + if (document.location.hash === tarteaucitron.hashtag) { + document.location.hash = ''; + } + tarteaucitron.userInterface.css('tarteaucitron', 'display', 'none'); + tarteaucitron.userInterface.css('tarteaucitronCookiesListContainer', 'display', 'none'); + + tarteaucitron.fallback(['tarteaucitronInfoBox'], function (elem) { + elem.style.display = 'none'; + }, true); + + if (tarteaucitron.reloadThePage === true) { + window.location.reload(); + } else { + tarteaucitron.userInterface.css('tarteaucitronBack', 'display', 'none'); + } + }, + "openAlert": function () { + "use strict"; + var c = 'tarteaucitron'; + tarteaucitron.userInterface.css(c + 'Percentage', 'display', 'block'); + tarteaucitron.userInterface.css(c + 'AlertSmall', 'display', 'none'); + tarteaucitron.userInterface.css(c + 'AlertBig', 'display', 'block'); + }, + "closeAlert": function () { + "use strict"; + var c = 'tarteaucitron'; + tarteaucitron.userInterface.css(c + 'Percentage', 'display', 'none'); + tarteaucitron.userInterface.css(c + 'AlertSmall', 'display', 'block'); + tarteaucitron.userInterface.css(c + 'AlertBig', 'display', 'none'); + tarteaucitron.userInterface.jsSizing('box'); + }, + "toggleCookiesList": function () { + "use strict"; + var div = document.getElementById('tarteaucitronCookiesListContainer'); + + if (div === null) { + return; + } + + if (div.style.display !== 'block') { + tarteaucitron.cookie.number(); + div.style.display = 'block'; + tarteaucitron.userInterface.jsSizing('cookie'); + tarteaucitron.userInterface.css('tarteaucitron', 'display', 'none'); + tarteaucitron.userInterface.css('tarteaucitronBack', 'display', 'block'); + tarteaucitron.fallback(['tarteaucitronInfoBox'], function (elem) { + elem.style.display = 'none'; + }, true); + } else { + div.style.display = 'none'; + tarteaucitron.userInterface.css('tarteaucitron', 'display', 'none'); + tarteaucitron.userInterface.css('tarteaucitronBack', 'display', 'none'); + } + }, + "toggle": function (id, closeClass) { + "use strict"; + var div = document.getElementById(id); + + if (div === null) { + return; + } + + if (closeClass !== undefined) { + tarteaucitron.fallback([closeClass], function (elem) { + if (elem.id !== id) { + elem.style.display = 'none'; + } + }, true); + } + + if (div.style.display !== 'block') { + div.style.display = 'block'; + } else { + div.style.display = 'none'; + } + }, + "order": function (id) { + "use strict"; + var main = document.getElementById('tarteaucitronServices_' + id), + allDivs, + store = [], + i; + + if (main === null) { + return; + } + + allDivs = main.childNodes; + + if (typeof Array.prototype.map === 'function') { + Array.prototype.map.call(main.children, Object).sort(function (a, b) { + if (tarteaucitron.services[a.id.replace(/Line/g, '')].name > tarteaucitron.services[b.id.replace(/Line/g, '')].name) { return 1; } + if (tarteaucitron.services[a.id.replace(/Line/g, '')].name < tarteaucitron.services[b.id.replace(/Line/g, '')].name) { return -1; } + return 0; + }).forEach(function (element) { + main.appendChild(element); + }); + } + }, + "jsSizing": function (type) { + "use strict"; + var scrollbarMarginRight = 10, + scrollbarWidthParent, + scrollbarWidthChild, + servicesHeight, + e = window, + a = 'inner', + windowInnerHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight, + mainTop, + mainHeight, + closeButtonHeight, + headerHeight, + cookiesListHeight, + cookiesCloseHeight, + cookiesTitleHeight, + paddingBox, + alertSmallHeight, + cookiesNumberHeight; + + if (type === 'box') { + if (document.getElementById('tarteaucitronAlertSmall') !== null && document.getElementById('tarteaucitronCookiesNumber') !== null) { + + // reset + tarteaucitron.userInterface.css('tarteaucitronCookiesNumber', 'padding', '0px 10px'); + + // calculate + alertSmallHeight = document.getElementById('tarteaucitronAlertSmall').offsetHeight; + cookiesNumberHeight = document.getElementById('tarteaucitronCookiesNumber').offsetHeight; + paddingBox = (alertSmallHeight - cookiesNumberHeight) / 2; + + // apply + tarteaucitron.userInterface.css('tarteaucitronCookiesNumber', 'padding', paddingBox + 'px 10px'); + } + } else if (type === 'main') { + + // get the real window width for media query + if (window.innerWidth === undefined) { + a = 'client'; + e = document.documentElement || document.body; + } + + // height of the services list container + if (document.getElementById('tarteaucitron') !== null && document.getElementById('tarteaucitronClosePanel') !== null && document.getElementById('tarteaucitronMainLineOffset') !== null) { + + // reset + tarteaucitron.userInterface.css('tarteaucitronScrollbarParent', 'height', 'auto'); + + // calculate + mainHeight = document.getElementById('tarteaucitron').offsetHeight; + closeButtonHeight = document.getElementById('tarteaucitronClosePanel').offsetHeight; + headerHeight = document.getElementById('tarteaucitronMainLineOffset').offsetHeight; + + // apply + servicesHeight = (mainHeight - closeButtonHeight - headerHeight + 1); + tarteaucitron.userInterface.css('tarteaucitronScrollbarParent', 'height', servicesHeight + 'px'); + } + + // align the main allow/deny button depending on scrollbar width + if (document.getElementById('tarteaucitronScrollbarParent') !== null && document.getElementById('tarteaucitronScrollbarChild') !== null) { + + // media query + if (e[a + 'Width'] <= 479) { + tarteaucitron.userInterface.css('tarteaucitronScrollbarAdjust', 'marginLeft', '11px'); + } else if (e[a + 'Width'] <= 767) { + scrollbarMarginRight = 12; + } + + scrollbarWidthParent = document.getElementById('tarteaucitronScrollbarParent').offsetWidth; + scrollbarWidthChild = document.getElementById('tarteaucitronScrollbarChild').offsetWidth; + tarteaucitron.userInterface.css('tarteaucitronScrollbarAdjust', 'marginRight', ((scrollbarWidthParent - scrollbarWidthChild) + scrollbarMarginRight) + 'px'); + } + + // center the main panel + if (document.getElementById('tarteaucitron') !== null) { + + // media query + if (e[a + 'Width'] <= 767) { + mainTop = 0; + } else { + mainTop = ((windowInnerHeight - document.getElementById('tarteaucitron').offsetHeight) / 2) - 21; + } + + // correct + if (mainTop < 0) { + mainTop = 0; + } + + if (document.getElementById('tarteaucitronMainLineOffset') !== null) { + if (document.getElementById('tarteaucitron').offsetHeight < (windowInnerHeight / 2)) { + mainTop -= document.getElementById('tarteaucitronMainLineOffset').offsetHeight; + } + } + + // apply + tarteaucitron.userInterface.css('tarteaucitron', 'top', mainTop + 'px'); + } + + + } else if (type === 'cookie') { + + // put cookies list at bottom + if (document.getElementById('tarteaucitronAlertSmall') !== null) { + tarteaucitron.userInterface.css('tarteaucitronCookiesListContainer', 'bottom', (document.getElementById('tarteaucitronAlertSmall').offsetHeight) + 'px'); + } + + // height of cookies list + if (document.getElementById('tarteaucitronCookiesListContainer') !== null) { + + // reset + tarteaucitron.userInterface.css('tarteaucitronCookiesList', 'height', 'auto'); + + // calculate + cookiesListHeight = document.getElementById('tarteaucitronCookiesListContainer').offsetHeight; + cookiesCloseHeight = document.getElementById('tarteaucitronClosePanelCookie').offsetHeight; + cookiesTitleHeight = document.getElementById('tarteaucitronCookiesTitle').offsetHeight; + + // apply + tarteaucitron.userInterface.css('tarteaucitronCookiesList', 'height', (cookiesListHeight - cookiesCloseHeight - cookiesTitleHeight - 2) + 'px'); + } + } + } + }, + "cookie": { + "owner": {}, + "create": function (key, status) { + "use strict"; + var d = new Date(), + time = d.getTime(), + expireTime = time + 31536000000, // 365 days + regex = new RegExp("!" + key + "=(wait|true|false)", "g"), + cookie = tarteaucitron.cookie.read().replace(regex, ""), + value = 'tarteaucitron=' + cookie + '!' + key + '=' + status; + + if (tarteaucitron.cookie.read().indexOf(key + '=' + status) === -1) { + tarteaucitron.pro('!' + key + '=' + status); + } + + d.setTime(expireTime); + document.cookie = value + '; expires=' + d.toGMTString() + '; path=/;'; + }, + "read": function () { + "use strict"; + var nameEQ = "tarteaucitron=", + ca = document.cookie.split(';'), + i, + c; + + for (i = 0; i < ca.length; i += 1) { + c = ca[i]; + while (c.charAt(0) === ' ') { + c = c.substring(1, c.length); + } + if (c.indexOf(nameEQ) === 0) { + return c.substring(nameEQ.length, c.length); + } + } + return ''; + }, + "purge": function (arr) { + "use strict"; + var i; + + for (i = 0; i < arr.length; i += 1) { + document.cookie = arr[i] + '=; expires=Thu, 01 Jan 2000 00:00:00 GMT; path=/;'; + document.cookie = arr[i] + '=; expires=Thu, 01 Jan 2000 00:00:00 GMT; path=/; domain=.' + location.hostname + ';'; + document.cookie = arr[i] + '=; expires=Thu, 01 Jan 2000 00:00:00 GMT; path=/; domain=.' + location.hostname.split('.').slice(-2).join('.') + ';'; + } + }, + "checkCount": function (key) { + "use strict"; + var arr = tarteaucitron.services[key].cookies, + nb = arr.length, + nbCurrent = 0, + html = '', + i, + status = document.cookie.indexOf(key + '=true'); + + if (status >= 0 && nb === 0) { + html += tarteaucitron.lang.useNoCookie; + } else if (status >= 0) { + for (i = 0; i < nb; i += 1) { + if (document.cookie.indexOf(arr[i] + '=') !== -1) { + nbCurrent += 1; + if (tarteaucitron.cookie.owner[arr[i]] === undefined) { + tarteaucitron.cookie.owner[arr[i]] = []; + } + if (tarteaucitron.cookie.crossIndexOf(tarteaucitron.cookie.owner[arr[i]], tarteaucitron.services[key].name) === false) { + tarteaucitron.cookie.owner[arr[i]].push(tarteaucitron.services[key].name); + } + } + } + + if (nbCurrent > 0) { + html += tarteaucitron.lang.useCookieCurrent + ' ' + nbCurrent + ' cookie'; + if (nbCurrent > 1) { + html += 's'; + } + html += '.'; + } else { + html += tarteaucitron.lang.useNoCookie; + } + } else if (nb === 0) { + html = tarteaucitron.lang.noCookie; + } else { + html += tarteaucitron.lang.useCookie + ' ' + nb + ' cookie'; + if (nb > 1) { + html += 's'; + } + html += '.'; + } + + if (document.getElementById('tacCL' + key) !== null) { + document.getElementById('tacCL' + key).innerHTML = html; + } + }, + "crossIndexOf": function (arr, match) { + "use strict"; + var i; + for (i = 0; i < arr.length; i += 1) { + if (arr[i] === match) { + return true; + } + } + return false; + }, + "number": function () { + "use strict"; + var cookies = document.cookie.split(';'), + nb = (document.cookie !== '') ? cookies.length : 0, + html = '', + i, + name, + namea, + nameb, + c, + d, + s = (nb > 1) ? 's' : '', + savedname, + regex = /^https?\:\/\/([^\/?#]+)(?:[\/?#]|$)/i, + regexedDomain = (tarteaucitron.cdn.match(regex) !== null) ? tarteaucitron.cdn.match(regex)[1] : tarteaucitron.cdn, + host = (tarteaucitron.domain !== undefined) ? tarteaucitron.domain : regexedDomain; + + cookies = cookies.sort(function (a, b) { + namea = a.split('=', 1).toString().replace(/ /g, ''); + nameb = b.split('=', 1).toString().replace(/ /g, ''); + c = (tarteaucitron.cookie.owner[namea] !== undefined) ? tarteaucitron.cookie.owner[namea] : '0'; + d = (tarteaucitron.cookie.owner[nameb] !== undefined) ? tarteaucitron.cookie.owner[nameb] : '0'; + if (c + a > d + b) { return 1; } + if (c + a < d + b) { return -1; } + return 0; + }); + + if (document.cookie !== '') { + for (i = 0; i < nb; i += 1) { + name = cookies[i].split('=', 1).toString().replace(/ /g, ''); + if (tarteaucitron.cookie.owner[name] !== undefined && tarteaucitron.cookie.owner[name].join(' // ') !== savedname) { + savedname = tarteaucitron.cookie.owner[name].join(' // '); + html += '
'; + } else if (tarteaucitron.cookie.owner[name] === undefined && host !== savedname) { + savedname = host; + html += '
'; + } + html += '
'; + } + } else { + html += '
'; + } + + html += '
'; + + if (document.getElementById('tarteaucitronCookiesList') !== null) { + document.getElementById('tarteaucitronCookiesList').innerHTML = html; + } + + if (document.getElementById('tarteaucitronCookiesNumber') !== null) { + document.getElementById('tarteaucitronCookiesNumber').innerHTML = nb; + } + + if (document.getElementById('tarteaucitronCookiesNumberBis') !== null) { + document.getElementById('tarteaucitronCookiesNumberBis').innerHTML = nb + ' cookie' + s; + } + + for (i = 0; i < tarteaucitron.job.length; i += 1) { + tarteaucitron.cookie.checkCount(tarteaucitron.job[i]); + } + } + }, + "getLanguage": function () { + "use strict"; + if (!navigator) { return 'en'; } + + var availableLanguages = 'cs,en,fr,es,it,de,pt,pl,ru', + defaultLanguage = 'en', + lang = navigator.language || navigator.browserLanguage || + navigator.systemLanguage || navigator.userLang || null, + userLanguage = lang.substr(0, 2); + + if (tarteaucitronForceLanguage !== '') { + if (availableLanguages.indexOf(tarteaucitronForceLanguage) !== -1) { + return tarteaucitronForceLanguage; + } + } + + if (availableLanguages.indexOf(userLanguage) === -1) { + return defaultLanguage; + } + return userLanguage; + }, + "getLocale": function () { + "use strict"; + if (!navigator) { return 'en_US'; } + + var lang = navigator.language || navigator.browserLanguage || + navigator.systemLanguage || navigator.userLang || null, + userLanguage = lang.substr(0, 2); + + if (userLanguage === 'fr') { + return 'fr_FR'; + } else if (userLanguage === 'en') { + return 'en_US'; + } else if (userLanguage === 'de') { + return 'de_DE'; + } else if (userLanguage === 'es') { + return 'es_ES'; + } else if (userLanguage === 'it') { + return 'it_IT'; + } else if (userLanguage === 'pt') { + return 'pt_PT'; + } else { + return 'en_US'; + } + }, + "addScript": function (url, id, callback, execute, attrName, attrVal) { + "use strict"; + var script, + done = false; + + if (execute === false) { + if (typeof callback === 'function') { + callback(); + } + } else { + script = document.createElement('script'); + script.type = 'text/javascript'; + script.id = (id !== undefined) ? id : ''; + script.async = true; + script.src = url; + + if (attrName !== undefined && attrVal !== undefined) { + script.setAttribute(attrName, attrVal); + } + + if (typeof callback === 'function') { + script.onreadystatechange = script.onload = function () { + var state = script.readyState; + if (!done && (!state || /loaded|complete/.test(state))) { + done = true; + callback(); + } + }; + } + + document.getElementsByTagName('head')[0].appendChild(script); + } + }, + "makeAsync": { + "antiGhost": 0, + "buffer": '', + "init": function (url, id) { + "use strict"; + var savedWrite = document.write, + savedWriteln = document.writeln; + + document.write = function (content) { + tarteaucitron.makeAsync.buffer += content; + }; + document.writeln = function (content) { + tarteaucitron.makeAsync.buffer += content.concat("\n"); + }; + + setTimeout(function () { + document.write = savedWrite; + document.writeln = savedWriteln; + }, 20000); + + tarteaucitron.makeAsync.getAndParse(url, id); + }, + "getAndParse": function (url, id) { + "use strict"; + if (tarteaucitron.makeAsync.antiGhost > 9) { + tarteaucitron.makeAsync.antiGhost = 0; + return; + } + tarteaucitron.makeAsync.antiGhost += 1; + tarteaucitron.addScript(url, '', function () { + if (document.getElementById(id) !== null) { + document.getElementById(id).innerHTML += "
" + tarteaucitron.makeAsync.buffer; + tarteaucitron.makeAsync.buffer = ''; + tarteaucitron.makeAsync.execJS(id); + } + }); + }, + "execJS": function (id) { + /* not strict because third party scripts may have errors */ + var i, + scripts, + childId, + type; + + if (document.getElementById(id) === null) { + return; + } + + scripts = document.getElementById(id).getElementsByTagName('script'); + for (i = 0; i < scripts.length; i += 1) { + type = (scripts[i].getAttribute('type') !== null) ? scripts[i].getAttribute('type') : ''; + if (type === '') { + type = (scripts[i].getAttribute('language') !== null) ? scripts[i].getAttribute('language') : ''; + } + if (scripts[i].getAttribute('src') !== null && scripts[i].getAttribute('src') !== '') { + childId = id + Math.floor(Math.random() * 99999999999); + document.getElementById(id).innerHTML += ''; + tarteaucitron.makeAsync.getAndParse(scripts[i].getAttribute('src'), childId); + } else if (type.indexOf('javascript') !== -1 || type === '') { + eval(scripts[i].innerHTML); + } + } + } + }, + "fallback": function (matchClass, content, noInner) { + "use strict"; + var elems = document.getElementsByTagName('*'), + i, + index = 0; + + for (i in elems) { + if (elems[i] !== undefined) { + for (index = 0; index < matchClass.length; index += 1) { + if ((' ' + elems[i].className + ' ') + .indexOf(' ' + matchClass[index] + ' ') > -1) { + if (typeof content === 'function') { + if (noInner === true) { + content(elems[i]); + } else { + elems[i].innerHTML = content(elems[i]); + } + } else { + elems[i].innerHTML = content; + } + } + } + } + } + }, + "engage": function (id) { + "use strict"; + var html = '', + r = Math.floor(Math.random() * 100000); + + html += '
'; + + return html; + }, + "extend": function (a, b) { + "use strict"; + var prop; + for (prop in b) { + if (b.hasOwnProperty(prop)) { + a[prop] = b[prop]; + } + } + }, + "proTemp": '', + "proTimer": function () { + "use strict"; + setTimeout(tarteaucitron.proPing, 1000); + }, + "pro": function (list) { + "use strict"; + tarteaucitron.proTemp += list; + clearTimeout(tarteaucitron.proTimer); + tarteaucitron.proTimer = setTimeout(tarteaucitron.proPing, 2500); + }, + "proPing": function () { + "use strict"; + if (tarteaucitron.uuid !== '' && tarteaucitron.uuid !== undefined && tarteaucitron.proTemp !== '') { + var div = document.getElementById('tarteaucitronPremium'), + timestamp = new Date().getTime(), + url = '//opt-out.ferank.eu/premium.php?'; + + if (div === null) { + return; + } + + url += 'domain=' + tarteaucitron.domain + '&'; + url += 'uuid=' + tarteaucitron.uuid + '&'; + url += 'c=' + encodeURIComponent(tarteaucitron.proTemp) + '&'; + url += '_' + timestamp; + + div.innerHTML = ''; + + tarteaucitron.proTemp = ''; + } + + tarteaucitron.cookie.number(); + } +}; diff --git a/docs/pages/assets/js/tarteaucitron/tarteaucitron.services.js b/docs/pages/assets/js/tarteaucitron/tarteaucitron.services.js new file mode 100755 index 0000000..81ea5c7 --- /dev/null +++ b/docs/pages/assets/js/tarteaucitron/tarteaucitron.services.js @@ -0,0 +1,1850 @@ +/*global tarteaucitron, ga, Shareaholic, stLight, clicky, top, google, Typekit, FB, ferankReady, IN, stButtons, twttr, PCWidget*/ +/*jslint regexp: true, nomen: true*/ + +// generic iframe +tarteaucitron.services.iframe = { + "key": "iframe", + "type": "other", + "name": "Web content", + "uri": "", + "needConsent": true, + "cookies": [], + "js": function () { + "use strict"; + tarteaucitron.fallback(['tac_iframe'], function (x) { + var width = x.getAttribute("width"), + height = x.getAttribute("height"), + url = x.getAttribute("data-url"); + + return ''; + }); + }, + "fallback": function () { + "use strict"; + var id = 'iframe'; + tarteaucitron.fallback(['tac_iframe'], function (elem) { + elem.style.width = elem.getAttribute('width') + 'px'; + elem.style.height = elem.getAttribute('height') + 'px'; + return tarteaucitron.engage(id); + }); + } +}; + +// addthis +tarteaucitron.services.addthis = { + "key": "addthis", + "type": "social", + "name": "AddThis", + "uri": "https://www.addthis.com/privacy/privacy-policy#publisher-visitors", + "needConsent": true, + "cookies": ['__atuvc', '__atuvs'], + "js": function () { + "use strict"; + if (tarteaucitron.user.addthisPubId === undefined) { + return; + } + if (tarteaucitron.isAjax === true) { + window.addthis = null; + window._adr = null; + window._atc = null; + window._atd = null; + window._ate = null; + window._atr = null; + window._atw = null; + } + tarteaucitron.fallback(['addthis_sharing_toolbox'], ''); + tarteaucitron.addScript('//s7.addthis.com/js/300/addthis_widget.js#pubid=' + tarteaucitron.user.addthisPubId); + }, + "fallback": function () { + "use strict"; + var id = 'addthis'; + tarteaucitron.fallback(['addthis_sharing_toolbox'], tarteaucitron.engage(id)); + } +}; + +// addtoanyfeed +tarteaucitron.services.addtoanyfeed = { + "key": "addtoanyfeed", + "type": "social", + "name": "AddToAny (feed)", + "uri": "https://www.addtoany.com/privacy", + "needConsent": true, + "cookies": [], + "js": function () { + "use strict"; + if (tarteaucitron.user.addtoanyfeedUri === undefined) { + return; + } + tarteaucitron.user.addtoanyfeedSubscribeLink = 'https://www.addtoany.com/subscribe?linkurl=' + tarteaucitron.user.addtoanyfeedUri; + window.a2a_config = window.a2a_config || {}; + window.a2a_config.linkurl = tarteaucitron.user.addtoanyfeedUri; + tarteaucitron.addScript('//static.addtoany.com/menu/feed.js'); + }, + "fallback": function () { + "use strict"; + tarteaucitron.user.addtoanyfeedSubscribeLink = 'https://www.addtoany.com/subscribe?linkurl=' + tarteaucitron.user.addtoanyfeedUri; + } +}; + +// addtoanyshare +tarteaucitron.services.addtoanyshare = { + "key": "addtoanyshare", + "type": "social", + "name": "AddToAny (share)", + "uri": "https://www.addtoany.com/privacy", + "needConsent": true, + "cookies": [], + "js": function () { + "use strict"; + tarteaucitron.fallback(['tac_addtoanyshare'], ''); + tarteaucitron.addScript('//static.addtoany.com/menu/page.js'); + }, + "fallback": function () { + "use strict"; + var id = 'addtoanyshare'; + tarteaucitron.fallback(['tac_addtoanyshare'], tarteaucitron.engage(id)); + } +}; + +// alexa +tarteaucitron.services.alexa = { + "key": "alexa", + "type": "analytic", + "name": "Alexa", + "uri": "https://www.alexa.com/help/privacy", + "needConsent": true, + "cookies": ['__asc', '__auc'], + "js": function () { + "use strict"; + if (tarteaucitron.user.alexaAccountID === undefined) { + return; + } + window._atrk_opts = { + atrk_acct: tarteaucitron.user.alexaAccountID, + domain: window.location.hostname.match(/[^\.]*\.[^.]*$/)[0], + dynamic: true + }; + tarteaucitron.addScript('https://d31qbv1cthcecs.cloudfront.net/atrk.js'); + } +}; + +// amazon +tarteaucitron.services.amazon = { + "key": "amazon", + "type": "ads", + "name": "Amazon", + "uri": "https://www.amazon.fr/gp/help/customer/display.html?ie=UTF8&*Version*=1&*entries*=0&nodeId=201149360", + "needConsent": true, + "cookies": [], + "js": function () { + "use strict"; + tarteaucitron.fallback(['amazon_product'], function (x) { + var amazonId = x.getAttribute("amazonid"), + productId = x.getAttribute("productid"), + url = '//ws-eu.amazon-adsystem.com/widgets/q?ServiceVersion=20070822&OneJS=1&Operation=GetAdHtml&MarketPlace=' + tarteaucitron.getLanguage().toUpperCase() + '&source=ss&ref=ss_til&ad_type=product_link&tracking_id=' + amazonId + '&marketplace=amazon®ion=' + tarteaucitron.getLanguage().toUpperCase() + '&placement=' + productId + '&asins=' + productId + '&show_border=true&link_opens_in_new_window=true', + iframe = ''; + + return iframe; + }); + }, + "fallback": function () { + "use strict"; + var id = 'amazon'; + tarteaucitron.fallback(['amazon_product'], tarteaucitron.engage(id)); + } +}; + +// calameo +tarteaucitron.services.calameo = { + "key": "calameo", + "type": "video", + "name": "Calameo", + "uri": "https://fr.calameo.com/privacy", + "needConsent": true, + "cookies": [], + "js": function () { + "use strict"; + tarteaucitron.fallback(['calameo-canvas'], function (x) { + var id = x.getAttribute("data-id"), + width = x.getAttribute("width"), + height = x.getAttribute("height"), + url = '//v.calameo.com/?bkcode=' + id; + + return ''; + }); + }, + "fallback": function () { + "use strict"; + var id = 'calameo'; + tarteaucitron.fallback(['calameo-canvas'], function (elem) { + elem.style.width = elem.getAttribute('width') + 'px'; + elem.style.height = elem.getAttribute('height') + 'px'; + return tarteaucitron.engage(id); + }); + } +}; + +// clicky +tarteaucitron.services.clicky = { + "key": "clicky", + "type": "analytic", + "name": "Clicky", + "uri": "https://clicky.com/terms", + "needConsent": true, + "cookies": ['_jsuid', '_eventqueue', '_referrer_og', '_utm_og', '_first_pageview', 'clicky_olark', 'no_trackyy_' + tarteaucitron.user.clickyId, 'unpoco_' + tarteaucitron.user.clickyId, 'heatmaps_g2g_' + tarteaucitron.user.clickyId], + "js": function () { + "use strict"; + if (tarteaucitron.user.clickyId === undefined) { + return; + } + tarteaucitron.addScript('//static.getclicky.com/js', '', function () { + if (typeof clicky.init === 'function') { + clicky.init(tarteaucitron.user.clickyId); + } + if (typeof tarteaucitron.user.clickyMore === 'function') { + tarteaucitron.user.clickyMore(); + } + }); + } +}; + +// clicmanager +tarteaucitron.services.clicmanager = { + "key": "clicmanager", + "type": "ads", + "name": "Clicmanager", + "uri": "http://www.clicmanager.fr/infos_legales.php", + "needConsent": true, + "cookies": [], + "js": function () { + "use strict"; + var uniqIds = [], + i, + uri; + + tarteaucitron.fallback(['clicmanager-canvas'], function (x) { + var uniqId = '_' + Math.random().toString(36).substr(2, 9); + uniqIds.push(uniqId); + return '
'; + }); + + for (i = 0; i < uniqIds.length; i += 1) { + uri = '//ads.clicmanager.fr/exe.php?'; + uri += 'c=' + document.getElementById(uniqIds[i]).getAttribute('c') + '&'; + uri += 's=' + document.getElementById(uniqIds[i]).getAttribute('s') + '&'; + uri += 't=' + document.getElementById(uniqIds[i]).getAttribute('t'); + + tarteaucitron.makeAsync.init(uri, uniqIds[i]); + } + }, + "fallback": function () { + "use strict"; + var id = 'clicmanager'; + tarteaucitron.fallback(['clicmanager-canvas'], tarteaucitron.engage(id)); + } +}; + +// crazyegg +tarteaucitron.services.crazyegg = { + "key": "crazyegg", + "type": "analytic", + "name": "Crazy Egg", + "uri": "https://www.crazyegg.com/privacy", + "needConsent": true, + "cookies": [], + "js": function () { + "use strict"; + + if (tarteaucitron.user.crazyeggId === undefined) { + return; + } + + tarteaucitron.addScript('//script.crazyegg.com/pages/scripts/' + tarteaucitron.user.crazyeggId.substr(0, 4) + '/' + tarteaucitron.user.crazyeggId.substr(4, 4) + '.js'); + } +}; + +// criteo +tarteaucitron.services.criteo = { + "key": "criteo", + "type": "ads", + "name": "Criteo", + "uri": "http://www.criteo.com/privacy/", + "needConsent": true, + "cookies": [], + "js": function () { + "use strict"; + document.MAX_ct0 = ''; + var uniqIds = [], + i, + uri; + + tarteaucitron.fallback(['criteo-canvas'], function (x) { + var uniqId = '_' + Math.random().toString(36).substr(2, 9); + uniqIds.push(uniqId); + return '
'; + }); + + for (i = 0; i < uniqIds.length; i += 1) { + uri = '//cas.criteo.com/delivery/ajs.php?'; + uri += 'zoneid=' + document.getElementById(uniqIds[i]).getAttribute('zoneid'); + uri += '&nodis=1&cb=' + Math.floor(Math.random() * 99999999999); + uri += '&loc=' + encodeURI(window.location); + uri += (document.MAX_used !== ',') ? '&exclude=' + document.MAX_used : ''; + uri += (document.charset !== undefined ? '&charset=' + document.charset : ''); + uri += (document.characterSet !== undefined ? '&charset=' + document.characterSet : ''); + uri += (document.referrer !== undefined) ? '&referer=' + encodeURI(document.referrer) : ''; + uri += (document.context !== undefined) ? '&context=' + encodeURI(document.context) : ''; + uri += ((document.MAX_ct0 !== undefined) && (document.MAX_ct0.substring(0, 4) === 'http')) ? '&ct0=' + encodeURI(document.MAX_ct0) : ''; + uri += (document.mmm_fo !== undefined) ? '&mmm_fo=1' : ''; + + tarteaucitron.makeAsync.init(uri, uniqIds[i]); + } + }, + "fallback": function () { + "use strict"; + var id = 'criteo'; + tarteaucitron.fallback(['criteo-canvas'], tarteaucitron.engage(id)); + } +}; + +// dailymotion +tarteaucitron.services.dailymotion = { + "key": "dailymotion", + "type": "video", + "name": "Dailymotion", + "uri": "https://www.dailymotion.com/legal/privacy", + "needConsent": true, + "cookies": ['ts', 'dmvk', 'hist', 'v1st', 's_vi'], + "js": function () { + "use strict"; + tarteaucitron.fallback(['dailymotion_player'], function (x) { + var video_id = x.getAttribute("videoID"), + video_width = x.getAttribute("width"), + frame_width = 'width=', + video_height = x.getAttribute("height"), + frame_height = 'height=', + video_frame, + params = 'info=' + x.getAttribute("showinfo") + '&autoPlay=' + x.getAttribute("autoplay"); + + if (video_id === undefined) { + return ""; + } + if (video_width !== undefined) { + frame_width += '"' + video_width + '" '; + } else { + frame_width += '"" '; + } + if (video_height !== undefined) { + frame_height += '"' + video_height + '" '; + } else { + frame_height += '"" '; + } + video_frame = ''; + return video_frame; + }); + }, + "fallback": function () { + "use strict"; + var id = 'dailymotion'; + tarteaucitron.fallback(['dailymotion_player'], function (elem) { + elem.style.width = elem.getAttribute('width') + 'px'; + elem.style.height = elem.getAttribute('height') + 'px'; + return tarteaucitron.engage(id); + }); + } +}; + +// dating affiliation +tarteaucitron.services.datingaffiliation = { + "key": "datingaffiliation", + "type": "ads", + "name": "Dating Affiliation", + "uri": "http://www.dating-affiliation.com/conditions-generales.php", + "needConsent": true, + "cookies": [], + "js": function () { + "use strict"; + tarteaucitron.fallback(['datingaffiliation-canvas'], function (x) { + var comfrom = x.getAttribute("data-comfrom"), + r = x.getAttribute("data-r"), + p = x.getAttribute("data-p"), + cf0 = x.getAttribute("data-cf0"), + langue = x.getAttribute("data-langue"), + forward_affiliate = x.getAttribute("data-forwardAffiliate"), + cf2 = x.getAttribute("data-cf2"), + cfsa2 = x.getAttribute("data-cfsa2"), + width = x.getAttribute("width"), + height = x.getAttribute("height"), + url = 'http://www.tools-affil2.com/rotaban/ban.php?' + comfrom; + + return ''; + }); + }, + "fallback": function () { + "use strict"; + var id = 'datingaffiliation'; + tarteaucitron.fallback(['datingaffiliation-canvas'], function (elem) { + elem.style.width = elem.getAttribute('width') + 'px'; + elem.style.height = elem.getAttribute('height') + 'px'; + return tarteaucitron.engage(id); + }); + } +}; + +// dating affiliation popup +tarteaucitron.services.datingaffiliationpopup = { + "key": "datingaffiliationpopup", + "type": "ads", + "name": "Dating Affiliation (Pop Up)", + "uri": "http://www.dating-affiliation.com/conditions-generales.php", + "needConsent": true, + "cookies": ['__utma', '__utmb', '__utmc', '__utmt_Tools', '__utmv', '__utmz', '_ga', '_gat', '_gat_UA-65072040-17', '__da-pu-xflirt-ID-pc-o169'], + "js": function () { + "use strict"; + var uniqIds = [], + i, + uri; + + tarteaucitron.fallback(['datingaffiliationpopup-canvas'], function (x) { + var uniqId = '_' + Math.random().toString(36).substr(2, 9); + uniqIds.push(uniqId); + return '
'; + }); + + for (i = 0; i < uniqIds.length; i += 1) { + uri = 'http://www.promotools.biz/da/popunder/script.php?'; + uri += 'comfrom=' + document.getElementById(uniqIds[i]).getAttribute('comfrom') + '&'; + uri += 'promo=' + document.getElementById(uniqIds[i]).getAttribute('promo') + '&'; + uri += 'product_id=' + document.getElementById(uniqIds[i]).getAttribute('productid') + '&'; + uri += 'submitconfig=' + document.getElementById(uniqIds[i]).getAttribute('submitconfig') + '&'; + uri += 'ur=' + document.getElementById(uniqIds[i]).getAttribute('ur') + '&'; + uri += 'brand=' + document.getElementById(uniqIds[i]).getAttribute('brand') + '&'; + uri += 'lang=' + document.getElementById(uniqIds[i]).getAttribute('lang') + '&'; + uri += 'cf0=' + document.getElementById(uniqIds[i]).getAttribute('cf0') + '&'; + uri += 'cf2=' + document.getElementById(uniqIds[i]).getAttribute('cf2') + '&'; + uri += 'subid1=' + document.getElementById(uniqIds[i]).getAttribute('subid1') + '&'; + uri += 'cfsa2=' + document.getElementById(uniqIds[i]).getAttribute('cfsa2') + '&'; + uri += 'subid2=' + document.getElementById(uniqIds[i]).getAttribute('subid2') + '&'; + uri += 'nicheId=' + document.getElementById(uniqIds[i]).getAttribute('nicheid') + '&'; + uri += 'degreId=' + document.getElementById(uniqIds[i]).getAttribute('degreid') + '&'; + uri += 'bt=' + document.getElementById(uniqIds[i]).getAttribute('bt') + '&'; + uri += 'vis=' + document.getElementById(uniqIds[i]).getAttribute('vis') + '&'; + uri += 'hid=' + document.getElementById(uniqIds[i]).getAttribute('hid') + '&'; + uri += 'snd=' + document.getElementById(uniqIds[i]).getAttribute('snd') + '&'; + uri += 'aabd=' + document.getElementById(uniqIds[i]).getAttribute('aabd') + '&'; + uri += 'aabs=' + document.getElementById(uniqIds[i]).getAttribute('aabs'); + + tarteaucitron.makeAsync.init(uri, uniqIds[i]); + } + }, + "fallback": function () { + "use strict"; + var id = 'datingaffiliationpopup'; + tarteaucitron.fallback(['datingaffiliationpopup-canvas'], tarteaucitron.engage(id)); + } +}; + +// disqus +tarteaucitron.services.disqus = { + "key": "disqus", + "type": "comment", + "name": "Disqus", + "uri": "https://help.disqus.com/customer/portal/articles/466259-privacy-policy", + "needConsent": true, + "cookies": [], + "js": function () { + "use strict"; + if (tarteaucitron.user.disqusShortname === undefined) { + return; + } + tarteaucitron.addScript('//' + tarteaucitron.user.disqusShortname + '.disqus.com/embed.js'); + tarteaucitron.addScript('//' + tarteaucitron.user.disqusShortname + '.disqus.com/count.js'); + }, + "fallback": function () { + "use strict"; + var id = 'disqus'; + + if (document.getElementById('disqus_thread')) { + document.getElementById('disqus_thread').innerHTML = tarteaucitron.engage(id); + } + } +}; + +// ekomi +tarteaucitron.services.ekomi = { + "key": "ekomi", + "type": "social", + "name": "eKomi", + "uri": "http://www.ekomi-us.com/us/privacy/", + "needConsent": true, + "cookies": [], + "js": function () { + "use strict"; + if (tarteaucitron.user.ekomiCertId === undefined) { + return; + } + window.eKomiIntegrationConfig = [ + {certId: tarteaucitron.user.ekomiCertId} + ]; + tarteaucitron.addScript('//connect.ekomi.de/integration_1410173009/' + tarteaucitron.user.ekomiCertId + '.js'); + } +}; + +// etracker +tarteaucitron.services.etracker = { + "key": "etracker", + "type": "analytic", + "name": "eTracker", + "uri": "https://www.etracker.com/en/data-protection.html", + "needConsent": true, + "cookies": [], + "js": function () { + "use strict"; + if (tarteaucitron.user.etracker === undefined) { + return; + } + + tarteaucitron.addScript('//static.etracker.com/code/e.js', '_etLoader', function () {}, true, "data-secure-code", tarteaucitron.user.etracker); + } +}; + +// facebook +tarteaucitron.services.facebook = { + "key": "facebook", + "type": "social", + "name": "Facebook", + "uri": "https://www.facebook.com/policies/cookies/", + "needConsent": true, + "cookies": [], + "js": function () { + "use strict"; + tarteaucitron.fallback(['fb-post', 'fb-follow', 'fb-activity', 'fb-send', 'fb-share-button', 'fb-like'], ''); + tarteaucitron.addScript('//connect.facebook.net/' + tarteaucitron.getLocale() + '/sdk.js#xfbml=1&version=v2.0', 'facebook-jssdk'); + if (tarteaucitron.isAjax === true) { + if (typeof FB !== "undefined") { + FB.XFBML.parse(); + } + } + }, + "fallback": function () { + "use strict"; + var id = 'facebook'; + tarteaucitron.fallback(['fb-post', 'fb-follow', 'fb-activity', 'fb-send', 'fb-share-button', 'fb-like'], tarteaucitron.engage(id)); + } +}; + +// facebooklikebox +tarteaucitron.services.facebooklikebox = { + "key": "facebooklikebox", + "type": "social", + "name": "Facebook (like box)", + "uri": "https://www.facebook.com/policies/cookies/", + "needConsent": true, + "cookies": [], + "js": function () { + "use strict"; + tarteaucitron.fallback(['fb-like-box', 'fb-page'], ''); + tarteaucitron.addScript('//connect.facebook.net/' + tarteaucitron.getLocale() + '/sdk.js#xfbml=1&version=v2.3', 'facebook-jssdk'); + if (tarteaucitron.isAjax === true) { + if (typeof FB !== "undefined") { + FB.XFBML.parse(); + } + } + }, + "fallback": function () { + "use strict"; + var id = 'facebooklikebox'; + tarteaucitron.fallback(['fb-like-box', 'fb-page'], tarteaucitron.engage(id)); + } +}; + +// facebookcomment +tarteaucitron.services.facebookcomment = { + "key": "facebookcomment", + "type": "comment", + "name": "Facebook (commentaire)", + "uri": "https://www.facebook.com/policies/cookies/", + "needConsent": true, + "cookies": [], + "js": function () { + "use strict"; + tarteaucitron.fallback(['fb-comments'], ''); + tarteaucitron.addScript('//connect.facebook.net/' + tarteaucitron.getLocale() + '/sdk.js#xfbml=1&version=v2.0', 'facebook-jssdk'); + if (tarteaucitron.isAjax === true) { + if (typeof FB !== "undefined") { + FB.XFBML.parse(); + } + } + }, + "fallback": function () { + "use strict"; + var id = 'facebookcomment'; + tarteaucitron.fallback(['fb-comments'], tarteaucitron.engage(id)); + } +}; + +// ferank +tarteaucitron.services.ferank = { + "key": "ferank", + "type": "analytic", + "name": "FERank", + "uri": "https://www.ferank.fr/respect-vie-privee/#mesureaudience", + "needConsent": false, + "cookies": [], + "js": function () { + "use strict"; + tarteaucitron.addScript('//static.ferank.fr/pixel.js', '', function () { + if (typeof tarteaucitron.user.ferankMore === 'function') { + tarteaucitron.user.ferankMore(); + } + }); + } +}; + +// ferank pub +tarteaucitron.services.ferankpub = { + "key": "ferankpub", + "type": "ads", + "name": "FERank (pub)", + "uri": "https://www.ferank.fr/respect-vie-privee/#regiepublicitaire", + "needConsent": false, + "cookies": [], + "js": function () { + "use strict"; + tarteaucitron.addScript('//static.ferank.fr/publicite.async.js'); + if (tarteaucitron.isAjax === true) { + if (typeof ferankReady === 'function') { + ferankReady(); + } + } + }, + "fallback": function () { + "use strict"; + var id = 'ferankpub'; + tarteaucitron.fallback(['ferank-publicite'], tarteaucitron.engage(id)); + } +}; + +// get+ +tarteaucitron.services.getplus = { + "key": "getplus", + "type": "analytic", + "name": "Get+", + "uri": "http://www.getplus.fr/Conditions-generales-de-vente_a226.html", + "needConsent": true, + "cookies": ['_first_pageview', '_jsuid', 'no_trackyy_' + tarteaucitron.user.getplusId, '_eventqueue'], + "js": function () { + "use strict"; + if (tarteaucitron.user.getplusId === undefined) { + return; + } + + window.webleads_site_ids = window.webleads_site_ids || []; + window.webleads_site_ids.push(tarteaucitron.user.getplusId); + tarteaucitron.addScript('//stats.webleads-tracker.com/js'); + } +}; + +// google+ +tarteaucitron.services.gplus = { + "key": "gplus", + "type": "social", + "name": "Google+", + "uri": "https://policies.google.com/privacy", + "needConsent": true, + "cookies": [], + "js": function () { + "use strict"; + tarteaucitron.addScript('https://apis.google.com/js/platform.js'); + }, + "fallback": function () { + "use strict"; + var id = 'gplus'; + tarteaucitron.fallback(['g-plus', 'g-plusone'], tarteaucitron.engage(id)); + } +}; + +// google+ badge +tarteaucitron.services.gplusbadge = { + "key": "gplusbadge", + "type": "social", + "name": "Google+ (badge)", + "uri": "https://policies.google.com/privacy", + "needConsent": true, + "cookies": [], + "js": function () { + "use strict"; + tarteaucitron.addScript('https://apis.google.com/js/platform.js'); + }, + "fallback": function () { + "use strict"; + var id = 'gplusbadge'; + tarteaucitron.fallback(['g-page', 'g-person'], tarteaucitron.engage(id)); + } +}; + +// google adsense +tarteaucitron.services.adsense = { + "key": "adsense", + "type": "ads", + "name": "Google Adsense", + "uri": "http://www.google.com/ads/preferences/", + "needConsent": true, + "cookies": [], + "js": function () { + "use strict"; + tarteaucitron.addScript('https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js'); + }, + "fallback": function () { + "use strict"; + var id = 'adsense'; + tarteaucitron.fallback(['adsbygoogle'], tarteaucitron.engage(id)); + } +}; + +// google partners badge +tarteaucitron.services.googlepartners = { + "key": "googlepartners", + "type": "ads", + "name": "Google Partners Badge", + "uri": "http://www.google.com/ads/preferences/", + "needConsent": true, + "cookies": [], + "js": function () { + "use strict"; + tarteaucitron.addScript('https://apis.google.com/js/platform.js'); + }, + "fallback": function () { + "use strict"; + var id = 'googlepartners'; + tarteaucitron.fallback(['g-partnersbadge'], tarteaucitron.engage(id)); + } +}; + +// google adsense search (form) +tarteaucitron.services.adsensesearchform = { + "key": "adsensesearchform", + "type": "ads", + "name": "Google Adsense Search (form)", + "uri": "http://www.google.com/ads/preferences/", + "needConsent": true, + "cookies": [], + "js": function () { + "use strict"; + tarteaucitron.addScript('//www.google.com/coop/cse/brand?form=cse-search-box&lang=' + tarteaucitron.getLanguage()); + } +}; + +// google adsense search (result) +tarteaucitron.services.adsensesearchresult = { + "key": "adsensesearchresult", + "type": "ads", + "name": "Google Adsense Search (result)", + "uri": "http://www.google.com/ads/preferences/", + "needConsent": true, + "cookies": [], + "js": function () { + "use strict"; + if (tarteaucitron.user.adsensesearchresultCx === undefined) { + return; + } + tarteaucitron.addScript('//www.google.com/cse/cse.js?cx=' + tarteaucitron.user.adsensesearchresultCx); + }, + "fallback": function () { + "use strict"; + var id = 'adsensesearchresult'; + + if (document.getElementById('gcse_searchresults')) { + document.getElementById('gcse_searchresults').innerHTML = tarteaucitron.engage(id); + } + } +}; + +// googleadwordsconversion +tarteaucitron.services.googleadwordsconversion = { + "key": "googleadwordsconversion", + "type": "ads", + "name": "Google Adwords (conversion)", + "uri": "https://www.google.com/settings/ads", + "needConsent": true, + "cookies": [], + "js": function () { + "use strict"; + if (tarteaucitron.user.adwordsconversionId === undefined) { + return; + } + + tarteaucitron.addScript('//www.googleadservices.com/pagead/conversion_async.js', '', function () { + window.google_trackConversion({ + google_conversion_id: tarteaucitron.user.adwordsconversionId, + google_conversion_label: tarteaucitron.user.adwordsconversionLabel, + google_conversion_language: tarteaucitron.user.adwordsconversionLanguage, + google_conversion_format: tarteaucitron.user.adwordsconversionFormat, + google_conversion_color: tarteaucitron.user.adwordsconversionColor, + google_conversion_value: tarteaucitron.user.adwordsconversionValue, + google_conversion_currency: tarteaucitron.user.adwordsconversionCurrency, + google_custom_params: { + parameter1: tarteaucitron.user.adwordsconversionCustom1, + parameter2: tarteaucitron.user.adwordsconversionCustom2 + } + }); + }); + } +}; + +// googleadwordsremarketing +tarteaucitron.services.googleadwordsremarketing = { + "key": "googleadwordsremarketing", + "type": "ads", + "name": "Google Adwords (remarketing)", + "uri": "https://www.google.com/settings/ads", + "needConsent": true, + "cookies": [], + "js": function () { + "use strict"; + if (tarteaucitron.user.adwordsremarketingId === undefined) { + return; + } + + tarteaucitron.addScript('//www.googleadservices.com/pagead/conversion_async.js', '', function () { + window.google_trackConversion({ + google_conversion_id: tarteaucitron.user.adwordsremarketingId, + google_remarketing_only: true + }); + }); + } +}; + +// google analytics (old) +tarteaucitron.services.gajs = { + "key": "gajs", + "type": "analytic", + "name": "Google Analytics (ga.js)", + "uri": "https://support.google.com/analytics/answer/6004245", + "needConsent": true, + "cookies": ['_ga', '_gat', '__utma', '__utmb', '__utmc', '__utmt', '__utmz'], + "js": function () { + "use strict"; + window._gaq = window._gaq || []; + window._gaq.push(['_setAccount', tarteaucitron.user.gajsUa]); + window._gaq.push(['_trackPageview']); + + tarteaucitron.addScript('//www.google-analytics.com/ga.js', '', function () { + if (typeof tarteaucitron.user.gajsMore === 'function') { + tarteaucitron.user.gajsMore(); + } + }); + } +}; + +// google analytics +tarteaucitron.services.analytics = { + "key": "analytics", + "type": "analytic", + "name": "Google Analytics (universal)", + "uri": "https://support.google.com/analytics/answer/6004245", + "needConsent": true, + "cookies": ['_ga', '_gat', '_gid', '__utma', '__utmb', '__utmc', '__utmt', '__utmz'], + "js": function () { + "use strict"; + window.GoogleAnalyticsObject = 'ga'; + window.ga = window.ga || function () { + window.ga.q = window.ga.q || []; + window.ga.q.push(arguments); + }; + window.ga.l = new Date(); + + tarteaucitron.addScript('//www.google-analytics.com/analytics.js', '', function () { + ga('create', tarteaucitron.user.analyticsUa, {'cookieExpires': 34128000}); + ga('send', 'pageview'); + if (typeof tarteaucitron.user.analyticsMore === 'function') { + tarteaucitron.user.analyticsMore(); + } + }); + } +}; + +// google analytics +tarteaucitron.services.gtag = { + "key": "gtag", + "type": "analytic", + "name": "Google Analytics (gtag.js)", + "uri": "https://support.google.com/analytics/answer/6004245", + "needConsent": true, + "cookies": ['_ga', '_gat', '_gid', '__utma', '__utmb', '__utmc', '__utmt', '__utmz'], + "js": function () { + "use strict"; + window.dataLayer = window.dataLayer || []; + + tarteaucitron.addScript('//www.googletagmanager.com/gtag/js?id=' + tarteaucitron.user.gtagUa, '', function () { + function gtag(){dataLayer.push(arguments);} + gtag('js', new Date()); + gtag('config', tarteaucitron.user.gtagUa); + + if (typeof tarteaucitron.user.gtagMore === 'function') { + tarteaucitron.user.gtagMore(); + } + }); + } +}; + +// google maps +tarteaucitron.services.googlemaps = { + "key": "googlemaps", + "type": "api", + "name": "Google Maps", + "uri": "http://www.google.com/ads/preferences/", + "needConsent": true, + "cookies": [], + "js": function () { + "use strict"; + var mapOptions, + map, + uniqIds = [], + i; + + if (tarteaucitron.user.mapscallback === undefined) { + tarteaucitron.user.mapscallback = 'tac_googlemaps_callback'; + } + + tarteaucitron.addScript('//maps.googleapis.com/maps/api/js?v=3.exp&key=' + tarteaucitron.user.googlemapsKey + '&callback='+tarteaucitron.user.mapscallback); + + window.tac_googlemaps_callback = function () { + tarteaucitron.fallback(['googlemaps-canvas'], function (x) { + var uniqId = '_' + Math.random().toString(36).substr(2, 9); + uniqIds.push(uniqId); + return '
'; + }); + + for (i = 0; i < uniqIds.length; i += 1) { + mapOptions = { + zoom: parseInt(document.getElementById(uniqIds[i]).getAttribute('zoom'), 10), + center: new google.maps.LatLng(parseFloat(document.getElementById(uniqIds[i]).getAttribute('latitude'), 10), parseFloat(document.getElementById(uniqIds[i]).getAttribute('longitude'), 10)) + }; + map = new google.maps.Map(document.getElementById(uniqIds[i]), mapOptions); + } + }; + }, + "fallback": function () { + "use strict"; + var id = 'googlemaps'; + tarteaucitron.fallback(['googlemaps-canvas'], tarteaucitron.engage(id)); + } +}; + +// google tag manager +tarteaucitron.services.googletagmanager = { + "key": "googletagmanager", + "type": "api", + "name": "Google Tag Manager", + "uri": "http://www.google.com/ads/preferences/", + "needConsent": true, + "cookies": ['_ga', '_gat', '__utma', '__utmb', '__utmc', '__utmt', '__utmz', '__gads', '_drt_', 'FLC', 'exchange_uid', 'id', 'fc', 'rrs', 'rds', 'rv', 'uid', 'UIDR', 'UID', 'clid', 'ipinfo', 'acs'], + "js": function () { + "use strict"; + if (tarteaucitron.user.googletagmanagerId === undefined) { + return; + } + window.dataLayer = window.dataLayer || []; + window.dataLayer.push({ + 'gtm.start': new Date().getTime(), + event: 'gtm.js' + }); + tarteaucitron.addScript('//www.googletagmanager.com/gtm.js?id=' + tarteaucitron.user.googletagmanagerId); + } +}; + +// jsapi +tarteaucitron.services.jsapi = { + "key": "jsapi", + "type": "api", + "name": "Google jsapi", + "uri": "http://www.google.com/policies/privacy/", + "needConsent": true, + "cookies": [], + "js": function () { + "use strict"; + tarteaucitron.addScript('//www.google.com/jsapi'); + } +}; + +// linkedin +tarteaucitron.services.linkedin = { + "key": "linkedin", + "type": "social", + "name": "Linkedin", + "uri": "https://www.linkedin.com/legal/cookie_policy", + "needConsent": true, + "cookies": [], + "js": function () { + "use strict"; + tarteaucitron.fallback(['tacLinkedin'], ''); + tarteaucitron.addScript('//platform.linkedin.com/in.js'); + if (tarteaucitron.isAjax === true) { + if (typeof IN !== "undefined") { + IN.parse(); + } + } + }, + "fallback": function () { + "use strict"; + var id = 'linkedin'; + tarteaucitron.fallback(['tacLinkedin'], tarteaucitron.engage(id)); + } +}; + +// mautic +tarteaucitron.services.mautic = { + "key": "mautic", + "type": "analytic", + "name": "Mautic", + "uri": "https://www.mautic.org/privacy-policy/", + "needConsent": true, + "cookies": ['mtc_id', 'mtc_sid'], + "js": function () { + "use strict"; + if (tarteaucitron.user.mauticurl === undefined) { + return; + } + + window['MauticTrackingObject'] = 'mt'; + window['mt'] = window['mt'] || function() { + (window['mt'].q = window['mt'].q || []).push(arguments); + }; + + tarteaucitron.addScript(tarteaucitron.user.mauticurl, '', function() { + mt('send', 'pageview'); + }); + } +}; + +// microsoftcampaignanalytics +tarteaucitron.services.microsoftcampaignanalytics = { + "key": "microsoftcampaignanalytics", + "type": "analytic", + "name": "Microsoft Campaign Analytics", + "uri": "https://privacy.microsoft.com/privacystatement/", + "needConsent": true, + "cookies": [], + "js": function () { + "use strict"; + if (tarteaucitron.user.microsoftcampaignanalyticsUUID === undefined) { + return; + } + + tarteaucitron.addScript('//flex.atdmt.com/mstag/site/' + tarteaucitron.user.microsoftcampaignanalyticsUUID + '/mstag.js', 'mstag_tops', function () { + window.mstag = {loadTag : function () {}, time : (new Date()).getTime()}; + window.mstag.loadTag("analytics", {dedup: "1", domainId: tarteaucitron.user.microsoftcampaignanalyticsdomainId, type: "1", actionid: tarteaucitron.user.microsoftcampaignanalyticsactionId}); + }); + } +}; + +// pinterest +tarteaucitron.services.pinterest = { + "key": "pinterest", + "type": "social", + "name": "Pinterest", + "uri": "https://about.pinterest.com/privacy-policy", + "needConsent": true, + "cookies": [], + "js": function () { + "use strict"; + tarteaucitron.fallback(['tacPinterest'], ''); + tarteaucitron.addScript('//assets.pinterest.com/js/pinit.js'); + }, + "fallback": function () { + "use strict"; + var id = 'pinterest'; + tarteaucitron.fallback(['tacPinterest'], tarteaucitron.engage(id)); + } +}; + +// prelinker +tarteaucitron.services.prelinker = { + "key": "prelinker", + "type": "ads", + "name": "Prelinker", + "uri": "http://www.prelinker.com/index/index/cgu/", + "needConsent": true, + "cookies": ['_sp_id.32f5', '_sp_ses.32f5'], + "js": function () { + "use strict"; + var uniqIds = [], + i, + uri; + + tarteaucitron.fallback(['prelinker-canvas'], function (x) { + var uniqId = '_' + Math.random().toString(36).substr(2, 9); + uniqIds.push(uniqId); + return '
'; + }); + + for (i = 0; i < uniqIds.length; i += 1) { + uri = 'http://promo.easy-dating.org/banner/index?'; + uri += 'site_id=' + document.getElementById(uniqIds[i]).getAttribute('siteId') + '&'; + uri += 'banner_id=' + document.getElementById(uniqIds[i]).getAttribute('bannerId') + '&'; + uri += 'default_language=' + document.getElementById(uniqIds[i]).getAttribute('defaultLanguage') + '&'; + uri += 'tr4ck=' + document.getElementById(uniqIds[i]).getAttribute('trackrt'); + + tarteaucitron.makeAsync.init(uri, uniqIds[i]); + } + }, + "fallback": function () { + "use strict"; + var id = 'prelinker'; + tarteaucitron.fallback(['prelinker-canvas'], tarteaucitron.engage(id)); + } +}; + +// prezi +tarteaucitron.services.prezi = { + "key": "prezi", + "type": "video", + "name": "Prezi", + "uri": "https://prezi.com/privacy-policy/", + "needConsent": true, + "cookies": [], + "js": function () { + "use strict"; + tarteaucitron.fallback(['prezi-canvas'], function (x) { + var id = x.getAttribute("data-id"), + width = x.getAttribute("width"), + height = x.getAttribute("height"), + url = 'https://prezi.com/embed/' + id + '/?bgcolor=ffffff&lock_to_path=0&autoplay=0&autohide_ctrls=0'; + + return ''; + }); + }, + "fallback": function () { + "use strict"; + var id = 'prezi'; + tarteaucitron.fallback(['prezi-canvas'], function (elem) { + elem.style.width = elem.getAttribute('width') + 'px'; + elem.style.height = elem.getAttribute('height') + 'px'; + return tarteaucitron.engage(id); + }); + } +}; + +// pubdirecte +tarteaucitron.services.pubdirecte = { + "key": "pubdirecte", + "type": "ads", + "name": "Pubdirecte", + "uri": "http://pubdirecte.com/contact.php", + "needConsent": true, + "cookies": [], + "js": function () { + "use strict"; + var uniqIds = [], + i, + uri; + + tarteaucitron.fallback(['pubdirecte-canvas'], function (x) { + var uniqId = '_' + Math.random().toString(36).substr(2, 9); + uniqIds.push(uniqId); + return '
'; + }); + + for (i = 0; i < uniqIds.length; i += 1) { + uri = '//www.pubdirecte.com/script/banniere.php?'; + uri += 'id=' + document.getElementById(uniqIds[i]).getAttribute('pid') + '&'; + uri += 'ref=' + document.getElementById(uniqIds[i]).getAttribute('ref'); + + tarteaucitron.makeAsync.init(uri, uniqIds[i]); + } + }, + "fallback": function () { + "use strict"; + var id = 'pubdirecte'; + tarteaucitron.fallback(['pubdirecte-canvas'], tarteaucitron.engage(id)); + } +}; + +// purechat +tarteaucitron.services.purechat = { + "key": "purechat", + "type": "support", + "name": "PureChat", + "uri": "https://www.purechat.com/privacy", + "needConsent": true, + "cookies": [], + "js": function () { + "use strict"; + if (tarteaucitron.user.purechatId === undefined) { + return; + } + + tarteaucitron.addScript('//app.purechat.com/VisitorWidget/WidgetScript', '', function () { + try { + window.w = new PCWidget({ c: tarteaucitron.user.purechatId, f: true }); + } catch (e) {} + }); + } +}; + +// shareaholic +tarteaucitron.services.shareaholic = { + "key": "shareaholic", + "type": "social", + "name": "Shareaholic", + "uri": "https://shareaholic.com/privacy/choices", + "needConsent": true, + "cookies": ['__utma', '__utmb', '__utmc', '__utmz', '__utmt_Shareaholic%20Pageviews'], + "js": function () { + "use strict"; + if (tarteaucitron.user.shareaholicSiteId === undefined) { + return; + } + + tarteaucitron.fallback(['shareaholic-canvas'], ''); + tarteaucitron.addScript('//dsms0mj1bbhn4.cloudfront.net/assets/pub/shareaholic.js', '', function () { + try { + Shareaholic.init(tarteaucitron.user.shareaholicSiteId); + } catch (e) {} + }); + }, + "fallback": function () { + "use strict"; + var id = 'shareaholic'; + tarteaucitron.fallback(['shareaholic-canvas'], tarteaucitron.engage(id)); + } +}; + +// shareasale +tarteaucitron.services.shareasale = { + "key": "shareasale", + "type": "ads", + "name": "ShareASale", + "uri": "https://www.shareasale.com/PrivacyPolicy.pdf", + "needConsent": true, + "cookies": [], + "js": function () { + "use strict"; + var uniqIds = [], + i, + uri; + + tarteaucitron.fallback(['shareasale-canvas'], function (x) { + var uniqId = '_' + Math.random().toString(36).substr(2, 9); + uniqIds.push(uniqId); + return '
'; + }); + + for (i = 0; i < uniqIds.length; i += 1) { + uri = 'https://shareasale.com/sale.cfm?'; + uri += 'amount=' + document.getElementById(uniqIds[i]).getAttribute('amount') + '&'; + uri += 'tracking=' + document.getElementById(uniqIds[i]).getAttribute('tracking') + '&'; + uri += 'transtype=' + document.getElementById(uniqIds[i]).getAttribute('transtype') + '&'; + uri += 'persale=' + document.getElementById(uniqIds[i]).getAttribute('persale') + '&'; + uri += 'perlead=' + document.getElementById(uniqIds[i]).getAttribute('perlead') + '&'; + uri += 'perhit=' + document.getElementById(uniqIds[i]).getAttribute('perhit') + '&'; + uri += 'merchantID=' + document.getElementById(uniqIds[i]).getAttribute('merchantID'); + + document.getElementById(uniqIds[i]).innerHTML = ''; + } + }, + "fallback": function () { + "use strict"; + var id = 'shareasale'; + tarteaucitron.fallback(['shareasale-canvas'], tarteaucitron.engage(id)); + } +}; + +// sharethis +tarteaucitron.services.sharethis = { + "key": "sharethis", + "type": "social", + "name": "ShareThis", + "uri": "http://www.sharethis.com/legal/privacy/", + "needConsent": true, + "cookies": ['__unam'], + "js": function () { + "use strict"; + if (tarteaucitron.user.sharethisPublisher === undefined) { + return; + } + var switchTo5x = true, + uri = ('https:' === document.location.protocol ? 'https://ws' : 'http://w') + '.sharethis.com/button/buttons.js'; + + tarteaucitron.fallback(['tacSharethis'], ''); + tarteaucitron.addScript(uri, '', function () { + stLight.options({publisher: tarteaucitron.user.sharethisPublisher, doNotHash: false, doNotCopy: false, hashAddressBar: false}); + }); + + if (tarteaucitron.isAjax === true) { + if (typeof stButtons !== "undefined") { + stButtons.locateElements(); + } + } + }, + "fallback": function () { + "use strict"; + var id = 'sharethis'; + tarteaucitron.fallback(['tacSharethis'], tarteaucitron.engage(id)); + } +}; + +// slideshare +tarteaucitron.services.slideshare = { + "key": "slideshare", + "type": "video", + "name": "SlideShare", + "uri": "https://www.linkedin.com/legal/privacy-policy", + "needConsent": true, + "cookies": [], + "js": function () { + "use strict"; + tarteaucitron.fallback(['slideshare-canvas'], function (x) { + var id = x.getAttribute("data-id"), + width = x.getAttribute("width"), + height = x.getAttribute("height"), + url = '//www.slideshare.net/slideshow/embed_code/' + id; + + return ''; + }); + }, + "fallback": function () { + "use strict"; + var id = 'slideshare'; + tarteaucitron.fallback(['slideshare-canvas'], function (elem) { + elem.style.width = elem.getAttribute('width') + 'px'; + elem.style.height = elem.getAttribute('height') + 'px'; + return tarteaucitron.engage(id); + }); + } +}; + +// statcounter +tarteaucitron.services.statcounter = { + "key": "statcounter", + "type": "analytic", + "name": "StatCounter", + "uri": "https://fr.statcounter.com/about/legal/#privacy", + "needConsent": true, + "cookies": ['sc_is_visitor_unique'], + "js": function () { + "use strict"; + var uniqIds = [], + i, + uri = '//statcounter.com/counter/counter.js'; + + tarteaucitron.fallback(['statcounter-canvas'], function (x) { + var uniqId = '_' + Math.random().toString(36).substr(2, 9); + uniqIds.push(uniqId); + return '
'; + }); + + for (i = 0; i < uniqIds.length; i += 1) { + tarteaucitron.makeAsync.init(uri, uniqIds[i]); + } + }, + "fallback": function () { + "use strict"; + var id = 'statcounter'; + tarteaucitron.fallback(['statcounter-canvas'], tarteaucitron.engage(id)); + } +}; + +// timelinejs +tarteaucitron.services.timelinejs = { + "key": "timelinejs", + "type": "api", + "name": "Timeline JS", + "uri": "http://timeline.knightlab.com/#help", + "needConsent": true, + "cookies": [], + "js": function () { + "use strict"; + tarteaucitron.fallback(['timelinejs-canvas'], function (x) { + var spreadsheet_id = x.getAttribute("spreadsheet_id"), + width = x.getAttribute("width"), + height = x.getAttribute("height"), + lang = x.getAttribute("lang_2_letter"), + font = x.getAttribute("font"), + map = x.getAttribute("map"), + start_at_end = x.getAttribute("start_at_end"), + hash_bookmark = x.getAttribute("hash_bookmark"), + start_at_slide = x.getAttribute("start_at_slide"), + start_zoom = x.getAttribute("start_zoom"), + url = '//cdn.knightlab.com/libs/timeline/latest/embed/index.html?source=' + spreadsheet_id + '&font=' + font + '&maptype=' + map + '&lang=' + lang + '&start_at_end=' + start_at_end + '&hash_bookmark=' + hash_bookmark + '&start_at_slide=' + start_at_slide + '&start_zoom_adjust=' + start_zoom + '&height=' + height; + + return ''; + }); + }, + "fallback": function () { + "use strict"; + var id = 'timelinejs'; + tarteaucitron.fallback(['timelinejs-canvas'], function (elem) { + elem.style.width = elem.getAttribute('width') + 'px'; + elem.style.height = elem.getAttribute('height') + 'px'; + return tarteaucitron.engage(id); + }); + } +}; + +// typekit +tarteaucitron.services.typekit = { + "key": "typekit", + "type": "api", + "name": "Typekit (adobe)", + "uri": "http://www.adobe.com/fr/privacy.html", + "needConsent": true, + "cookies": [], + "js": function () { + "use strict"; + if (tarteaucitron.user.typekitId === undefined) { + return; + } + tarteaucitron.addScript('//use.typekit.net/' + tarteaucitron.user.typekitId + '.js', '', function () { + try { + Typekit.load(); + } catch (e) {} + }); + } +}; + +// twenga +tarteaucitron.services.twenga = { + "key": "twenga", + "type": "ads", + "name": "Twenga", + "uri": "http://www.twenga.com/privacy.php", + "needConsent": true, + "cookies": [], + "js": function () { + "use strict"; + + if (tarteaucitron.user.twengaId === undefined || tarteaucitron.user.twengaLocale === undefined) { + return; + } + + tarteaucitron.addScript('//tracker.twenga.' + tarteaucitron.user.twengaLocale + '/st/tracker_' + tarteaucitron.user.twengaId + '.js'); + } +}; + +// twitter +tarteaucitron.services.twitter = { + "key": "twitter", + "type": "social", + "name": "Twitter", + "uri": "https://support.twitter.com/articles/20170514", + "needConsent": true, + "cookies": [], + "js": function () { + "use strict"; + tarteaucitron.fallback(['tacTwitter'], ''); + tarteaucitron.addScript('//platform.twitter.com/widgets.js', 'twitter-wjs'); + }, + "fallback": function () { + "use strict"; + var id = 'twitter'; + tarteaucitron.fallback(['tacTwitter'], tarteaucitron.engage(id)); + } +}; + +// twitter embed +tarteaucitron.services.twitterembed = { + "key": "twitterembed", + "type": "social", + "name": "Twitter (cards)", + "uri": "https://support.twitter.com/articles/20170514", + "needConsent": true, + "cookies": [], + "js": function () { + "use strict"; + var uniqIds = [], + i, + e, + html; + + tarteaucitron.fallback(['twitterembed-canvas'], function (x) { + var uniqId = '_' + Math.random().toString(36).substr(2, 9); + uniqIds.push(uniqId); + html = '
'; + return html; + }); + + tarteaucitron.addScript('//platform.twitter.com/widgets.js', 'twitter-wjs', function () { + for (i = 0; i < uniqIds.length; i += 1) { + e = document.getElementById(uniqIds[i]); + twttr.widgets.createTweet( + e.getAttribute('tweetid'), + e, + { + theme: e.getAttribute('theme'), + cards: e.getAttribute('cards'), + conversation: e.getAttribute('conversation'), + lang: tarteaucitron.getLanguage(), + dnt: true, + width: e.getAttribute('data-width'), + align: e.getAttribute('data-align') + } + ); + } + }); + }, + "fallback": function () { + "use strict"; + var id = 'twitterembed'; + tarteaucitron.fallback(['twitterembed-canvas'], function (elem) { + elem.style.width = elem.getAttribute('data-width') + 'px'; + return tarteaucitron.engage(id); + }); + } +}; + +// twitter timeline +tarteaucitron.services.twittertimeline = { + "key": "twittertimeline", + "type": "social", + "name": "Twitter (timelines)", + "uri": "https://support.twitter.com/articles/20170514", + "needConsent": true, + "cookies": [], + "js": function () { + "use strict"; + tarteaucitron.fallback(['tacTwitterTimelines'], ''); + tarteaucitron.addScript('//platform.twitter.com/widgets.js', 'twitter-wjs'); + }, + "fallback": function () { + "use strict"; + var id = 'twittertimeline'; + tarteaucitron.fallback(['tacTwitterTimelines'], tarteaucitron.engage(id)); + } +}; + +// user voice +tarteaucitron.services.uservoice = { + "key": "uservoice", + "type": "support", + "name": "UserVoice", + "uri": "https://www.uservoice.com/privacy/", + "needConsent": true, + "cookies": [], + "js": function () { + "use strict"; + if (tarteaucitron.user.userVoiceApi === undefined) { + return; + } + tarteaucitron.addScript('//widget.uservoice.com/' + tarteaucitron.user.userVoiceApi + '.js'); + } +}; + +// vimeo +tarteaucitron.services.vimeo = { + "key": "vimeo", + "type": "video", + "name": "Vimeo", + "uri": "http://vimeo.com/privacy", + "needConsent": true, + "cookies": ['__utmt_player', '__utma', '__utmb', '__utmc', '__utmv', 'vuid', '__utmz', 'player'], + "js": function () { + "use strict"; + tarteaucitron.fallback(['vimeo_player'], function (x) { + var video_id = x.getAttribute("videoID"), + video_width = x.getAttribute("width"), + frame_width = 'width=', + video_height = x.getAttribute("height"), + frame_height = 'height=', + video_frame; + + if (video_id === undefined) { + return ""; + } + if (video_width !== undefined) { + frame_width += '"' + video_width + '" '; + } else { + frame_width += '"" '; + } + if (video_height !== undefined) { + frame_height += '"' + video_height + '" '; + } else { + frame_height += '"" '; + } + video_frame = ''; + return video_frame; + }); + }, + "fallback": function () { + "use strict"; + var id = 'vimeo'; + tarteaucitron.fallback(['vimeo_player'], function (elem) { + elem.style.width = elem.getAttribute('width') + 'px'; + elem.style.height = elem.getAttribute('height') + 'px'; + return tarteaucitron.engage(id); + }); + } +}; + +// visualrevenue +tarteaucitron.services.visualrevenue = { + "key": "visualrevenue", + "type": "analytic", + "name": "VisualRevenue", + "uri": "http://www.outbrain.com/legal/privacy-713/", + "needConsent": true, + "cookies": ['__vrf', '__vrm', '__vrl', '__vry', '__vru', '__vrid', '__vrz'], + "js": function () { + "use strict"; + if (tarteaucitron.user.visualrevenueId === undefined) { + return; + } + window._vrq = window._vrq || []; + window._vrq.push(['id', tarteaucitron.user.visualrevenueId]); + window._vrq.push(['automate', true]); + window._vrq.push(['track', function () {}]); + tarteaucitron.addScript('http://a.visualrevenue.com/vrs.js'); + } +}; + +// vshop +tarteaucitron.services.vshop = { + "key": "vshop", + "type": "ads", + "name": "vShop", + "uri": "http://vshop.fr/privacy-policy", + "needConsent": true, + "cookies": [], + "js": function () { + "use strict"; + tarteaucitron.fallback(['vcashW'], ''); + tarteaucitron.addScript('//vshop.fr/js/w.js'); + }, + "fallback": function () { + "use strict"; + var id = 'vshop'; + tarteaucitron.fallback(['vcashW'], tarteaucitron.engage(id)); + } +}; + +// wysistat +tarteaucitron.services.wysistat = { + "key": "wysistat", + "type": "analytic", + "name": "Wysistat", + "uri": "http://wysistat.net/contact/", + "needConsent": true, + "cookies": ['Wysistat'], + "js": function () { + "use strict"; + if (tarteaucitron.user.wysistat === undefined) { + return; + } + tarteaucitron.addScript('//www.wysistat.com/statistique.js', '', function () { + window.stat(tarteaucitron.user.wysistat.cli, tarteaucitron.user.wysistat.frm, tarteaucitron.user.wysistat.prm, tarteaucitron.user.wysistat.ce, tarteaucitron.user.wysistat.page, tarteaucitron.user.wysistat.roi, tarteaucitron.user.wysistat.prof, tarteaucitron.user.wysistat.cpt); + }); + } +}; + +// xiti +tarteaucitron.services.xiti = { + "key": "xiti", + "type": "analytic", + "name": "Xiti", + "uri": "http://www.atinternet.com/politique-du-respect-de-la-vie-privee/", + "needConsent": true, + "cookies": [], + "js": function () { + "use strict"; + if (tarteaucitron.user.xitiId === undefined) { + return; + } + var Xt_param = 's=' + tarteaucitron.user.xitiId + '&p=', + Xt_r, + Xt_h, + Xt_i, + Xt_s, + div = document.createElement('div'); + try { + Xt_r = top.document.referrer; + } catch (e) { + Xt_r = document.referrer; + } + Xt_h = new Date(); + Xt_i = '= 4) { + Xt_s = screen; + Xt_i += '&r=' + Xt_s.width + 'x' + Xt_s.height + 'x' + Xt_s.pixelDepth + 'x' + Xt_s.colorDepth; + } + + div.innerHTML = Xt_i + '&ref=' + Xt_r.replace(/[<>"]/g, '').replace(/&/g, '$') + '" title="Internet Audience">'; + document.getElementsByTagName('body')[0].appendChild(div.firstChild); + + if (typeof tarteaucitron.user.xitiMore === 'function') { + tarteaucitron.user.xitiMore(); + } + } +}; + +// youtube +tarteaucitron.services.youtube = { + "key": "youtube", + "type": "video", + "name": "YouTube", + "uri": "https://www.google.fr/intl/fr/policies/privacy/", + "needConsent": true, + "cookies": ['VISITOR_INFO1_LIVE', 'YSC', 'PREF', 'GEUP'], + "js": function () { + "use strict"; + tarteaucitron.fallback(['youtube_player'], function (x) { + var video_id = x.getAttribute("videoID"), + video_width = x.getAttribute("width"), + frame_width = 'width=', + video_height = x.getAttribute("height"), + frame_height = 'height=', + video_frame, + params = 'theme=' + x.getAttribute("theme") + '&rel=' + x.getAttribute("rel") + '&controls=' + x.getAttribute("controls") + '&showinfo=' + x.getAttribute("showinfo") + '&autoplay=' + x.getAttribute("autoplay"); + + if (video_id === undefined) { + return ""; + } + if (video_width !== undefined) { + frame_width += '"' + video_width + '" '; + } else { + frame_width += '"" '; + } + if (video_height !== undefined) { + frame_height += '"' + video_height + '" '; + } else { + frame_height += '"" '; + } + video_frame = ''; + return video_frame; + }); + }, + "fallback": function () { + "use strict"; + var id = 'youtube'; + tarteaucitron.fallback(['youtube_player'], function (elem) { + elem.style.width = elem.getAttribute('width') + 'px'; + elem.style.height = elem.getAttribute('height') + 'px'; + return tarteaucitron.engage(id); + }); + } +}; + +// youtube playlist +tarteaucitron.services.youtubeplaylist = { + "key": "youtubeplaylist", + "type": "video", + "name": "YouTube (playlist)", + "uri": "https://www.google.fr/intl/fr/policies/privacy/", + "needConsent": true, + "cookies": ['VISITOR_INFO1_LIVE', 'YSC', 'PREF', 'GEUP'], + "js": function () { + "use strict"; + tarteaucitron.fallback(['youtube_playlist_player'], function (x) { + var playlist_id = x.getAttribute("playlistID"), + video_width = x.getAttribute("width"), + frame_width = 'width=', + video_height = x.getAttribute("height"), + frame_height = 'height=', + video_frame, + params = 'theme=' + x.getAttribute("theme") + '&rel=' + x.getAttribute("rel") + '&controls=' + x.getAttribute("controls") + '&showinfo=' + x.getAttribute("showinfo") + '&autoplay=' + x.getAttribute("autoplay"); + + if (playlist_id === undefined) { + return ""; + } + if (video_width !== undefined) { + frame_width += '"' + video_width + '" '; + } else { + frame_width += '"" '; + } + if (video_height !== undefined) { + frame_height += '"' + video_height + '" '; + } else { + frame_height += '"" '; + } + video_frame = ''; + return video_frame; + }); + }, + "fallback": function () { + "use strict"; + var id = 'youtubeplaylist'; + tarteaucitron.fallback(['youtube_playlist_player'], function (elem) { + elem.style.width = elem.getAttribute('width') + 'px'; + elem.style.height = elem.getAttribute('height') + 'px'; + return tarteaucitron.engage(id); + }); + } +}; + +// zopim +tarteaucitron.services.zopim = { + "key": "zopim", + "type": "support", + "name": "Zopim", + "uri": "https://www.zopim.com/privacy", + "needConsent": true, + "cookies": ['__zlcid', '__zprivacy'], + "js": function () { + "use strict"; + if (tarteaucitron.user.zopimID === undefined) { + return; + } + tarteaucitron.addScript('//v2.zopim.com/?' + tarteaucitron.user.zopimID); + } +}; + +// xiti smartTag +tarteaucitron.services.xiti_smarttag = { + "key": "xiti_smarttag", + "type": "analytic", + "name": "Xiti (SmartTag)", + "uri": "https://www.atinternet.com/societe/protection-des-donnees/", + "needConsent": true, + "cookies": ["atidvisitor", "atreman", "atredir", "atsession", "atuserid", "attvtreman", "attvtsession"], + "js": function () { + "use strict"; + if (tarteaucitron.user.xiti_smarttagLocalPath !== undefined) { + tarteaucitron.addScript(tarteaucitron.user.xiti_smarttagLocalPath, 'smarttag', null, null, "onload", "addTracker();"); + } else { + var xitiSmarttagId = tarteaucitron.user.xiti_smarttagSiteId; + if (xitiSmarttagId === undefined) { + return; + } + + tarteaucitron.addScript('//tag.aticdn.net/' + xitiSmarttagId + '/smarttag.js', 'smarttag', null, null, "onload", "addTracker();"); + } + } +}; + +// facebook pixel +tarteaucitron.services.facebookpixel = { + "key": "facebookpixel", + "type": "ads", + "name": "Facebook Pixel", + "uri": "https://fr-fr.facebook.com/business/help/www/651294705016616", + "needConsent": true, + "cookies": ['datr', 'fr', 'reg_ext_ref', 'reg_fb_gate', 'reg_fb_ref', 'sb', 'wd', 'x-src'], + "js": function () { + "use strict"; + var n; + if(window.fbq)return; + n=window.fbq=function(){n.callMethod? n.callMethod.apply(n,arguments):n.queue.push(arguments)} ; + if(!window._fbq)window._fbq=n; + n.push=n; + n.loaded=!0; + n.version='2.0'; + n.queue=[]; + tarteaucitron.addScript('https://connect.facebook.net/en_US/fbevents.js'); + fbq('init', tarteaucitron.user.facebookpixelId); + fbq('track', 'PageView'); + + if (typeof tarteaucitron.user.facebookpixelMore === 'function') { + tarteaucitron.user.facebookpixelMore(); + } + } +}; + diff --git a/docs/pages/home.md b/docs/pages/home.md new file mode 100644 index 0000000..23abc2c --- /dev/null +++ b/docs/pages/home.md @@ -0,0 +1,30 @@ +
+
+ An Open Source Rules Engine - Make rule handling simple +
+
+ +
+ +# Welcome to the documentation + +* Want to discover what is **Arta**? :arrow_right: [Get Started](a_simple_example.md) +* Want to know how to use it? :arrow_right: [User Guide](how_to.md) + +!!! info "New feature" + + Check out the new and very convenient feature called the [simple condition](how_to.md#simple-condition). A new and lightweight way of configuring your rules' conditions. + +**Arta** is automatically tested with: + +![Alt Python](https://img.shields.io/pypi/pyversions/arta) + +!!! tip "Releases" + + Want to see last updates, check the [Release notes](https://github.com/MAIF/arta/releases) :rocket: + +!!! success "Pydantic 2" + + **Arta** is now working with [Pydantic 2](https://docs.pydantic.dev/latest/)! And of course, Pydantic 1 as well. diff --git a/docs/pages/how_to.md b/docs/pages/how_to.md index cb4dca2..4315116 100644 --- a/docs/pages/how_to.md +++ b/docs/pages/how_to.md @@ -1,246 +1,107 @@ Ensure that you have correctly installed **Arta** before, check the [Installation](installation.md) page :wrench: -## Hello World +## Simple condition -You want a simple code to play with? Here it comes: +!!! example "Beta feature" -=== "Without type hints" - - ```python - from arta import RulesEngine - - set_admission = lambda value, **kwargs: {"is_admitted": value} - - rules = { - "check_admission": { - "ADMITTED_RULE": { - "condition": lambda power: power in ["strength", "fly", "immortality"], - "condition_parameters": {"power": "input.super_power"}, - "action": set_admission, - "action_parameters": {"value": True}, - }, - "DEFAULT_RULE": { - "condition": None, - "condition_parameters": None, - "action": set_admission, - "action_parameters": {"value": False}, - }, - } - } - - input_data = { - "id": 1, - "name": "Superman", - "civilian_name": "Clark Kent", - "age": None, - "city": "Metropolis", - "language": "french", - "super_power": "fly", - "favorite_meal": "Spinach", - "secret_weakness": "Kryptonite", - "weapons": [], - } - - eng = RulesEngine(rules_dict=rules) - - result = eng.apply_rules(input_data) - - print(result) - ``` - -=== "With type hints (>=3.9)" - - ```python - from typing import Any, Callable - - from arta import RulesEngine - - set_admission: Callable = lambda value, **kwargs: {"is_admitted": value} - - rules: dict[str, Any] = { - "check_admission": { - "ADMITTED_RULE": { - "condition": lambda power: power in ["strength", "fly", "immortality"], - "condition_parameters": {"power": "input.super_power"}, - "action": set_admission, - "action_parameters": {"value": True}, - }, - "DEFAULT_RULE": { - "condition": None, - "condition_parameters": None, - "action": set_admission, - "action_parameters": {"value": False}, - }, - } - } - - input_data: dict[str, Any] = { - "id": 1, - "name": "Superman", - "civilian_name": "Clark Kent", - "age": None, - "city": "Metropolis", - "language": "french", - "super_power": "fly", - "favorite_meal": "Spinach", - "secret_weakness": "Kryptonite", - "weapons": [], - } - - eng = RulesEngine(rules_dict=rules) + **Simple condition** is still a *beta feature*, some cases could not work as designed. - result: dict[str, Any] = eng.apply_rules(input_data) - - print(result) - ``` +**Simple conditions** are a new and straightforward way of configuring your *conditions*. -You should get: +It simplifies a lot your rules by: - {'check_admission': {'is_admitted': True}} - -!!! success - Superman is admitted to the superhero school! - -Well done! By executing this code you have: - -1. Defined an **action function** (`set_admission`) -2. Defined a **rule set** (`rules`) -3. Used some **input data** (`input_data`) -4. Instanciated a **rules engine** (`RulesEngine`) -5. Applied the rules on the data and get some results (`.apply_rules()`) +* Removing the use of a `conditions.py` module (no validation functions needed). +* Removing the `conditions:` configuration key in your YAML files. !!! note - In the code example we used some anonymous/lambda function for simplicity but it could be regular python functions as well. - -!!! abstract "API Documentation" - - You can get details on the `RulesEngine` parameters in the [API Reference](api_reference.md). - -Have you read the [Get Started](in_a_nutshell.md) section? If not, you probably should before going further :smiley: - -## Concepts - -Let's go deeper into the previous code: - -### Rule sets and rule groups - -A **rule set** is composed of **rule groups** which are themselves composed of **rules**. We can find this tree structure in the following dictionary: - -```python -rules = { # (1) - "check_admission": { # (2) - "ADMITTED_RULE": { # (3) - "condition": lambda power: power in ["strength", "fly", "immortality"], - "condition_parameters": {"power": "input.super_power"}, - "action": set_admission, - "action_parameters": {"value": True}, - }, - "DEFAULT_RULE": { - "condition": None, - "condition_parameters": None, - "action": set_admission, - "action_parameters": {"value": False}, - }, - } -} -``` - -1. This dictionary contains a *rule set*. -2. This key define a *rule group*, we can have many groups (we have only one here for simplicity). -3. This key is a *rule id*, which identifies *rules* among others. - -### Rules - -**Rules** are identified by an id or key (e.g., `ADMITTED_RULE`) and defined by a dictionary: - -```python hl_lines="2-5" -"ADMITTED_RULE": { - "condition": lambda power: power in ["strength", "fly", "immortality"], - "condition_parameters": {"power": "input.super_power"}, - "action": set_admission, - "action_parameters": {"value": True}, -} -``` - -!!! tip + With the **simple conditions** you use straight *boolean expressions* directly in your configuration. + + It is easyer to read and maintain :+1: - Rule **ids** are in capital letters for readability only: it is an advised best practice. +The *configuration key* here is: -**Rules** are made of 2 different things: +> `simple_condition:` -* Condition: +Example : -```python hl_lines="2 3" -{ - "condition": lambda power: power in ["strength", "fly", "immortality"], - "condition_parameters": {"power": "input.super_power"}, - "action": set_admission, - "action_parameters": {"value": True}, -} -``` - -* Action: +```yaml hl_lines="6 11 16" +--- +rules: + default_rule_set: + admission: + ADM_OK: + simple_condition: input.power=="strength" or input.power=="fly" + action: set_admission + action_parameters: + value: OK + ADM_TO_BE_CHECKED: + simple_condition: input.age>=150 and input.age!=None + action: set_admission + action_parameters: + value: TO_CHECK + ADM_KO: + simple_condition: null + action: set_admission + action_parameters: + value: KO -```python hl_lines="4 5" -{ - "condition": lambda power: power in ["strength", "fly", "immortality"], - "condition_parameters": {"power": "input.super_power"}, - "action": set_admission, - "action_parameters": {"value": True}, -} +actions_source_modules: + - my_folder.actions # (1) ``` -### Conditions and Actions +1. Contains *action function* implementations, no need of the key `conditions_source_modules` here. -**Conditions** and **actions** are quite similar in terms of implementation but their goal is different. +How to write a simple condition like: -Both are made of a *callable object* and *parameters*: + input.power=="strength" or input.power=="fly" -* Condition keys: - * `condition`: a callable python object that returns a `bool`, we called this function the **validation function** (or *condition function*). - * `condition_parameters`: a dictionary mapping the validation function's parameters with their correponding values. -* Action keys: - * `action`: a callable python object that returns what you want (or does what you want such as: requesting an api, sending an email, etc.), we called this function the **action function**. - * `action_parameters`: a dictionary mapping the action function's parameters with their correponding values. +* **Left operand (data mapping):** + * You must use one of the following prefixes: + * `input` (for input data) + * `output` (for previous rule's result) + * A *dot path* expression like `input.powers.main_power`. +* **Operator:** you must use basic python *boolean operator* (i.e., `==, <, >, <=, >=, !=`) +* **Right operand:** basic python data types (e.i., `str, int, None`). -!!! question "Does a condition could be something else than a function?" +!!! warning - Actually yes, a `condition` can be a python function but you will learn later that it can also be a **condition expression** (i.e., a boolean expression combining different individual conditions). + * You can't use: `is` or `in`, as an **operator** (yet). + * You can't use a `float` as **right operand** (it's a bug, will be fixed). + * For strings, don't forget the **double quotes** `"`. -!!! tip "Parameter's special syntax" +!!! danger "Security concern" - As you can see in the previous code, the action and condition parameters can have a special syntax: + **Python code injection:** - {"power": "input.super_power"} + Because **Arta** is using the `eval()` built-in function to evaluate *simple conditions*: - The string `input.super_power` is evaluated by the rules engine and it means *"fetch the key `super_power` in the input data"*. Keep reading, you will find out later. - -## Configuration + * **You should never let the user** being able of dynamically define a *simple condition* (in `simple_condition:` conf. key). + * You should verify that **write permissions on the YAML files** are not allowed when your app is deployed. -In the [Hello World](#hello-world) section of this user guide, you learnt how to instanciate and use the *rules engine* with a dictionary **rule set**. It's the reason why you used the correponding parameter `rules_dict` for the instancation: +## Standard condition - eng = RulesEngine(rules_dict=rules) +It is the first implemented way of using **Arta** and probably the most powerful. -But there is another way to define your rules: using a **configuration** (i.e., some configuration files). +The *configuration key* here is: -For real use cases, using configuration is way much more convenient than using a dictionary :+1: +> `condition:` !!! info "YAML" - The built-in file format used by Arta for configuration is YAML. + The built-in file format used by Arta for configuration is **YAML**. !!! example "Enhancement proposal" - We are thinking on a design that will allow custom configuration backend which will allow user-implemented loading of the configuration (e.g., you prefer using a JSON format). Stay tuned. + We are thinking on a design that will allow user-implemented loading of the configuration (e.g., if you prefer using a JSON format). Stay tuned. ### YAML file !!! tip "Simple Conditions" - The following **YAML** example illustrates how to configure usual *standard conditions* but there is another and simpler way to do it by using a special feature: the [simple condition](special_conditions.md#simple-condition). + The following **YAML** example illustrates how to configure usual *standard conditions* but there is another and simpler way to do it by using a special feature: the [simple condition](#simple-condition). -Create a YAML file and define your rules almost like you did with the dictionary `rules`. There is few differences that we will focus on later: +Create a YAML file and define your rules like this: ```yaml hl_lines="6 16-26" --- @@ -286,8 +147,8 @@ actions_source_modules: # (5) You can split your configuration in multiple YAML files seamlessly in order to keep things clear. Example: * global.yaml => source modules - * rules.yaml => rule definitions - * conditions.yaml => condition definitions + * rules.yaml => rules' definition + * conditions.yaml => conditions' definition It's very convenient when you have a lot of different rules and conditions in your app. @@ -307,7 +168,7 @@ rules: value: true ``` -As it was previously mentionned, the key `condition:` can take one **condition id** but also a **condition expression** (i.e., a boolean expression of condition ids) combining several conditions: +The key `condition:` can take one **condition id** but also a **condition expression** (i.e., a boolean expression of condition ids) combining several conditions: ```yaml hl_lines="6" --- @@ -323,7 +184,7 @@ rules: !!! warning - In that example, you must define the 3 condition ids in the configuration: + In that example, you must define the 3 conditions in the configuration: * HAS_SCHOOL_AUTHORIZED_POWER * SPEAKS_FRENCH @@ -333,7 +194,7 @@ rules: Use the **condition expressions** to keep things simple. Put your conditions in one expression as you can rather than creating several rules :wink: -### Implementing functions +### Functions We must create 2 modules: @@ -393,22 +254,235 @@ result = eng.apply_rules(input_data) print(result) ``` -You should get the same result as [previously](#hello-world) (dictionary version): +You should get: - {'check_admission': {'is_admitted': True}} +> `{'check_admission': {'is_admitted': True}}` + +!!! abstract "API Documentation" + + You can get details on the `RulesEngine` parameters in the [API Reference](api_reference.md). + +## Concepts + +Let's go deeper into the concepts. + +### Rule set and rule group + +A **rule set** is composed of **rule groups** which are themselves composed of **rules**. We can find this tree structure in the following YAML: + +```yaml +--- +rules: + default_rule_set: # (1) + check_admission: # (2) + ADMITTED_RULE: # (3) + condition: HAS_SCHOOL_AUTHORIZED_POWER + action: set_admission + action_parameters: + value: true + DEFAULT_RULE: + condition: null + action: set_admission + action_parameters: + value: false -## To sum up +conditions: + HAS_SCHOOL_AUTHORIZED_POWER: + description: "Does applicant have a school authorized power?" + validation_function: has_authorized_super_power + condition_parameters: + power: input.super_power +``` -At this point you have learnt the regular use of an **Arta** rules engine and you have seen the two major ways of defining rules: +1. This is the id of the *rule set*. +2. This key define a *rule group*, we can have many groups (we have only one here for simplicity). +3. This key is a *rule id*, which identifies *rules* among others. + +### Rule + +**Rule** definitions are identified by an id (e.g., `ADMITTED_RULE`): -* [Using a dictionary of rules](#hello-world). -* [Using a configuration file](#configuration) (or many). +```yaml hl_lines="2-5" + ADMITTED_RULE: + condition: HAS_SCHOOL_AUTHORIZED_POWER + action: set_admission + action_parameters: + value: true +``` !!! tip + Rule **ids** are in capital letters for readability only: it is an advised practice. + +**Rules** are made of 2 different things: + +* Condition: + +```yaml hl_lines="2" + ADMITTED_RULE: + condition: HAS_SCHOOL_AUTHORIZED_POWER + action: set_admission + action_parameters: + value: true +``` + +* Action: + +```yaml hl_lines="3-5" + ADMITTED_RULE: + condition: HAS_SCHOOL_AUTHORIZED_POWER + action: set_admission + action_parameters: + value: true +``` + +### Condition and Action + +**Conditions** and **actions** are quite similar in terms of implementation but their goals are different. + +Both are made of a *callable object* and some *parameters*: + +* **Condition keys:** + + * *`validation_function`: name of a callable python object that returns a `bool`, we called this function the *validation function* (or *condition function*). + + * `condition_parameters`: the validation function's arguments. + +* **Action keys:** + + * `action`: name of a callable python object that returns what you want (or does what you want such as: requesting an api, sending an email, etc.), we called this function the *action function*. + + * `action_parameters`: the action function's arguments. + +!!! tip "Parameter's special syntax" + + The action and condition **arguments** can have a special syntax: + + condition_parameters: + power: input.super_power + + The string `input.super_power` is evaluated by the rules engine and it means *"fetch the key `super_power` in the input data"*. + +## Dictionary rules + +**Rules** can be configured in a YAML file but they can also be defined by a regular dictionary: + +=== "Without type hints" + + ```python + from arta import RulesEngine + + set_admission = lambda value, **kwargs: {"is_admitted": value} + + rules = { + "check_admission": { + "ADMITTED_RULE": { + "condition": lambda power: power in ["strength", "fly", "immortality"], + "condition_parameters": {"power": "input.super_power"}, + "action": set_admission, + "action_parameters": {"value": True}, + }, + "DEFAULT_RULE": { + "condition": None, + "condition_parameters": None, + "action": set_admission, + "action_parameters": {"value": False}, + }, + } + } + + input_data = { + "id": 1, + "name": "Superman", + "civilian_name": "Clark Kent", + "age": None, + "city": "Metropolis", + "language": "french", + "super_power": "fly", + "favorite_meal": "Spinach", + "secret_weakness": "Kryptonite", + "weapons": [], + } + + eng = RulesEngine(rules_dict=rules) + + result = eng.apply_rules(input_data) + + print(result) + ``` + +=== "With type hints (>=3.9)" + + ```python + from typing import Any, Callable + + from arta import RulesEngine + + set_admission: Callable = lambda value, **kwargs: {"is_admitted": value} + + rules: dict[str, Any] = { + "check_admission": { + "ADMITTED_RULE": { + "condition": lambda power: power in ["strength", "fly", "immortality"], + "condition_parameters": {"power": "input.super_power"}, + "action": set_admission, + "action_parameters": {"value": True}, + }, + "DEFAULT_RULE": { + "condition": None, + "condition_parameters": None, + "action": set_admission, + "action_parameters": {"value": False}, + }, + } + } + + input_data: dict[str, Any] = { + "id": 1, + "name": "Superman", + "civilian_name": "Clark Kent", + "age": None, + "city": "Metropolis", + "language": "french", + "super_power": "fly", + "favorite_meal": "Spinach", + "secret_weakness": "Kryptonite", + "weapons": [], + } + + eng = RulesEngine(rules_dict=rules) + + result: dict[str, Any] = eng.apply_rules(input_data) + + print(result) + ``` + +You should get: + + {'check_admission': {'is_admitted': True}} + +!!! success + Superman is admitted to the superhero school! + +Well done! By executing this code you have: + +1. Defined an **action function** (`set_admission`) +2. Defined a **rule set** (`rules`) +3. Used some **input data** (`input_data`) +4. Instanciated a **rules engine** (`RulesEngine`) +5. Applied the rules on the data and get some results (`.apply_rules()`) + +!!! note + + In the code example we used some anonymous/lambda function for simplicity but it could be regular python functions as well. + +!!! tip "YAML vs Dictionary" + **How to choose between dictionary and configuration?** - In most cases, you must choose the configuration way of defining your rules. You will improve your rules' maintainability a lot. - In some cases like proof-of-concepts or Jupyter notebook works, you will probably be happy to use straightforward dictionaries. + *In most cases, you must choose the configuration way of defining your rules.* + + You will improve your rules' maintainability a lot. + In some cases like proof-of-concepts or Jupyter notebook works, you will probably be happy with straightforward dictionaries. **Arta** has plenty more features to discover. If you want to learn more, go to the next chapter: [Advanced User Guide](parameters.md). \ No newline at end of file diff --git a/docs/pages/in_a_nutshell.md b/docs/pages/in_a_nutshell.md deleted file mode 100644 index 354379a..0000000 --- a/docs/pages/in_a_nutshell.md +++ /dev/null @@ -1,199 +0,0 @@ -## Intro - -As we already mentioned in the [Home](index.md) page: ***Arta** is a very simple python rules engine*, but what do we mean by *rules engine*? - -* **rule** : a set of different conditions that can be `True` or `False` (i.e., we say *verified* or *not verified*) triggering an action (i.e., any python callable object). -* **engine** : some code used for combining and evaluating different rules on some input data. - -## Quick example: The Superhero School :school: :superhero: - -Imagine the following use case: - -*Your are managing a superhero school and you want to use some school rules in your python app.* - -The rules are (intentionally simple): - -!!! success "Admission rules" - - If the applicant has a school authorized power then he is admitted, - - Else he is not. - -!!! example "Course selection rules" - - If he is speaking french and his age is known then he must take the "french" course, - - Else if his age is unknown (e.g., it's a very old superhero), then he must take the "senior" course, - - Else if he is not speaking french, then he must take the "international" course. - -!!! info "Send favorite meal rules" - - If he is admitted and has a prefered dish, then we send an email to the school cook with the dish name. - -## Focus on a rule - -If we focus on one rule: - -> If the applicant has a school authorized power then he is admitted, else he is not. - -Here we can identify: - -* The condition: **has a school authorized power** (only one condition) -* The triggered action: **is admitted** - -## Focus on a condition - -Let's be more precise on the following condition: - -> has a school authorized power - -If we define a list of "school authorized powers" it will be easy to verify this condition for an applicant: - -```python -authorized_powers = [ - "strength", - "fly", - "immortality", -] -``` - -## Focus on an action - -Defining the action is probably the hardest part because it means defining the rules engine output, which depends on the use of the rules' results. - -Let's focus on the following *action*: - -> he is admitted - -Let's say that in our use case, a simple dictionary *key* is used for storing the admission status: `{"is_admitted": True}` - -We previously mentioned that action are *python callable object*, so it could be a simple function as: - -```python -def set_admission(value: bool, **kwargs: Any) -> dict[str, bool]: - """Return a dictionary containing the admission result.""" - return {"is_admitted": value} -``` - -We will see later how the `value` argument is passed to this **action function**. - -## Focus on the input data - -The *rules engine* is responsible for evaluating the [configured rules](#quick-example-the-superhero-school) against some *data* (usually named *input data*). - -In our use case, the input data could be a list of applicants: - -```python -applicants = [ - { - "id": 1, - "name": "Superman", - "civilian_name": "Clark Kent", - "age": None, - "city": "Metropolis", - "language": "french", - "powers": ["strength", "fly"], - "favorite_meal": "Spinach", - "secret_weakness": "Kryptonite", - "weapons": [], - }, - { - "id": 2, - "name": "Batman", - "civilian_name": "Bruce Wayne", - "age": 33, - "city": "Gotham City", - "language": "english", - "powers": ["bank_account", "determination", "strength"], - "favorite_meal": None, - "secret_weakness": "Feel alone", - "weapons": ["Hands", "Batarang", "Batgrenade"], - }, - { - "id": 3, - "name": "Wonder Woman", - "civilian_name": "Diana Prince", - "age": 5000, - "city": "Island of Themyscira", - "language": "french", - "powers": ["strength", "greek_gods", "regeneration", "immortality"], - "favorite_meal": None, - "secret_weakness": "Lost faith in humanity", - "weapons": ["Magic lasso", "Bulletproof bracelets", "Sword", "Shield"], - }, -] -``` - -## Focus on the results - -We talked about *rules*, *conditions*, *actions* and then *input data*, it is the **rules engine** responsability to put all them together and output some results. - -To do that we need only two things: - -1. Instanciating a *rules engine* (by giving it the rules' definition). -2. Applying the rules on the *input data*. - -The first task is explained in the [User Guide](how_to.md) section as the second but if you are curious you will find a simple example below of how to apply the rules on a data set. - -Let's apply the rules on a single applicant of our data set: - -```python -from arta import RulesEngine - -eng = RulesEngine(config_path="/to/my/config/dir") # (1) - -result = eng.apply_rules(applicants[0]) - -print(result) # (2) -# { -# "admission": {"is_admitted": True}, -# "course_selection": {"course": "senior"}, -# "send_dish": True -# } -``` - -1. Many possibilites for instanciation, we will explain them later -2. Print a single result for the first applicant - -In the *rules engine* result, we have 3 outputs: - -* `"admission": {"is_admitted": True},` -* `"course_selection": {"course": "senior"},` -* `"send_dish": True` - -It's simple, each correpond to one [rule](#quick-example-the-superhero-school). - -Then we can apply the rules to all the data set (only 3 applicants): - -```python -from arta import RulesEngine - -results = {applicant["name"]: eng.apply_rules(applicant) for applicant in applicants} - -print(results) # (1) -# { -# "Superman": { -# "admission": {"is_admitted": True}, -# "course_selection": {"course": "senior"}, -# "send_dish": True}, -# "Batman": { -# "admission": {"is_admitted": True}, -# "course_selection": {"course": "international"}, -# "send_dish": False, -# }, -# "Wonder Woman": { -# "admission": {"is_admitted": True}, -# "course_selection": {"course": "french"}, -# "send_dish": False, -# } -# } -``` - -1. Print the results of all applicants - -!!! success "Human readable format of the result" - - Superman, Batman and Wonder Womam are all admitted to school. Superman to the "senior" course, Batman to the "international" course and Wonder Woman to the "french" one. An email has been sent to the cook with Superman's favorite meal 'spinach'. - -Now, if you want to learn how to configure your rules, go to the [User Guide](how_to.md) section. \ No newline at end of file diff --git a/docs/pages/index.html b/docs/pages/index.html new file mode 100644 index 0000000..f9a774a --- /dev/null +++ b/docs/pages/index.html @@ -0,0 +1,131 @@ + + + +
+ + + + + + + + + + +
+ + + + +
+ +