├── .gitignore ├── .travis.yml ├── .yamllint.yml ├── CHANGELOG.md ├── Gemfile ├── Joblint ├── Acronyms.yml ├── Benefits.yml ├── Bro.yml ├── Competitive.yml ├── Derogatory.yml ├── DevEnv.yml ├── DumbTitles.yml ├── Gendered.yml ├── Hair.yml ├── LegacyTech.yml ├── Meritocracy.yml ├── Profanity.yml ├── README.md ├── Reassure.yml ├── Sexualised.yml ├── Starter.yml ├── TechTerms.yml ├── Visionary.yml └── meta.json ├── LICENSE ├── README.md ├── features ├── rules.feature ├── steps.rb └── support │ └── aruba.rb └── fixtures └── basic ├── .vale.ini ├── fail.md ├── pass.md └── real.md /.gitignore: -------------------------------------------------------------------------------- 1 | *.gem 2 | *.rbc 3 | /.config 4 | /coverage/ 5 | /InstalledFiles 6 | /pkg/ 7 | /spec/reports/ 8 | /spec/examples.txt 9 | /test/tmp/ 10 | /test/version_tmp/ 11 | /tmp/ 12 | 13 | # Used by dotenv library to load environment variables. 14 | # .env 15 | 16 | ## Specific to RubyMotion: 17 | .dat* 18 | .repl_history 19 | build/ 20 | *.bridgesupport 21 | build-iPhoneOS/ 22 | build-iPhoneSimulator/ 23 | 24 | ## Specific to RubyMotion (use of CocoaPods): 25 | # 26 | # We recommend against adding the Pods directory to your .gitignore. However 27 | # you should judge for yourself, the pros and cons are mentioned at: 28 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 29 | # 30 | # vendor/Pods/ 31 | 32 | ## Documentation cache and generated files: 33 | /.yardoc/ 34 | /_yardoc/ 35 | /doc/ 36 | /rdoc/ 37 | 38 | ## Environment normalization: 39 | /.bundle/ 40 | /vendor/bundle 41 | /lib/bundler/man/ 42 | 43 | # for a library or gem, you might want to ignore these files since the code is 44 | # intended to run in multiple environments; otherwise, check them in: 45 | # Gemfile.lock 46 | # .ruby-version 47 | # .ruby-gemset 48 | 49 | # unless supporting rvm < 1.11.0 or doing something fancy, ignore this: 50 | .rvmrc 51 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: python 2 | cache: bundler 3 | python: 4 | - "3.6" 5 | install: 6 | # Install the latest release of Vale: 7 | - wget https://github.com/errata-ai/vale/releases/download/v2.0.0-beta.2/vale_2.0.0-beta.2_Linux_64-bit.tar.gz 8 | - mkdir bin && tar -xvzf vale_2.0.0-beta.2_Linux_64-bit.tar.gz -C bin 9 | - export PATH=./bin:"$PATH" 10 | 11 | - bundle install --jobs=3 12 | 13 | - pip install yamllint 14 | - pip install markdata 15 | - pip install pyyaml 16 | before_script: 17 | - yamllint -c '.yamllint.yml' Joblint 18 | script: 19 | - cucumber 20 | - zip -r Joblint.zip Joblint -x "*.DS_Store" 21 | deploy: 22 | provider: releases 23 | api_key: $GITHUB_TOKEN 24 | file: Joblint.zip 25 | skip_cleanup: true 26 | on: 27 | tags: true 28 | -------------------------------------------------------------------------------- /.yamllint.yml: -------------------------------------------------------------------------------- 1 | rules: 2 | # We only include a single document (without directives) in our rules, so 3 | # the extra markup is unnecessary. 4 | document-start: disable 5 | # Many rules include a `link` key that can be relatively long. 6 | # 7 | # TODO: Should we change this? 8 | line-length: disable 9 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | ## [v0.2.0](https://github.com/errata-ai/Joblint/tree/v0.2.0) (2019-07-08) 4 | [Full Changelog](https://github.com/errata-ai/Joblint/compare/v0.1.1...v0.2.0) 5 | 6 | ## [v0.1.1](https://github.com/errata-ai/Joblint/tree/v0.1.1) (2019-06-04) 7 | [Full Changelog](https://github.com/errata-ai/Joblint/compare/v0.1.0...v0.1.1) 8 | 9 | ## [v0.1.0](https://github.com/errata-ai/Joblint/tree/v0.1.0) (2019-06-03) 10 | 11 | 12 | \* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)* -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gem 'aruba', '~> 0.14.3' 4 | -------------------------------------------------------------------------------- /Joblint/Acronyms.yml: -------------------------------------------------------------------------------- 1 | extends: substitution 2 | message: Use '%s' instead of '%s' 3 | description: "Tech people know their acronyms; you come across as not very tech-savvy if you expand them." 4 | ignorecase: true 5 | level: warning 6 | action: 7 | name: replace 8 | swap: 9 | 'cascading[ -]?style[ -]?sheets': CSS 10 | 'hyper[ -]?text(?:[ -]?mark[ -]?up(?:[ -]?language)?)?': HTML 11 | -------------------------------------------------------------------------------- /Joblint/Benefits.yml: -------------------------------------------------------------------------------- 1 | extends: existence 2 | message: "Avoid using '%s'" 3 | description: "Benefits such as '%s' are not bad in themselves, but their appearance in a job post often disguises the fact that there are few real benefits to working for a company." 4 | ignorecase: true 5 | level: warning 6 | tokens: 7 | - 'ales?' 8 | - 'beers?' 9 | - 'brewskis?' 10 | - 'coffee' 11 | - '(?:foos|fuss)[ -]*ball' 12 | - 'happy[ -]*hours?' 13 | - 'keg(erator)?s?' 14 | - 'lagers?' 15 | - 'nerf[ -]*guns?' 16 | - 'ping[ -]*pong?' 17 | - 'pints?' 18 | - 'pizzas?' 19 | - 'play\\s*stations?' 20 | - 'pool[ -]*table|pool' 21 | - 'rock[ -]*walls?' 22 | - 'table[ -]*football' 23 | - 'table[ -]*tennis' 24 | - 'wiis?' 25 | - 'xbox(?:es|s)?' 26 | - 'massages?' 27 | -------------------------------------------------------------------------------- /Joblint/Bro.yml: -------------------------------------------------------------------------------- 1 | extends: existence 2 | message: "Avoid using '%s'" 3 | description: "Bro culture terminology can really reduce the number of people likely to show interest." 4 | ignorecase: true 5 | level: error 6 | tokens: 7 | - 'brogramm(?:er|ers|ing)' 8 | - 'crank' 9 | - 'crush' 10 | - 'hard[ -]*core' 11 | - 'hella' 12 | - 'mak(?:e|ing) it rain' 13 | - 'skillz' 14 | -------------------------------------------------------------------------------- /Joblint/Competitive.yml: -------------------------------------------------------------------------------- 1 | extends: existence 2 | message: "Avoid using '%s'" 3 | description: "Competition can be healthy, but for a lot of people a heavily competitive environment can be a strain." 4 | ignorecase: true 5 | level: suggestion 6 | tokens: 7 | - 'compete' 8 | - 'competition' 9 | - 'competitive' 10 | - 'cutting[ -]edge' 11 | - 'fail' 12 | - 'fore[ -]*front' 13 | - 'super[ -]*stars?' 14 | - 'the best' 15 | - 'reach the top' 16 | - 'top of .{2,8} (?:game|class)' 17 | - 'win' 18 | -------------------------------------------------------------------------------- /Joblint/Derogatory.yml: -------------------------------------------------------------------------------- 1 | extends: existence 2 | message: "Avoid using '%s'" 3 | description: "When you use '%s,' you're being discriminatory." 4 | ignorecase: true 5 | level: error 6 | tokens: 7 | - 'bia?tch(?:es)?' 8 | - 'bimbos?' 9 | - 'hoes?' 10 | - 'hunks?' 11 | - 'milfs?' 12 | - 'slags?' 13 | - 'sluts?' 14 | - 'stallions?' 15 | - 'studs?' 16 | -------------------------------------------------------------------------------- /Joblint/DevEnv.yml: -------------------------------------------------------------------------------- 1 | extends: existence 2 | message: "Don't specify a development environment unless absolutely necessary." 3 | ignorecase: true 4 | level: suggestion 5 | tokens: 6 | - 'atom' 7 | - 'bb[ -]*edit' 8 | - 'dream[ -]*weaver' 9 | - 'eclipse' 10 | - 'emacs' 11 | - 'net[ -]*beans' 12 | - 'note[ -]*pad' 13 | - 'sublime[ -]*text' 14 | - 'text[ -]*wrangler' 15 | - 'text[ -]*mate' 16 | - 'vim?' 17 | - 'visual[ -]*studio' 18 | -------------------------------------------------------------------------------- /Joblint/DumbTitles.yml: -------------------------------------------------------------------------------- 1 | extends: existence 2 | message: "Avoid using '%s'" 3 | description: "Referring to tech people as '%s' devalues the work that they do and shows a lack of respect and professionalism." 4 | ignorecase: true 5 | level: warning 6 | tokens: 7 | - 'gurus?' 8 | - 'hero(?:es|ic)?' 9 | - 'ninjas?' 10 | - 'rock[ -]*stars?' 11 | - 'super[ -]*stars?' 12 | - 'badass(?:es)?' 13 | - 'BAMF' 14 | -------------------------------------------------------------------------------- /Joblint/Gendered.yml: -------------------------------------------------------------------------------- 1 | extends: existence 2 | message: "Avoid using '%s'" 3 | description: "Use of '%s' could indicate that you're discriminating in favour of a certain gender." 4 | ignorecase: true 5 | level: error 6 | tokens: 7 | - 'boys?' 8 | - 'bros?' 9 | - 'broth(?:a|er)s?' 10 | - 'chicks?' 11 | - 'dads?' 12 | - 'dudes?' 13 | - 'fathers?' 14 | - 'females?' 15 | - 'gentlem[ae]n' 16 | - 'girls?' 17 | - 'grandfathers?' 18 | - 'grandmas?' 19 | - 'grandmothers?' 20 | - 'grandpas?' 21 | - 'gran' 22 | - 'grann(?:y|ies)' 23 | - 'guys?' 24 | - 'husbands?' 25 | - 'lad(y|ies)?' 26 | - 'm[ae]n' 27 | - 'm[ou]ms?' 28 | - 'males?' 29 | - 'momm(?:y|ies)' 30 | - 'mommas?' 31 | - 'mothers?' 32 | - 'papas?' 33 | - 'sist(?:a|er)s?' 34 | - 'wi(?:fe|ves)' 35 | - 'wom[ae]n' 36 | - he 37 | - her 38 | - him 39 | - his 40 | - she 41 | -------------------------------------------------------------------------------- /Joblint/Hair.yml: -------------------------------------------------------------------------------- 1 | extends: existence 2 | message: "Avoid using '%s'" 3 | description: "The use of '%s' indicates that you're only looking for male developers." 4 | ignorecase: true 5 | level: error 6 | tokens: 7 | - 'beard(?:ed|s|y)?' 8 | - 'grizzl(?:ed|y)' 9 | -------------------------------------------------------------------------------- /Joblint/LegacyTech.yml: -------------------------------------------------------------------------------- 1 | extends: existence 2 | message: "Avoid using '%s'" 3 | description: "Legacy technologies can reduce the number of people interested in a job." 4 | ignorecase: true 5 | level: suggestion 6 | tokens: 7 | - 'cobol' 8 | - 'cvs' 9 | - 'front[ -]*page' 10 | - 'rcs' 11 | - 'sccs' 12 | - 'source[ -]*safe' 13 | - 'vb\\s*6' 14 | - 'visual[ -]*basic\\s*6' 15 | - 'vbscript' 16 | -------------------------------------------------------------------------------- /Joblint/Meritocracy.yml: -------------------------------------------------------------------------------- 1 | extends: existence 2 | message: "Reevaluate the use of '%s'" 3 | ignorecase: true 4 | level: suggestion 5 | tokens: 6 | - 'meritocra(?:cy|cies|tic)' 7 | -------------------------------------------------------------------------------- /Joblint/Profanity.yml: -------------------------------------------------------------------------------- 1 | extends: existence 2 | message: "Remove '%s'" 3 | ignorecase: true 4 | level: warning 5 | tokens: 6 | - 'bloody' 7 | - 'bugger' 8 | - 'cunt' 9 | - 'damn' 10 | - 'fuck(?:er|ing)?' 11 | - 'piss(?:ing)?' 12 | - 'shit' 13 | - 'motherfuck(?:ers?|ing)' 14 | -------------------------------------------------------------------------------- /Joblint/README.md: -------------------------------------------------------------------------------- 1 | Based on [Joblint](https://github.com/rowanmanning/joblint). 2 | 3 | > Test tech job posts for issues with sexism, culture, expectations, and recruiter fails. 4 | 5 | ``` 6 | Copyright (c) 2015, Rowan Manning 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a copy 9 | of this software and associated documentation files (the "Software"), to deal 10 | in the Software without restriction, including without limitation the rights 11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | copies of the Software, and to permit persons to whom the Software is 13 | furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included in 16 | all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | THE SOFTWARE. 25 | ``` 26 | -------------------------------------------------------------------------------- /Joblint/Reassure.yml: -------------------------------------------------------------------------------- 1 | extends: existence 2 | message: "Avoid using '%s'" 3 | description: "Something feels off when you need to reassure someone of something that should definitely not be an issue in any workplace." 4 | ignorecase: true 5 | level: suggestion 6 | tokens: 7 | - 'drama[ -]*free' 8 | - 'stress[ -]*free' 9 | -------------------------------------------------------------------------------- /Joblint/Sexualised.yml: -------------------------------------------------------------------------------- 1 | extends: existence 2 | message: "Avoid using '%s'" 3 | description: "Terms like '%s' are often used if the person writing a post doesn't know what they are talking about." 4 | ignorecase: true 5 | level: warning 6 | tokens: 7 | - gay for 8 | - sexy 9 | - hawt 10 | - phat 11 | -------------------------------------------------------------------------------- /Joblint/Starter.yml: -------------------------------------------------------------------------------- 1 | extends: existence 2 | message: "Avoid using '%s'" 3 | description: "Terms like '%s' and others can indicate that the person writing a job post is unaware of the time and effort involved in preparing a new starter for work." 4 | ignorecase: true 5 | level: suggestion 6 | tokens: 7 | - 'hit[ -]the[ -]ground[ -]running' 8 | - 'juggle' 9 | - 'tight deadlines?' 10 | -------------------------------------------------------------------------------- /Joblint/TechTerms.yml: -------------------------------------------------------------------------------- 1 | extends: substitution 2 | message: Use '%s' instead of '%s' 3 | ignorecase: true 4 | level: error 5 | action: 6 | name: replace 7 | swap: 8 | 'java[ -]?scripts?': JavaScript 9 | ruby on rail: Ruby on Rails 10 | -------------------------------------------------------------------------------- /Joblint/Visionary.yml: -------------------------------------------------------------------------------- 1 | extends: existence 2 | message: "Avoid using '%s'" 3 | description: "Terms like '%s' often indicate that a non technical person (perhaps a CEO or stakeholder) has been involved in writing the post." 4 | ignorecase: true 5 | level: warning 6 | tokens: 7 | - 'blue[ -]*sk(?:y|ies)' 8 | - 'enlighten(?:ed|ing)?' 9 | - 'green[ -]*fields?' 10 | - 'incentivi[sz]e' 11 | - 'paradigm' 12 | - 'producti[sz]e' 13 | - 'reach(?:ed|ing)? out' 14 | - 'synerg(?:y|ize|ise)' 15 | - 'visionar(?:y|ies)' 16 | -------------------------------------------------------------------------------- /Joblint/meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "feed": "https://github.com/errata-ai/Joblint/releases.atom", 3 | "vale_version": ">=1.0.0" 4 | } 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 errata.ai 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Joblint [![Build Status](https://travis-ci.org/errata-ai/Joblint.svg?branch=master)](https://travis-ci.org/errata-ai/Joblint) ![Vale version](https://img.shields.io/badge/vale-%3E%3D%20v1.7.0-blue.svg) ![license](https://img.shields.io/github/license/mashape/apistatus.svg) 2 | 3 | > [`Joblint`](https://github.com/rowanmanning/joblint): Test tech job posts for issues with sexism, culture, expectations, and recruiter fails. 4 | 5 | This repository contains a [Vale-compatible](https://github.com/errata-ai/vale) implementation of the guidelines enforced by the `Joblint` ([LICENSE](https://github.com/rowanmanning/joblint/blob/master/LICENSE)) linter. 6 | 7 | ## Getting Started 8 | 9 | To get started, add the package to your configuration file (as shown below) and then run `vale sync`. 10 | 11 | ```ini 12 | StylesPath = styles 13 | MinAlertLevel = suggestion 14 | 15 | Packages = Joblint 16 | 17 | [*] 18 | BasedOnStyles = Joblint 19 | ``` -------------------------------------------------------------------------------- /features/rules.feature: -------------------------------------------------------------------------------- 1 | Feature: Rules 2 | 3 | Scenario: Basic test case 4 | When I test "basic" 5 | Then the output should contain exactly: 6 | """ 7 | fail.md:3:21:Joblint.Profanity:Remove 'fucking' 8 | fail.md:3:37:Joblint.TechTerms:Use 'JavaScript' instead of 'java script' 9 | fail.md:3:49:Joblint.Gendered:Avoid using 'dude' 10 | fail.md:3:76:Joblint.DumbTitles:Avoid using 'ninja' 11 | fail.md:4:19:Joblint.TechTerms:Use 'JavaScript' instead of 'javascript' 12 | fail.md:4:59:Joblint.Bro:Avoid using 'crush' 13 | fail.md:6:13:Joblint.Profanity:Remove 'damn' 14 | fail.md:6:18:Joblint.Sexualised:Avoid using 'sexy' 15 | fail.md:6:49:Joblint.LegacyTech:Avoid using 'Frontpage' 16 | fail.md:6:85:Joblint.DevEnv:Don't specify a development environment unless absolutely necessary. 17 | fail.md:6:145:Joblint.Competitive:Avoid using 'top of your game' 18 | fail.md:6:179:Joblint.Visionary:Avoid using 'enlightened' 19 | fail.md:8:69:Joblint.LegacyTech:Avoid using 'VBScript' 20 | fail.md:8:91:Joblint.Gendered:Avoid using 'He' 21 | fail.md:8:112:Joblint.Starter:Avoid using 'hit the ground running' 22 | fail.md:8:145:Joblint.Competitive:Avoid using 'cutting-edge' 23 | fail.md:8:159:Joblint.Meritocracy:Reevaluate the use of 'meritocratic' 24 | fail.md:10:24:Joblint.Benefits:Avoid using 'pool table' 25 | fail.md:10:52:Joblint.Benefits:Avoid using 'beer' 26 | fail.md:10:71:Joblint.Reassure:Avoid using 'drama-free' 27 | fail.md:10:118:Joblint.DumbTitles:Avoid using 'heroic' 28 | fail.md:13:21:Joblint.Hair:Avoid using 'beards' 29 | real.md:3:32:Joblint.TechTerms:Use 'JavaScript' instead of 'java script' 30 | real.md:3:44:Joblint.Gendered:Avoid using 'guy' 31 | real.md:4:19:Joblint.TechTerms:Use 'JavaScript' instead of 'javascript' 32 | """ 33 | -------------------------------------------------------------------------------- /features/steps.rb: -------------------------------------------------------------------------------- 1 | cmd = 'vale --output=line --sort --normalize --relative' 2 | 3 | When(/^I test "(.*)"$/) do |rule| 4 | step %(I cd to "../../fixtures/#{rule}") 5 | step %(I run `#{cmd} .`) 6 | end 7 | -------------------------------------------------------------------------------- /features/support/aruba.rb: -------------------------------------------------------------------------------- 1 | require 'aruba/cucumber' 2 | -------------------------------------------------------------------------------- /fixtures/basic/.vale.ini: -------------------------------------------------------------------------------- 1 | StylesPath = ../../ 2 | 3 | MinAlertLevel = suggestion 4 | 5 | [*.md] 6 | BasedOnStyles = Joblint 7 | -------------------------------------------------------------------------------- /fixtures/basic/fail.md: -------------------------------------------------------------------------------- 1 | Sup. 2 | 3 | We'd like to hire a fucking awesome java script dude, please. A proper web ninja! 4 | If you're good at javascript then please apply and we can crush code together! 5 | 6 | Our site is damn sexy, it was all built with MS Frontpage originally but now we use Dreamweaver mostly. It's important to us that you're at the top of your game, we want to feel enlightened whenever we read your code. 7 | 8 | We'd also like candidates to be able to turn their hand to a little VBScript if possible. He should be able to hit the ground running – we're a cutting-edge, meritocratic company so we can't afford to take on dead-weight. 9 | 10 | Our benefits include a pool table, a fully-stocked beer fridge, and a drama-free environment – we like to reward our heroic dev team properly! 11 | 12 | Call 01234567890 to apply. 13 | Candidates with rad beards get extra credit! 14 | -------------------------------------------------------------------------------- /fixtures/basic/pass.md: -------------------------------------------------------------------------------- 1 | Hi. 2 | 3 | We'd like to hire an excellent JavaScript developer, please. 4 | If you're good at JavaScript then please apply. 5 | 6 | Thank you. 7 | -------------------------------------------------------------------------------- /fixtures/basic/real.md: -------------------------------------------------------------------------------- 1 | Hi. 2 | 3 | We'd like to hire an excellent java script guy, please. 4 | If you're good at javascript then please apply. 5 | 6 | Thank you. 7 | --------------------------------------------------------------------------------