├── Procfile
├── .gitignore
├── .github
├── CONTRIBUTING.md
├── PULL_REQUEST_TEMPLATE.md
└── ISSUE_TEMPLATE
│ ├── new-pronouns.md
│ ├── feature_request.md
│ └── bug_report.md
├── resources
├── pronouns.css
├── 500.html
├── log4j.xml
├── 404.html
└── pronouns.tab
├── test
└── pronouns
│ ├── resource_test.clj
│ ├── pages_test.clj
│ └── util_test.clj
├── project.clj
├── src
└── pronouns
│ ├── config.clj
│ ├── web.clj
│ ├── util.clj
│ └── pages.clj
├── .circleci
└── config.yml
├── CODE_OF_CONDUCT.md
├── README.md
└── COPYING
/Procfile:
--------------------------------------------------------------------------------
1 | web: java $JVM_OPTS -cp target/pronouns-standalone.jar clojure.main -m pronouns.web
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | pom.xml
2 | *jar
3 | /classes/
4 | /.lein-deps-sum
5 | /.lein-failures
6 | /.lein-env
7 | /checkouts
8 | /.env
9 | /target
10 | .nrepl-port
11 |
--------------------------------------------------------------------------------
/.github/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | Please check out the following resources:
2 |
3 | * [Info For Developers](../README.md#for-developers)
4 | * [FAQ](../README.md#FAQ)
5 | * [Code of Conduct](../CODE_OF_CONDUCT.md)
6 |
--------------------------------------------------------------------------------
/resources/pronouns.css:
--------------------------------------------------------------------------------
1 | body {
2 | font-family: Futura, sans-serif;
3 | background-color: #F6CEFC;
4 | }
5 |
6 | footer {
7 | font-size: 0.8em;
8 | }
9 |
10 | .section {
11 | margin: 8px;
12 | padding: 4px 6px 4px 6px;
13 | border: 4px solid #EEEEEE;
14 | border-radius: 7px;
15 | }
16 |
17 | .examples {
18 | }
19 |
20 | .title {
21 | }
22 |
23 | .usage {
24 | }
25 |
26 | .contact {
27 | }
28 |
29 | .table {
30 | }
31 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | *Thanks for contributing! Please check the following things before submitting your PR :)*
2 |
3 | - [ ] PR message includes a link to the relevant issue(s) 💁♀️🖇️🧾
4 | - [ ] Commit messages are well-formatted
5 | (please follow [this guide](https://chris.beams.io/posts/git-commit/)) 📝📐
6 | - [ ] New features have test coverage 📋☑️☑️☑️
7 | - [ ] The app boots and pronoun pages are served correctly
8 | (try `lein ring server`) 👩💻🚀
9 |
--------------------------------------------------------------------------------
/test/pronouns/resource_test.clj:
--------------------------------------------------------------------------------
1 | (ns pronouns.resource-test
2 | (:require [pronouns.util :as util]
3 | [clojure.test :refer [deftest testing is]]))
4 |
5 | (deftest valid-pronouns-table
6 | (let [table (util/slurp-tabfile "resources/pronouns.tab")]
7 | (is table "pronouns.tab exists and is non-empty")
8 | (doseq [row table]
9 | (is (= (count row) 5)
10 | "row has five elements")
11 | (is (re-matches #".*sel(f|ves)$" (last row))
12 | "final element is reflexive"))))
13 |
--------------------------------------------------------------------------------
/resources/500.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Error
6 |
13 |
14 |
15 |
16 | Error
17 | Something went wrong. Try again, and if the problem persists
18 | please contact support.
19 |
20 |
21 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/new-pronouns.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: New pronouns
3 | about: For requesting a new set of pronouns to pronoun.is
4 | labels:
5 |
6 | ---
7 |
8 | ### Link to fully filled-out pronoun.is link of your pronouns
9 |
10 | https://pronoun.is/a/b/c/d/e
11 |
12 | ### External link showing real-world usage of these pronouns
13 |
14 | https://example.com/whatever
15 |
16 | ### Should this pronoun set be included according to the [Philosophy on pronoun inclusion](/witch-house/pronoun.is/blob/master/README.md#philosophy-on-pronoun-inclusion)?
17 |
18 | yes/no
19 |
--------------------------------------------------------------------------------
/resources/log4j.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
7 |
8 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/resources/404.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Page Not Found
6 |
13 |
14 |
15 |
16 | Page Not Found
17 | There's no page at the address you requested. If you entered it
18 | by hand, check for typos. If you followed a link or a bookmark,
19 | it may need to be updated.
20 |
21 |
22 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | labels:
5 |
6 | ---
7 | *please search the issues for duplicates and read the [FAQ](/witch-house/pronoun.is/blob/master/README.md#FAQ)
8 | before submitting a new issue :)*
9 |
10 | **Is your feature request related to a problem? Please describe.**
11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12 |
13 | **Describe the solution you'd like**
14 | A clear and concise description of what you want to happen.
15 |
16 | **Describe alternatives you've considered**
17 | A clear and concise description of any alternative solutions or features you've considered.
18 |
19 | **Additional context**
20 | Add any other context or screenshots about the feature request here.
21 |
--------------------------------------------------------------------------------
/project.clj:
--------------------------------------------------------------------------------
1 | (defproject witch-house/pronouns "1.12.0-SNAPSHOT"
2 | :description "Pronoun.is is a website for personal pronoun usage examples"
3 | :url "https://pronoun.is"
4 | :license "GNU Affero General Public License 3.0"
5 | :dependencies [[compojure "1.6.1"]
6 | [environ "1.1.0"]
7 | [hiccup "1.0.5"]
8 | [lambdaisland/ring.middleware.logger "0.5.1"]
9 | [org.clojure/clojure "1.9.0"]
10 | [ring/ring-devel "1.7.1"]
11 | [ring/ring-jetty-adapter "1.7.1"]]
12 | :min-lein-version "2.0.0"
13 | :plugins [[environ/environ.lein "0.2.1"]
14 | [lein-ring "0.9.7"]]
15 | :hooks [environ.leiningen.hooks]
16 | :uberjar-name "pronouns-standalone.jar"
17 | ;; FIXME morgan.astra <2018-11-14 Wed>
18 | ;; Is this production profile used for anything?
19 | :profiles {:production {:env {:production true}}}
20 | :ring {:handler pronouns.web/app})
21 |
--------------------------------------------------------------------------------
/test/pronouns/pages_test.clj:
--------------------------------------------------------------------------------
1 | (ns pronouns.pages-test
2 | (:require [pronouns.pages :as pages]
3 | [clojure.test :refer [deftest testing is are]]))
4 |
5 | (deftest prose-comma-list
6 | (testing "`prose-comma-list` turns a list of strings into a prose list"
7 | (are [v s] (= (pages/prose-comma-list v) s)
8 | ["foo" "bar" "baz" "bobble"] "foo, bar, baz, and bobble"
9 | ["foo" "bar" "baz"] "foo, bar, and baz"
10 | ["foo" "bar"] "foo and bar"
11 | ["foo"] "foo"
12 | [] "")))
13 |
14 | (deftest lookup-pronouns
15 | (are [pronoun-strs pronouns]
16 | (= (pages/lookup-pronouns pronoun-strs)
17 | pronouns)
18 | ["she/her"] '(["she" "her" "her" "hers" "herself"])
19 | ["she" "they"] '(["she" "her" "her" "hers" "herself"]
20 | ["they" "them" "their" "theirs" "themselves"])
21 | ["she/her" "foo/bar"] '(["she" "her" "her" "hers" "herself"])
22 | ["foo/bar"] '()
23 | ["a/b/c/d/e"] '(("a" "b" "c" "d" "e"))))
24 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | labels:
5 |
6 | ---
7 | *please search the issues for duplicates and read the [FAQ](/witch-house/pronoun.is/blob/master/README.md#FAQ)
8 | before submitting a new issue :)*
9 |
10 |
11 | **Describe the bug**
12 | A clear and concise description of what the bug is.
13 |
14 | **To Reproduce**
15 | Steps to reproduce the behavior:
16 | 1. Go to '...'
17 | 2. Click on '....'
18 | 3. Scroll down to '....'
19 | 4. See error
20 |
21 | **Expected behavior**
22 | A clear and concise description of what you expected to happen.
23 |
24 | **Screenshots**
25 | If applicable, add screenshots to help explain your problem.
26 |
27 | **Desktop (please complete the following information):**
28 | - OS: [e.g. iOS]
29 | - Browser [e.g. chrome, safari]
30 | - Version [e.g. 22]
31 |
32 | **Smartphone (please complete the following information):**
33 | - Device: [e.g. iPhone6]
34 | - OS: [e.g. iOS8.1]
35 | - Browser [e.g. stock browser, safari]
36 | - Version [e.g. 22]
37 |
38 | **Additional context**
39 | Add any other context about the problem here.
40 |
--------------------------------------------------------------------------------
/src/pronouns/config.clj:
--------------------------------------------------------------------------------
1 | ;; pronoun.is - a website for pronoun usage examples
2 | ;; Copyright (C) 2014 - 2018 Morgan Astra
3 |
4 | ;; This program is free software: you can redistribute it and/or modify
5 | ;; it under the terms of the GNU Affero General Public License as
6 | ;; published by the Free Software Foundation, either version 3 of the
7 | ;; License, or (at your option) any later version.
8 |
9 | ;; This program is distributed in the hope that it will be useful,
10 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | ;; GNU Affero General Public License for more details.
13 |
14 | ;; You should have received a copy of the GNU Affero General Public License
15 | ;; along with this program. If not, see
16 |
17 | (ns pronouns.config
18 | (:require [pronouns.util :as u]))
19 |
20 | (def pronouns-table
21 | (atom (u/slurp-tabfile "resources/pronouns.tab")))
22 |
23 | (defn replace-value [old new] new)
24 |
25 | (defn reload-table! []
26 | (swap! pronouns-table
27 | replace-value
28 | (u/slurp-tabfile "resources/pronouns.tab")))
29 |
30 |
--------------------------------------------------------------------------------
/resources/pronouns.tab:
--------------------------------------------------------------------------------
1 | she her her hers herself
2 | he him his his himself
3 | they them their theirs themselves
4 | ze hir hir hirs hirself
5 | ze zir zir zirs zirself
6 | xey xem xyr xyrs xemself
7 | ae aer aer aers aerself
8 | e em eir eirs emself
9 | ey em eir eirs eirself
10 | fae faer faer faers faerself
11 | fey fem feir feirs feirself
12 | hu hum hus hus humself
13 | it it its its itself
14 | jee jem jeir jeirs jemself
15 | kit kit kits kits kitself
16 | ne nem nir nirs nemself
17 | peh pehm peh's peh's pehself
18 | per per per pers perself
19 | sie hir hir hirs hirself
20 | se sim ser sers serself
21 | shi hir hir hirs hirself
22 | si hyr hyr hyrs hyrself
23 | they them their theirs themself
24 | thon thon thons thons thonself
25 | ve ver vis vis verself
26 | ve vem vir virs vemself
27 | vi ver ver vers verself
28 | vi vim vir virs vimself
29 | vi vim vim vims vimself
30 | xie xer xer xers xerself
31 | xe xem xyr xyrs xemself
32 | xey xem xeir xeirs xemself
33 | yo yo yos yos yosself
34 | ze zem zes zes zirself
35 | ze mer zer zers zemself
36 | zee zed zeta zetas zedself
37 | zie zir zir zirs zirself
38 | zie zem zes zes zirself
39 | zie hir hir hirs hirself
40 | zme zmyr zmyr zmyrs zmyrself
41 |
--------------------------------------------------------------------------------
/.circleci/config.yml:
--------------------------------------------------------------------------------
1 | # Clojure CircleCI 2.0 configuration file
2 | #
3 | # Check https://circleci.com/docs/2.0/language-clojure/ for more details
4 | #
5 | version: 2
6 | jobs:
7 | build:
8 | docker:
9 | # specify the version you desire here
10 | - image: circleci/clojure:lein-2.7.1
11 |
12 | # Specify service dependencies here if necessary
13 | # CircleCI maintains a library of pre-built images
14 | # documented at https://circleci.com/docs/2.0/circleci-images/
15 | # - image: circleci/postgres:9.4
16 |
17 | working_directory: ~/repo
18 |
19 | environment:
20 | LEIN_ROOT: "true"
21 | # Customize the JVM maximum heap limit
22 | JVM_OPTS: -Xmx3200m
23 |
24 | steps:
25 | - checkout
26 |
27 | # Download and cache dependencies
28 | - restore_cache:
29 | keys:
30 | - v1-dependencies-{{ checksum "project.clj" }}
31 | # fallback to using the latest cache if no exact match is found
32 | - v1-dependencies-
33 |
34 | - run: lein deps
35 |
36 | - save_cache:
37 | paths:
38 | - ~/.m2
39 | key: v1-dependencies-{{ checksum "project.clj" }}
40 |
41 | # run tests!
42 | - run: lein test
43 |
--------------------------------------------------------------------------------
/test/pronouns/util_test.clj:
--------------------------------------------------------------------------------
1 | (ns pronouns.util-test
2 | (:require [pronouns.util :as util]
3 | [clojure.test :refer [deftest testing is are]]))
4 |
5 | (def test-table [["ze" "hir" "hir" "hirs" "hirself"]
6 | ["ze" "zir" "zir" "zirs" "zirself"]
7 | ["she" "her" "her" "hers" "herself"]
8 | ["he" "him" "his" "his" "himself"]
9 | ["they" "them" "their" "theirs" "themselves"]
10 | ["they" "them" "their" "theirs" "themself"]])
11 |
12 | (deftest table-filters
13 | (testing "table-front-filter"
14 | (are [arg return] (= (util/table-front-filter arg test-table) return)
15 | ["she"] [["she" "her" "her" "hers" "herself"]]
16 | ["ze"] [["ze" "hir" "hir" "hirs" "hirself"]
17 | ["ze" "zir" "zir" "zirs" "zirself"]]
18 | ["ze" "zir"] [["ze" "zir" "zir" "zirs" "zirself"]]))
19 |
20 | (testing "table-end-filter"
21 | (are [arg return] (= (util/table-end-filter arg test-table) return)
22 | ["themself"] [["they" "them" "their" "theirs" "themself"]]
23 | ["themselves"] [["they" "them" "their" "theirs" "themselves"]])))
24 |
25 | (deftest table-lookup
26 | (are [arg return] (= (util/table-lookup arg test-table) return)
27 | ["she"] ["she" "her" "her" "hers" "herself"]
28 | ["ze"] ["ze" "hir" "hir" "hirs" "hirself"]
29 | ["ze" "zir"] ["ze" "zir" "zir" "zirs" "zirself"]
30 | ["they"] ["they" "them" "their" "theirs" "themselves"]
31 | ["they" "..." "themself"] ["they" "them" "their" "theirs" "themself"]))
32 |
33 |
--------------------------------------------------------------------------------
/src/pronouns/web.clj:
--------------------------------------------------------------------------------
1 | ;; pronoun.is - a website for pronoun usage examples
2 | ;; Copyright (C) 2014 - 2018 Morgan Astra
3 |
4 | ;; This program is free software: you can redistribute it and/or modify
5 | ;; it under the terms of the GNU Affero General Public License as
6 | ;; published by the Free Software Foundation, either version 3 of the
7 | ;; License, or (at your option) any later version.
8 |
9 | ;; This program is distributed in the hope that it will be useful,
10 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | ;; GNU Affero General Public License for more details.
13 |
14 | ;; You should have received a copy of the GNU Affero General Public License
15 | ;; along with this program. If not, see
16 |
17 | (ns pronouns.web
18 | (:require [compojure.core :refer [defroutes GET PUT POST DELETE ANY]]
19 | [compojure.handler :refer [site]]
20 | [compojure.route :as route]
21 | [clojure.string :as s]
22 | [clojure.java.io :as io]
23 | [ring.adapter.jetty :as jetty]
24 | [ring.middleware.logger :as logger]
25 | [ring.middleware.stacktrace :as trace]
26 | [ring.middleware.params :as params]
27 | [ring.middleware.resource :refer [wrap-resource]]
28 | [ring.middleware.content-type :refer [wrap-content-type]]
29 | [ring.middleware.not-modified :refer [wrap-not-modified]]
30 | [environ.core :refer [env]]
31 | [pronouns.util :as u]
32 | [pronouns.pages :as pages]))
33 |
34 | (defroutes app-routes
35 | (GET "/" []
36 | {:status 200
37 | :headers {"Content-Type" "text/html"}
38 | :body (pages/front)})
39 |
40 | (GET "/all-pronouns" []
41 | {:status 200
42 | :headers {"Content-Type" "text/html"}
43 | :body (pages/all-pronouns)})
44 |
45 | (GET "/pronouns.css" []
46 | {:status 200
47 | :headers {"Content-Type" "text/css"}
48 | :body (slurp (io/resource "pronouns.css"))})
49 |
50 | (GET "/*" {params :params}
51 | {:status 200
52 | :headers {"Content-Type" "text/html"}
53 | :body (pages/pronouns params)})
54 |
55 | (ANY "*" []
56 | (route/not-found (slurp (io/resource "404.html")))))
57 |
58 | (defn wrap-gnu-natalie-nguyen [handler]
59 | (fn [req]
60 | (when-let [resp (handler req)]
61 | (assoc-in resp [:headers "X-Clacks-Overhead"] "GNU Natalie Nguyen"))))
62 |
63 | (defn wrap-error-page [handler]
64 | (fn [req]
65 | (try (handler req)
66 | (catch Exception e
67 | (binding [*out* *err*]
68 | {:status 500
69 | :headers {"Content-Type" "text/html"}
70 | :body (slurp (io/resource "500.html"))})))))
71 |
72 | (def app
73 | (-> app-routes
74 | ;; FIXME morgan.astra <2018-11-14 Wed>
75 | ;; use this resource or delete it
76 | ;; (wrap-resource "images")
77 | wrap-content-type
78 | wrap-not-modified
79 | logger/wrap-with-logger
80 | wrap-error-page
81 | wrap-gnu-natalie-nguyen
82 | trace/wrap-stacktrace
83 | params/wrap-params))
84 |
85 | (defn -main []
86 | (let [port (Integer. (:port env))]
87 | (jetty/run-jetty app {:port port})))
88 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as
6 | contributors and maintainers pledge to making participation in our project and
7 | our community a harassment-free experience for everyone, regardless of age, body
8 | size, disability, ethnicity, sex characteristics, gender identity and expression,
9 | level of experience, education, socio-economic status, nationality, personal
10 | appearance, race, religion, or sexual identity and orientation.
11 |
12 | ## Our Standards
13 |
14 | Examples of behavior that contributes to creating a positive environment
15 | include:
16 |
17 | * Using welcoming and inclusive language
18 | * Being respectful of differing viewpoints and experiences
19 | * Gracefully accepting constructive criticism
20 | * Focusing on what is best for the community
21 | * Showing empathy towards other community members
22 |
23 | Examples of unacceptable behavior by participants include:
24 |
25 | * The use of sexualized language or imagery and unwelcome sexual attention or
26 | advances
27 | * Trolling, insulting/derogatory comments, and personal or political attacks
28 | * Public or private harassment
29 | * Publishing others' private information, such as a physical or electronic
30 | address, without explicit permission
31 | * Other conduct which could reasonably be considered inappropriate in a
32 | professional setting
33 |
34 | ## Our Responsibilities
35 |
36 | Project maintainers are responsible for clarifying the standards of acceptable
37 | behavior and are expected to take appropriate and fair corrective action in
38 | response to any instances of unacceptable behavior.
39 |
40 | Project maintainers have the right and responsibility to remove, edit, or
41 | reject comments, commits, code, wiki edits, issues, and other contributions
42 | that are not aligned to this Code of Conduct, or to ban temporarily or
43 | permanently any contributor for other behaviors that they deem inappropriate,
44 | threatening, offensive, or harmful.
45 |
46 | ## Scope
47 |
48 | This Code of Conduct applies both within project spaces and in public spaces
49 | when an individual is representing the project or its community. Examples of
50 | representing a project or community include using an official project e-mail
51 | address, posting via an official social media account, or acting as an appointed
52 | representative at an online or offline event. Representation of a project may be
53 | further defined and clarified by project maintainers.
54 |
55 | ## Enforcement
56 |
57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
58 | reported by contacting the project maintainer, @morganastra. All
59 | complaints will be reviewed and investigated and will result in a response that
60 | is deemed necessary and appropriate to the circumstances. The project team is
61 | obligated to maintain confidentiality with regard to the reporter of an incident.
62 | Further details of specific enforcement policies may be posted separately.
63 |
64 | Project maintainers who do not follow or enforce the Code of Conduct in good
65 | faith may face temporary or permanent repercussions as determined by other
66 | members of the project's leadership.
67 |
68 | ## Attribution
69 |
70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
72 |
73 | [homepage]: https://www.contributor-covenant.org
74 |
75 | For answers to common questions about this code of conduct, see
76 | https://www.contributor-covenant.org/faq
77 |
--------------------------------------------------------------------------------
/src/pronouns/util.clj:
--------------------------------------------------------------------------------
1 | ;; pronoun.is - a website for pronoun usage examples
2 | ;; Copyright (C) 2014 - 2018 Morgan Astra
3 |
4 | ;; This program is free software: you can redistribute it and/or modify
5 | ;; it under the terms of the GNU Affero General Public License as
6 | ;; published by the Free Software Foundation, either version 3 of the
7 | ;; License, or (at your option) any later version.
8 |
9 | ;; This program is distributed in the hope that it will be useful,
10 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | ;; GNU Affero General Public License for more details.
13 |
14 | ;; You should have received a copy of the GNU Affero General Public License
15 | ;; along with this program. If not, see
16 |
17 | (ns pronouns.util
18 | (:require [clojure.string :as s]))
19 |
20 | (defn slurp-tabfile
21 | "Read a tabfile from a filesystem as a table"
22 | [path]
23 | (let [lines (s/split (slurp path) #"\n")]
24 | (map #(s/split % #"\t") lines)))
25 |
26 | (defn table-front-filter
27 | "filter a to the rows which begin with "
28 | [query-key table]
29 | (let [arity (count query-key)]
30 | (filter #(= query-key (take arity %)) table)))
31 |
32 | (defn table-end-filter
33 | "filter a to the rows which end with "
34 | [query-key table]
35 | (let [table-arity (count (first table))
36 | query-arity (count query-key)]
37 | (filter #(= query-key (drop (- table-arity query-arity) %)) table)))
38 |
39 | (defn table-lookup
40 | "find the row corresponding to in "
41 | [query-key table]
42 | (if (some #(= "..." %) query-key)
43 | (let [[query-front query-end-] (split-with #(not= "..." %) query-key)
44 | query-end (drop 1 query-end-)
45 | front-matches (table-front-filter query-front table)]
46 | (first (table-end-filter query-end front-matches)))
47 | (first (table-front-filter query-key table))))
48 |
49 | (defn shortest-unambiguous-forward-path
50 | "Compute the shortest (in number of path elements) forward path which
51 | unambiguously refers to a specific in a . The behavior of
52 | this function is undefined if given a that is not in the .
53 |
54 | See also: shortest-unambiguous-path"
55 | [table row]
56 | (loop [n 1]
57 | (let [row-front (take n row)]
58 | (if (>= 1 (count (table-front-filter row-front table)))
59 | row-front
60 | (recur (inc n))))))
61 |
62 | (defn shortest-unambiguous-ellipses-path
63 | "Compute the shortest (in number of path elements) ellipses path which
64 | unambiguously refers to a specific in a . The behavior of
65 | this function is undefined if given a that is not in the .
66 |
67 | See also: shortest-unambiguous-path"
68 | [table row]
69 | (let [row-end (last row)
70 | filtered-table (table-end-filter [row-end] table)]
71 | (loop [n 1]
72 | (let [row-front (take n row)]
73 | (if (>= 1 (count (table-front-filter row-front filtered-table)))
74 | (concat row-front ["..." row-end])
75 | (recur (inc n)))))))
76 |
77 | (defn shortest-unambiguous-path
78 | "Compute the shortest (in number of path elements) path which unambiguously
79 | refers to a specific in a . The behavior of this function is
80 | undefined if given a that is not in the .
81 |
82 | A path can either be a 'forward path', in which it specifies the row with
83 | elements from the front (e.g. ze/zir), or an 'ellipses path', which elides
84 | unnecessary elements from the middle (e.g. they/.../themselves). If the
85 | shortest forward and ellipses paths are the same length, prefer the forward
86 | path"
87 | [table row]
88 | (let [forward-path (shortest-unambiguous-forward-path table row)
89 | ellipses-path (shortest-unambiguous-ellipses-path table row)]
90 | (s/join "/"
91 | (if (> (count forward-path) (count ellipses-path))
92 | ellipses-path
93 | forward-path))))
94 |
95 | (defn abbreviate
96 | "return the list of minimum unabiguous paths from a "
97 | [table]
98 | (map (partial shortest-unambiguous-path table) table))
99 |
100 | (defn vec-coerce
101 | "wrap a value in a vector if it is not already in one. note that if
102 | is already in a sequence for which vector? is false, this will add
103 | another layer of nesting."
104 | [x]
105 | (if (vector? x) x [x]))
106 |
107 | (defn strip-markup [form]
108 | (s/join " " (filter string? (flatten form))))
109 |
110 |
--------------------------------------------------------------------------------
/src/pronouns/pages.clj:
--------------------------------------------------------------------------------
1 | ;; pronoun.is - a website for pronoun usage examples
2 | ;; Copyright (C) 2014 - 2018 Morgan Astra
3 |
4 | ;; This program is free software: you can redistribute it and/or modify
5 | ;; it under the terms of the GNU Affero General Public License as
6 | ;; published by the Free Software Foundation, either version 3 of the
7 | ;; License, or (at your option) any later version.
8 |
9 | ;; This program is distributed in the hope that it will be useful,
10 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | ;; GNU Affero General Public License for more details.
13 |
14 | ;; You should have received a copy of the GNU Affero General Public License
15 | ;; along with this program. If not, see
16 |
17 | (ns pronouns.pages
18 | (:require [clojure.string :as s]
19 | [pronouns.config :refer [pronouns-table]]
20 | [pronouns.util :as u]
21 | [hiccup.core :refer :all]
22 | [hiccup.element :as e]
23 | [hiccup.util :refer [escape-html]]))
24 |
25 | (defn prose-comma-list
26 | [items]
27 | (let [c (count items)]
28 | (cond
29 | (<= c 1) (or (first items) "")
30 | (= c 2) (s/join " and " items)
31 | :else (str (s/join ", " (butlast items)) ", and " (last items)))))
32 |
33 | (defn href
34 | [url text]
35 | [:a {:href url} text])
36 |
37 | ;; FIXME morgan.astra <2018-11-14 Wed>
38 | ;; use a div for this instead of a plain bold tag
39 | (defn wrap-pronoun
40 | [pronoun]
41 | [:b pronoun])
42 |
43 | (defn render-sentence [& content]
44 | [:p [:span.sentence content]])
45 |
46 | (defn subject-example
47 | [subject]
48 | (render-sentence (wrap-pronoun (s/capitalize subject)) " went to the park."))
49 |
50 | (defn object-example
51 | [object]
52 | (render-sentence "I went with " (wrap-pronoun object) "."))
53 |
54 | (defn posessive-determiner-example
55 | [subject possessive-determiner]
56 | (render-sentence (wrap-pronoun (s/capitalize subject))
57 | " brought "
58 | (wrap-pronoun possessive-determiner)
59 | " frisbee."))
60 |
61 | (defn possessive-pronoun-example
62 | [possessive-pronoun]
63 | (render-sentence "At least I think it was "
64 | (wrap-pronoun possessive-pronoun)
65 | "."))
66 |
67 | (defn reflexive-example
68 | [subject reflexive]
69 | (render-sentence (wrap-pronoun (s/capitalize subject))
70 | " threw the frisbee to "
71 | (wrap-pronoun reflexive)
72 | "."))
73 |
74 | (defn header-block [header]
75 | [:div {:class "section title"}
76 | (href "/" [:h1 header])])
77 |
78 | (defn examples-block
79 | [subject object possessive-determiner possessive-pronoun reflexive]
80 | (let [sub-obj (s/join "/" [subject object])
81 | header-str (str "Here are some example sentences using my "
82 | sub-obj
83 | " pronouns:")]
84 | [:div {:class "section examples"}
85 | [:h2 header-str]
86 | [:p (subject-example subject)
87 | (object-example object)
88 | (posessive-determiner-example subject possessive-determiner)
89 | (possessive-pronoun-example possessive-pronoun)
90 | (reflexive-example subject reflexive)]]))
91 |
92 | (defn usage-block []
93 | [:div {:class "section usage"}
94 | [:p "Full usage: "
95 | ;; FIXME morgan.astra <2018-11-14 Wed>
96 | ;; This looks really ugly in the browser
97 | [:tt "https://pronoun.is/subject-pronoun/object-pronoun/possessive-determiner/possessive-pronoun/reflexive"]
98 | " displays examples of your pronouns."]
99 | [:p "This is a bit unwieldy. If we have a good guess we'll let you use"
100 | " just the first one or two."]])
101 |
102 | (defn contact-block []
103 | (let [twitter-name (fn [handle] (href (str "https://www.twitter.com/" handle)
104 | (str "@" handle)))]
105 | [:div {:class "section contact"}
106 | [:p "Written by "
107 | (twitter-name "morganastra")
108 | ", whose "
109 | (href "https://pronoun.is/she" "pronoun.is/she")]
110 | [:p "pronoun.is is free software under the "
111 | (href "https://www.gnu.org/licenses/agpl.html" "AGPLv3")
112 | "! visit the project on "
113 | (href "https://github.com/witch-house/pronoun.is" "github")]
114 | [:p "<3"]]))
115 |
116 | (defn footer-block []
117 | [:footer (usage-block) (contact-block)])
118 |
119 | (defn format-pronoun-examples
120 | [pronoun-declensions]
121 | (let [sub-objs (map #(s/join "/" (take 2 %)) pronoun-declensions)
122 | title (str "Pronoun Island: " (prose-comma-list sub-objs) " examples")
123 | examples (map #(apply examples-block %) pronoun-declensions)]
124 | (html
125 | [:html
126 | [:head
127 | [:title title]
128 | [:meta {:name "viewport" :content "width=device-width"}]
129 | [:meta {:charset "utf-8"}]
130 | [:meta {:name "description" :content (u/strip-markup examples)}]
131 | [:meta {:name "twitter:card" :content "summary"}]
132 | [:meta {:name "twitter:title" :content title}]
133 | [:meta {:name "twitter:description" :content (u/strip-markup examples)}]
134 | [:link {:rel "stylesheet" :href "/pronouns.css"}]]
135 | [:body
136 | (header-block title)
137 | examples
138 | (footer-block)]])))
139 |
140 | (defn table-lookup* [pronouns-string]
141 | (let [inputs (s/split pronouns-string #"/")
142 | n (count inputs)]
143 | (if (>= n 5)
144 | (take 5 inputs)
145 | (u/table-lookup inputs @pronouns-table))))
146 |
147 | (defn lookup-pronouns
148 | "Given a seq of pronoun sets, look up each set in the pronouns table"
149 | [pronoun-sets]
150 | (->> pronoun-sets
151 | (map (comp table-lookup* escape-html))
152 | (filter some?)))
153 |
154 | (defn make-link [path]
155 | (let [link (str "/" path)
156 | label path]
157 | [:li (href link label)]))
158 |
159 | (defn front []
160 | (let [abbreviations (take 6 (u/abbreviate @pronouns-table))
161 | links (map make-link abbreviations)
162 | title "Pronoun Island"
163 | description "Pronoun.is is a website for personal pronoun usage examples."]
164 | (html
165 | [:html
166 | [:head
167 | [:title title]
168 | [:meta {:name "description" :content description}]
169 | [:meta {:name "twitter:card" :content "summary"}]
170 | [:meta {:name "twitter:title" :content title}]
171 | [:meta {:name "twitter:description" :content description}]
172 | [:meta {:name "viewport" :content "width=device-width"}]
173 | [:meta {:charset "utf-8"}]
174 | [:link {:rel "stylesheet" :href "/pronouns.css"}]]
175 | [:body
176 | (header-block title)
177 | [:div {:class "section table"}
178 | [:p "pronoun.is is a website for personal pronoun usage examples"]
179 | [:p "here are some pronouns the site knows about:"]
180 | [:ul links]
181 | [:p [:small (href "all-pronouns" "see all pronouns in the database")]]]]
182 | (footer-block)])))
183 |
184 | (defn all-pronouns []
185 | (let [abbreviations (u/abbreviate @pronouns-table)
186 | links (map make-link abbreviations)
187 | title "Pronoun Island"]
188 | (html
189 | [:html
190 | [:head
191 | [:title title]
192 | [:meta {:name "viewport" :content "width=device-width"}]
193 | [:meta {:charset "utf-8"}]
194 | [:link {:rel "stylesheet" :href "/pronouns.css"}]]
195 | [:body
196 | (header-block title)
197 | [:div {:class "section table"}
198 | [:p "All pronouns the site knows about:"]
199 | [:ul links]]]
200 | (footer-block)])))
201 |
202 | (defn not-found [path]
203 | (let [title "Pronoun Island: English Language Examples"
204 | or-re #"/[oO][rR]/"]
205 | (html
206 | [:html
207 | [:head
208 | [:title title]
209 | [:meta {:name "viewport" :content "width=device-width"}]
210 | [:meta {:charset "utf-8"}]
211 | [:link {:rel "stylesheet" :href "/pronouns.css"}]]
212 | [:body
213 | (header-block title)
214 | [:div {:class "section examples"}
215 | [:p [:h2 "We couldn't find those pronouns in our database :("]
216 | "If you think we should have them, please reach out!"]
217 | (when (re-find or-re path)
218 | (let [alts (s/split path or-re)
219 | new-path (str "/" (s/join "/:OR/" alts))]
220 | [:div
221 | "Did you mean: "
222 | (href new-path
223 | (str "pronoun.is"
224 | new-path))]))]
225 | (footer-block)]])))
226 |
227 | (defn pronouns [params]
228 | (let [path (params :*)
229 | param-alts (u/vec-coerce (or (params "or") []))
230 | path-alts (s/split path #"/:[oO][rR]/")
231 | pronouns (lookup-pronouns (concat path-alts param-alts))]
232 | (if (seq pronouns)
233 | (format-pronoun-examples pronouns)
234 | (not-found path))))
235 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # pronoun.is
2 |
3 | [pronoun.is](https://pronoun.is) is a website for personal pronoun usage examples
4 |
5 |
6 | **Table of Contents**
7 |
8 | - [pronoun.is](#pronounis)
9 | - [For users](#for-users)
10 | - [For developers](#for-developers)
11 | - [The database](#the-database)
12 | - [The code](#the-code)
13 | - [Tests](#tests)
14 | - [Running the app in a dev environment](#running-the-app-in-a-dev-environment)
15 | - [The git repo](#the-git-repo)
16 | - [Philosophy on pronoun inclusion](#philosophy-on-pronoun-inclusion)
17 | - [FAQ](#faq)
18 | - [Can we translate pronoun.is into another language?](#can-we-translate-pronounis-into-another-language)
19 | - [Can we change the example sentences?](#can-we-change-the-example-sentences)
20 | - [Can we add pronunciation guides?](#can-we-add-pronunciation-guides)
21 | - [Can we add pluralization support (i.e. themself vs themselves)](#can-we-add-pluralization-support-ie-themself-vs-themselves)
22 | - [License](#license)
23 |
24 |
25 |
26 |
27 | ## For users
28 |
29 | You can use any pronouns you like simply by filling them into the
30 | url path. For example, https://pronoun.is/ze/zir/zir/zirs/zirself
31 |
32 | That's pretty unwieldy! Fortunately you can also give it only the
33 | first pronoun or two: https://pronoun.is/she/her or https://pronoun.is/they
34 |
35 | Automatically filling in the rest from only one or two forms only
36 | works for pronouns in the [database][pronoun-database]. If the
37 | pronouns you or a friend uses aren't supported, please let us know and
38 | we'll add them. Alternatively you could add them yourself and submit a
39 | pull request (see the next section for details)
40 |
41 | ## For developers
42 |
43 | ### The database
44 |
45 | The pronouns "database" is a tab-delimited file located in [resources/pronouns.tab][pronoun-database] with fields and example values as follows:
46 |
47 | subject|object|possessive-determiner|possessive-pronoun|reflexive
48 | -------|------|---------------------|------------------|---------
49 | they | them | their | theirs | themselves
50 |
51 | The top 6 pronouns are displayed on the front page. Please don't edit these
52 | without talking to me, they've been hand-curated based on usage frequency.
53 | Below the top 6, the remaining pronouns are sorted in alphabetical order by
54 | subject and then in roughly frequency order for sets that have the same subject
55 | pronoun. If you're adding a set that shares the same object pronoun as other
56 | set(s) already in the database, please insert it immediately below those ones.
57 |
58 | If you edit the database with a text editor, make sure your editor inputs real
59 | tab characters in that file (a thing your editor might normally be configured
60 | not to do!) In Emacs, you can input real tabs by doing Ctrl+q .
61 | In Vi you can use Ctrl+v .
62 |
63 | [pronoun-database]: resources/pronouns.tab
64 |
65 | ### The code
66 |
67 | The top-level logic for running the server lives in [`pronouns.web`](src/pronouns/web.clj)
68 |
69 | Page rendering markup is in [`pronouns.pages`](src/pronouns/pages.clj), it uses
70 | [hiccup](https://github.com/weavejester/hiccup) for rendering HTML from Clojure
71 | datastructures.
72 |
73 | [`pronouns.config`](src/pronouns/config.clj) is currently used only for loading
74 | the [pronouns database][pronoun-database]
75 |
76 | The unfortunately-named [`pronouns.util`](src/pronouns/util.clj) includes both
77 | actual utility functions used elsewhere in the code, but also what you might
78 | think of as "controllers" if you're used to the MVC model of web design - code
79 | that does the computations necessary for the `pages` (analogous to "views")
80 | to render themselves. We should probably break up `util` into (at least) two
81 | namespaces and be a little more deliberate about where everything currently
82 | in that namespace should live!
83 |
84 | ### Tests
85 |
86 | Run the suite with `lein test`
87 |
88 | Test coverage is not great but getting better. Please run the tests and
89 | confirm that everything passes before merging changes, and please include
90 | tests with any new logic you introduce in a PR!
91 |
92 | Goals for the future include setting up automated CI to run the tests for
93 | us on every PR branch
94 |
95 | ### Running the app in a dev environment
96 |
97 | First, install [leiningen](https://leiningen.org/). Then you can launch the app
98 | on your own computer by running the following command:
99 |
100 | ```
101 | $ lein ring server
102 | ```
103 |
104 | This will launch a server running the app and open your default web browser to
105 | the index page. The server will automatically reload files as you edit them -
106 | with the unfortunate exception of `pronouns.tab`, which is loaded as a resource
107 | and requires an app restart to reload.
108 |
109 | ### The git repo
110 |
111 | For most of this project's history we had separate `master` and `develop`
112 | branches but that's proven to be more trouble than it's worth. Going
113 | forward we'll be doing all development in feature branches off of `master`,
114 | and PRs should be issued against `master`.
115 |
116 | Please follow [this guide](https://chris.beams.io/posts/git-commit/)
117 | for writing good commit messages :)
118 |
119 | ## Philosophy on pronoun inclusion
120 |
121 | Pronoun.is aims foremost and exclusively to be a useful resource for people to communicate the personal pronoun they use for themselves.
122 |
123 | It is possible to use these example sentences to demonstrate the usage of words that are not personal pronouns, or even cleverly insert an [entire story](https://pronoun.is/she/or%20they,%20those%20ships%20who%20were%20docked%20and%20still%20equipped%20with%20ancillaries,%20arranged%20to%20share%20the%20duty%20of%20monitoring%20our%20guest%20as%20it%20fit%20into%20their%20routines;%20that%20was%20the%20agreement,%20despite%20it%20being%20less%20convenient%20for%20me%20to%20participate%20at%20all,%20on%20the%20grounds%20that%20certain%20visitors%20might%20prefer%20a%20constant%20individual%20companion%20to%20what%20might%20seem,%20depending%20on%20their%20past%20experiences,%20to%20be%20undue%20attention%20from%20every%20soldier%20they%20passed.%20As%20usual,%20then,%20I%20took%20the%20first%20shift/the%20one%20possession%20of%20hers%20that%20Station%20Security%20hadn't%20confiscated,%20a/knowingly%20left%20with%20her.%20What%20a%20Presger%20frisbee%20might%20do%20or%20even%20look%20like%20I%20couldn't%20say.%20She%20hadn't%20seemed%20the%20sort%20to%20have%20alien%20technology,%20but,%20then%20again,%20neither%20had%20I/another%20unremarkable%20stranger,%20quite%20a%20ways%20down%20the%20concourse,%20who%20caught%20it%20with%20a%20degree%20of%20coordination%20that%20most%20would%20have%20overlooked.%20It%20did%20not%20escape%20my%20notice,%20however.%20"Cousin,"%20I%20said,%20enough%20to%20convey%20-%20unless%20our%20visitor%20were%20quite%20ignorant,%20but,%20of%20course,%20at%20this%20point%20I%20was%20certain%20that%20she%20couldn't%20be%20-%20both%20that%20I%20knew%20what%20she%20was%20not%20and%20that%20I%20was%20giving%20her%20the%20benefit%20of%20the%20doubt%20as%20to%20what,%20or%20who,%20she%20was)! However, as a policy we will not include such entries in the database.
124 |
125 |
126 | ## FAQ
127 |
128 | ### Can we translate pronoun.is into another language?
129 |
130 | I'd love to see pronoun.is-like apps exist in the world for other languages.
131 | I'll answer any questions you need answered if you decide to fork the code to
132 | create a similar site for a different language, and I'll also entertain the
133 | idea of patching the pronoun.is codebase to support rending pages in different
134 | languages as long as it doesn't make the code substantially more complicated.
135 |
136 | Even if we add I18N support to the code, other language versions of the site
137 | should have their own domains names (ideally with clever TLD puns like
138 | pronoun.is has for english!)
139 |
140 | (This was discussed in issues #13, #14, and #66)
141 |
142 | ### Can we change the example sentences?
143 |
144 | Probably not, sorry, I really like these ones! Maybe in the future we can add
145 | multiple different example sentence sets, though.
146 |
147 | ### Can we add pronunciation guides?
148 |
149 | The short answer is, this is very hard! I'd love to have them if someone can
150 | come up with a design for how to do this that'd work (including the logistics
151 | of hosting media files and stuff).
152 |
153 | (This was discussed in issues #43 and #80)
154 |
155 | ### Can we add pluralization support (i.e. themself vs themselves)
156 |
157 | All of the ways I can think of to do this are pretty ugly (both visually
158 | and in the code) so I'm pretty reluctant to do it. That's not an absolute no,
159 | but any proposed solution would need to keep the pronouns database simple
160 | enough that non-programmers can edit it and keep the URLs short, pretty, and
161 | readable to humans as a sentence if you take all the punctuation out.
162 |
163 | ## License
164 | Copyright © 2014-2018 Morgan Astra
165 |
166 | This program is free software: you can redistribute it and/or modify
167 | it under the terms of the GNU Affero General Public License as
168 | published by the Free Software Foundation, either version 3 of the
169 | License, or (at your option) any later version.
170 |
171 | This program is distributed in the hope that it will be useful,
172 | but WITHOUT ANY WARRANTY; without even the implied warranty of
173 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
174 | GNU Affero General Public License for more details.
175 |
176 | You should have received a copy of the GNU Affero General Public License
177 | along with this program. If not, see
178 |
179 |
--------------------------------------------------------------------------------
/COPYING:
--------------------------------------------------------------------------------
1 | GNU AFFERO GENERAL PUBLIC LICENSE
2 |
3 | Version 3, 19 November 2007
4 |
5 | Copyright © 2007 Free Software Foundation, Inc. Everyone is
6 | permitted to copy and distribute verbatim copies of this license document, but
7 | changing it is not allowed. Preamble
8 |
9 | The GNU Affero General Public License is a free, copyleft license for software
10 | and other kinds of works, specifically designed to ensure cooperation with the
11 | community in the case of network server software.
12 |
13 | The licenses for most software and other practical works are designed to take
14 | away your freedom to share and change the works. By contrast, our General Public
15 | Licenses are intended to guarantee your freedom to share and change all versions
16 | of a program--to make sure it remains free software for all its users.
17 |
18 | When we speak of free software, we are referring to freedom, not price. Our
19 | General Public Licenses are designed to make sure that you have the freedom to
20 | distribute copies of free software (and charge for them if you wish), that you
21 | receive source code or can get it if you want it, that you can change the
22 | software or use pieces of it in new free programs, and that you know you can do
23 | these things.
24 |
25 | Developers that use our General Public Licenses protect your rights with two
26 | steps: (1) assert copyright on the software, and (2) offer you this License
27 | which gives you legal permission to copy, distribute and/or modify the software.
28 |
29 | A secondary benefit of defending all users' freedom is that improvements made in
30 | alternate versions of the program, if they receive widespread use, become
31 | available for other developers to incorporate. Many developers of free software
32 | are heartened and encouraged by the resulting cooperation. However, in the case
33 | of software used on network servers, this result may fail to come about. The GNU
34 | General Public License permits making a modified version and letting the public
35 | access it on a server without ever releasing its source code to the public.
36 |
37 | The GNU Affero General Public License is designed specifically to ensure that,
38 | in such cases, the modified source code becomes available to the community. It
39 | requires the operator of a network server to provide the source code of the
40 | modified version running there to the users of that server. Therefore, public
41 | use of a modified version, on a publicly accessible server, gives the public
42 | access to the source code of the modified version.
43 |
44 | An older license, called the Affero General Public License and published by
45 | Affero, was designed to accomplish similar goals. This is a different license,
46 | not a version of the Affero GPL, but Affero has released a new version of the
47 | Affero GPL which permits relicensing under this license.
48 |
49 | The precise terms and conditions for copying, distribution and modification
50 | follow. TERMS AND CONDITIONS 0. Definitions.
51 |
52 | "This License" refers to version 3 of the GNU Affero General Public License.
53 |
54 | "Copyright" also means copyright-like laws that apply to other kinds of works,
55 | such as semiconductor masks.
56 |
57 | "The Program" refers to any copyrightable work licensed under this License. Each
58 | licensee is addressed as "you". "Licensees" and "recipients" may be individuals
59 | or organizations.
60 |
61 | To "modify" a work means to copy from or adapt all or part of the work in a
62 | fashion requiring copyright permission, other than the making of an exact copy.
63 | The resulting work is called a "modified version" of the earlier work or a work
64 | "based on" the earlier work.
65 |
66 | A "covered work" means either the unmodified Program or a work based on the
67 | Program.
68 |
69 | To "propagate" a work means to do anything with it that, without permission,
70 | would make you directly or secondarily liable for infringement under applicable
71 | copyright law, except executing it on a computer or modifying a private copy.
72 | Propagation includes copying, distribution (with or without modification),
73 | making available to the public, and in some countries other activities as well.
74 |
75 | To "convey" a work means any kind of propagation that enables other parties to
76 | make or receive copies. Mere interaction with a user through a computer network,
77 | with no transfer of a copy, is not conveying.
78 |
79 | An interactive user interface displays "Appropriate Legal Notices" to the extent
80 | that it includes a convenient and prominently visible feature that (1) displays
81 | an appropriate copyright notice, and (2) tells the user that there is no
82 | warranty for the work (except to the extent that warranties are provided), that
83 | licensees may convey the work under this License, and how to view a copy of this
84 | License. If the interface presents a list of user commands or options, such as a
85 | menu, a prominent item in the list meets this criterion. 1. Source Code.
86 |
87 | The "source code" for a work means the preferred form of the work for making
88 | modifications to it. "Object code" means any non-source form of a work.
89 |
90 | A "Standard Interface" means an interface that either is an official standard
91 | defined by a recognized standards body, or, in the case of interfaces specified
92 | for a particular programming language, one that is widely used among developers
93 | working in that language.
94 |
95 | The "System Libraries" of an executable work include anything, other than the
96 | work as a whole, that (a) is included in the normal form of packaging a Major
97 | Component, but which is not part of that Major Component, and (b) serves only to
98 | enable use of the work with that Major Component, or to implement a Standard
99 | Interface for which an implementation is available to the public in source code
100 | form. A "Major Component", in this context, means a major essential component
101 | (kernel, window system, and so on) of the specific operating system (if any) on
102 | which the executable work runs, or a compiler used to produce the work, or an
103 | object code interpreter used to run it.
104 |
105 | The "Corresponding Source" for a work in object code form means all the source
106 | code needed to generate, install, and (for an executable work) run the object
107 | code and to modify the work, including scripts to control those activities.
108 | However, it does not include the work's System Libraries, or general-purpose
109 | tools or generally available free programs which are used unmodified in
110 | performing those activities but which are not part of the work. For example,
111 | Corresponding Source includes interface definition files associated with source
112 | files for the work, and the source code for shared libraries and dynamically
113 | linked subprograms that the work is specifically designed to require, such as by
114 | intimate data communication or control flow between those subprograms and other
115 | parts of the work.
116 |
117 | The Corresponding Source need not include anything that users can regenerate
118 | automatically from other parts of the Corresponding Source.
119 |
120 | The Corresponding Source for a work in source code form is that same work. 2.
121 | Basic Permissions.
122 |
123 | All rights granted under this License are granted for the term of copyright on
124 | the Program, and are irrevocable provided the stated conditions are met. This
125 | License explicitly affirms your unlimited permission to run the unmodified
126 | Program. The output from running a covered work is covered by this License only
127 | if the output, given its content, constitutes a covered work. This License
128 | acknowledges your rights of fair use or other equivalent, as provided by
129 | copyright law.
130 |
131 | You may make, run and propagate covered works that you do not convey, without
132 | conditions so long as your license otherwise remains in force. You may convey
133 | covered works to others for the sole purpose of having them make modifications
134 | exclusively for you, or provide you with facilities for running those works,
135 | provided that you comply with the terms of this License in conveying all
136 | material for which you do not control copyright. Those thus making or running
137 | the covered works for you must do so exclusively on your behalf, under your
138 | direction and control, on terms that prohibit them from making any copies of
139 | your copyrighted material outside their relationship with you.
140 |
141 | Conveying under any other circumstances is permitted solely under the conditions
142 | stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3.
143 | Protecting Users' Legal Rights From Anti-Circumvention Law.
144 |
145 | No covered work shall be deemed part of an effective technological measure under
146 | any applicable law fulfilling obligations under article 11 of the WIPO copyright
147 | treaty adopted on 20 December 1996, or similar laws prohibiting or restricting
148 | circumvention of such measures.
149 |
150 | When you convey a covered work, you waive any legal power to forbid
151 | circumvention of technological measures to the extent such circumvention is
152 | effected by exercising rights under this License with respect to the covered
153 | work, and you disclaim any intention to limit operation or modification of the
154 | work as a means of enforcing, against the work's users, your or third parties'
155 | legal rights to forbid circumvention of technological measures. 4. Conveying
156 | Verbatim Copies.
157 |
158 | You may convey verbatim copies of the Program's source code as you receive it,
159 | in any medium, provided that you conspicuously and appropriately publish on each
160 | copy an appropriate copyright notice; keep intact all notices stating that this
161 | License and any non-permissive terms added in accord with section 7 apply to the
162 | code; keep intact all notices of the absence of any warranty; and give all
163 | recipients a copy of this License along with the Program.
164 |
165 | You may charge any price or no price for each copy that you convey, and you may
166 | offer support or warranty protection for a fee. 5. Conveying Modified Source
167 | Versions.
168 |
169 | You may convey a work based on the Program, or the modifications to produce it
170 | from the Program, in the form of source code under the terms of section 4,
171 | provided that you also meet all of these conditions:
172 |
173 | a) The work must carry prominent notices stating that you modified it, and
174 | giving a relevant date. b) The work must carry prominent notices stating that it
175 | is released under this License and any conditions added under section 7. This
176 | requirement modifies the requirement in section 4 to "keep intact all notices".
177 | c) You must license the entire work, as a whole, under this License to anyone
178 | who comes into possession of a copy. This License will therefore apply, along
179 | with any applicable section 7 additional terms, to the whole of the work, and
180 | all its parts, regardless of how they are packaged. This License gives no
181 | permission to license the work in any other way, but it does not invalidate such
182 | permission if you have separately received it. d) If the work has interactive
183 | user interfaces, each must display Appropriate Legal Notices; however, if the
184 | Program has interactive interfaces that do not display Appropriate Legal
185 | Notices, your work need not make them do so.
186 |
187 | A compilation of a covered work with other separate and independent works, which
188 | are not by their nature extensions of the covered work, and which are not
189 | combined with it such as to form a larger program, in or on a volume of a
190 | storage or distribution medium, is called an "aggregate" if the compilation and
191 | its resulting copyright are not used to limit the access or legal rights of the
192 | compilation's users beyond what the individual works permit. Inclusion of a
193 | covered work in an aggregate does not cause this License to apply to the other
194 | parts of the aggregate. 6. Conveying Non-Source Forms.
195 |
196 | You may convey a covered work in object code form under the terms of sections 4
197 | and 5, provided that you also convey the machine-readable Corresponding Source
198 | under the terms of this License, in one of these ways:
199 |
200 | a) Convey the object code in, or embodied in, a physical product (including a
201 | physical distribution medium), accompanied by the Corresponding Source fixed on
202 | a durable physical medium customarily used for software interchange. b) Convey
203 | the object code in, or embodied in, a physical product (including a physical
204 | distribution medium), accompanied by a written offer, valid for at least three
205 | years and valid for as long as you offer spare parts or customer support for
206 | that product model, to give anyone who possesses the object code either (1) a
207 | copy of the Corresponding Source for all the software in the product that is
208 | covered by this License, on a durable physical medium customarily used for
209 | software interchange, for a price no more than your reasonable cost of
210 | physically performing this conveying of source, or (2) access to copy the
211 | Corresponding Source from a network server at no charge. c) Convey individual
212 | copies of the object code with a copy of the written offer to provide the
213 | Corresponding Source. This alternative is allowed only occasionally and
214 | noncommercially, and only if you received the object code with such an offer, in
215 | accord with subsection 6b. d) Convey the object code by offering access from a
216 | designated place (gratis or for a charge), and offer equivalent access to the
217 | Corresponding Source in the same way through the same place at no further
218 | charge. You need not require recipients to copy the Corresponding Source along
219 | with the object code. If the place to copy the object code is a network server,
220 | the Corresponding Source may be on a different server (operated by you or a
221 | third party) that supports equivalent copying facilities, provided you maintain
222 | clear directions next to the object code saying where to find the Corresponding
223 | Source. Regardless of what server hosts the Corresponding Source, you remain
224 | obligated to ensure that it is available for as long as needed to satisfy these
225 | requirements. e) Convey the object code using peer-to-peer transmission,
226 | provided you inform other peers where the object code and Corresponding Source
227 | of the work are being offered to the general public at no charge under
228 | subsection 6d.
229 |
230 | A separable portion of the object code, whose source code is excluded from the
231 | Corresponding Source as a System Library, need not be included in conveying the
232 | object code work.
233 |
234 | A "User Product" is either (1) a "consumer product", which means any tangible
235 | personal property which is normally used for personal, family, or household
236 | purposes, or (2) anything designed or sold for incorporation into a dwelling. In
237 | determining whether a product is a consumer product, doubtful cases shall be
238 | resolved in favor of coverage. For a particular product received by a particular
239 | user, "normally used" refers to a typical or common use of that class of
240 | product, regardless of the status of the particular user or of the way in which
241 | the particular user actually uses, or expects or is expected to use, the
242 | product. A product is a consumer product regardless of whether the product has
243 | substantial commercial, industrial or non-consumer uses, unless such uses
244 | represent the only significant mode of use of the product.
245 |
246 | "Installation Information" for a User Product means any methods, procedures,
247 | authorization keys, or other information required to install and execute
248 | modified versions of a covered work in that User Product from a modified version
249 | of its Corresponding Source. The information must suffice to ensure that the
250 | continued functioning of the modified object code is in no case prevented or
251 | interfered with solely because modification has been made.
252 |
253 | If you convey an object code work under this section in, or with, or
254 | specifically for use in, a User Product, and the conveying occurs as part of a
255 | transaction in which the right of possession and use of the User Product is
256 | transferred to the recipient in perpetuity or for a fixed term (regardless of
257 | how the transaction is characterized), the Corresponding Source conveyed under
258 | this section must be accompanied by the Installation Information. But this
259 | requirement does not apply if neither you nor any third party retains the
260 | ability to install modified object code on the User Product (for example, the
261 | work has been installed in ROM).
262 |
263 | The requirement to provide Installation Information does not include a
264 | requirement to continue to provide support service, warranty, or updates for a
265 | work that has been modified or installed by the recipient, or for the User
266 | Product in which it has been modified or installed. Access to a network may be
267 | denied when the modification itself materially and adversely affects the
268 | operation of the network or violates the rules and protocols for communication
269 | across the network.
270 |
271 | Corresponding Source conveyed, and Installation Information provided, in accord
272 | with this section must be in a format that is publicly documented (and with an
273 | implementation available to the public in source code form), and must require no
274 | special password or key for unpacking, reading or copying. 7. Additional Terms.
275 |
276 | "Additional permissions" are terms that supplement the terms of this License by
277 | making exceptions from one or more of its conditions. Additional permissions
278 | that are applicable to the entire Program shall be treated as though they were
279 | included in this License, to the extent that they are valid under applicable
280 | law. If additional permissions apply only to part of the Program, that part may
281 | be used separately under those permissions, but the entire Program remains
282 | governed by this License without regard to the additional permissions.
283 |
284 | When you convey a copy of a covered work, you may at your option remove any
285 | additional permissions from that copy, or from any part of it. (Additional
286 | permissions may be written to require their own removal in certain cases when
287 | you modify the work.) You may place additional permissions on material, added by
288 | you to a covered work, for which you have or can give appropriate copyright
289 | permission.
290 |
291 | Notwithstanding any other provision of this License, for material you add to a
292 | covered work, you may (if authorized by the copyright holders of that material)
293 | supplement the terms of this License with terms:
294 |
295 | a) Disclaiming warranty or limiting liability differently from the terms of
296 | sections 15 and 16 of this License; or b) Requiring preservation of specified
297 | reasonable legal notices or author attributions in that material or in the
298 | Appropriate Legal Notices displayed by works containing it; or c) Prohibiting
299 | misrepresentation of the origin of that material, or requiring that modified
300 | versions of such material be marked in reasonable ways as different from the
301 | original version; or d) Limiting the use for publicity purposes of names of
302 | licensors or authors of the material; or e) Declining to grant rights under
303 | trademark law for use of some trade names, trademarks, or service marks; or f)
304 | Requiring indemnification of licensors and authors of that material by anyone
305 | who conveys the material (or modified versions of it) with contractual
306 | assumptions of liability to the recipient, for any liability that these
307 | contractual assumptions directly impose on those licensors and authors.
308 |
309 | All other non-permissive additional terms are considered "further restrictions"
310 | within the meaning of section 10. If the Program as you received it, or any part
311 | of it, contains a notice stating that it is governed by this License along with
312 | a term that is a further restriction, you may remove that term. If a license
313 | document contains a further restriction but permits relicensing or conveying
314 | under this License, you may add to a covered work material governed by the terms
315 | of that license document, provided that the further restriction does not survive
316 | such relicensing or conveying.
317 |
318 | If you add terms to a covered work in accord with this section, you must place,
319 | in the relevant source files, a statement of the additional terms that apply to
320 | those files, or a notice indicating where to find the applicable terms.
321 |
322 | Additional terms, permissive or non-permissive, may be stated in the form of a
323 | separately written license, or stated as exceptions; the above requirements
324 | apply either way. 8. Termination.
325 |
326 | You may not propagate or modify a covered work except as expressly provided
327 | under this License. Any attempt otherwise to propagate or modify it is void, and
328 | will automatically terminate your rights under this License (including any
329 | patent licenses granted under the third paragraph of section 11).
330 |
331 | However, if you cease all violation of this License, then your license from a
332 | particular copyright holder is reinstated (a) provisionally, unless and until
333 | the copyright holder explicitly and finally terminates your license, and (b)
334 | permanently, if the copyright holder fails to notify you of the violation by
335 | some reasonable means prior to 60 days after the cessation.
336 |
337 | Moreover, your license from a particular copyright holder is reinstated
338 | permanently if the copyright holder notifies you of the violation by some
339 | reasonable means, this is the first time you have received notice of violation
340 | of this License (for any work) from that copyright holder, and you cure the
341 | violation prior to 30 days after your receipt of the notice.
342 |
343 | Termination of your rights under this section does not terminate the licenses of
344 | parties who have received copies or rights from you under this License. If your
345 | rights have been terminated and not permanently reinstated, you do not qualify
346 | to receive new licenses for the same material under section 10. 9. Acceptance
347 | Not Required for Having Copies.
348 |
349 | You are not required to accept this License in order to receive or run a copy of
350 | the Program. Ancillary propagation of a covered work occurring solely as a
351 | consequence of using peer-to-peer transmission to receive a copy likewise does
352 | not require acceptance. However, nothing other than this License grants you
353 | permission to propagate or modify any covered work. These actions infringe
354 | copyright if you do not accept this License. Therefore, by modifying or
355 | propagating a covered work, you indicate your acceptance of this License to do
356 | so. 10. Automatic Licensing of Downstream Recipients.
357 |
358 | Each time you convey a covered work, the recipient automatically receives a
359 | license from the original licensors, to run, modify and propagate that work,
360 | subject to this License. You are not responsible for enforcing compliance by
361 | third parties with this License.
362 |
363 | An "entity transaction" is a transaction transferring control of an
364 | organization, or substantially all assets of one, or subdividing an
365 | organization, or merging organizations. If propagation of a covered work results
366 | from an entity transaction, each party to that transaction who receives a copy
367 | of the work also receives whatever licenses to the work the party's predecessor
368 | in interest had or could give under the previous paragraph, plus a right to
369 | possession of the Corresponding Source of the work from the predecessor in
370 | interest, if the predecessor has it or can get it with reasonable efforts.
371 |
372 | You may not impose any further restrictions on the exercise of the rights
373 | granted or affirmed under this License. For example, you may not impose a
374 | license fee, royalty, or other charge for exercise of rights granted under this
375 | License, and you may not initiate litigation (including a cross-claim or
376 | counterclaim in a lawsuit) alleging that any patent claim is infringed by
377 | making, using, selling, offering for sale, or importing the Program or any
378 | portion of it. 11. Patents.
379 |
380 | A "contributor" is a copyright holder who authorizes use under this License of
381 | the Program or a work on which the Program is based. The work thus licensed is
382 | called the contributor's "contributor version".
383 |
384 | A contributor's "essential patent claims" are all patent claims owned or
385 | controlled by the contributor, whether already acquired or hereafter acquired,
386 | that would be infringed by some manner, permitted by this License, of making,
387 | using, or selling its contributor version, but do not include claims that would
388 | be infringed only as a consequence of further modification of the contributor
389 | version. For purposes of this definition, "control" includes the right to grant
390 | patent sublicenses in a manner consistent with the requirements of this License.
391 |
392 | Each contributor grants you a non-exclusive, worldwide, royalty-free patent
393 | license under the contributor's essential patent claims, to make, use, sell,
394 | offer for sale, import and otherwise run, modify and propagate the contents of
395 | its contributor version.
396 |
397 | In the following three paragraphs, a "patent license" is any express agreement
398 | or commitment, however denominated, not to enforce a patent (such as an express
399 | permission to practice a patent or covenant not to sue for patent infringement).
400 | To "grant" such a patent license to a party means to make such an agreement or
401 | commitment not to enforce a patent against the party.
402 |
403 | If you convey a covered work, knowingly relying on a patent license, and the
404 | Corresponding Source of the work is not available for anyone to copy, free of
405 | charge and under the terms of this License, through a publicly available network
406 | server or other readily accessible means, then you must either (1) cause the
407 | Corresponding Source to be so available, or (2) arrange to deprive yourself of
408 | the benefit of the patent license for this particular work, or (3) arrange, in a
409 | manner consistent with the requirements of this License, to extend the patent
410 | license to downstream recipients. "Knowingly relying" means you have actual
411 | knowledge that, but for the patent license, your conveying the covered work in a
412 | country, or your recipient's use of the covered work in a country, would
413 | infringe one or more identifiable patents in that country that you have reason
414 | to believe are valid.
415 |
416 | If, pursuant to or in connection with a single transaction or arrangement, you
417 | convey, or propagate by procuring conveyance of, a covered work, and grant a
418 | patent license to some of the parties receiving the covered work authorizing
419 | them to use, propagate, modify or convey a specific copy of the covered work,
420 | then the patent license you grant is automatically extended to all recipients of
421 | the covered work and works based on it.
422 |
423 | A patent license is "discriminatory" if it does not include within the scope of
424 | its coverage, prohibits the exercise of, or is conditioned on the non-exercise
425 | of one or more of the rights that are specifically granted under this License.
426 | You may not convey a covered work if you are a party to an arrangement with a
427 | third party that is in the business of distributing software, under which you
428 | make payment to the third party based on the extent of your activity of
429 | conveying the work, and under which the third party grants, to any of the
430 | parties who would receive the covered work from you, a discriminatory patent
431 | license (a) in connection with copies of the covered work conveyed by you (or
432 | copies made from those copies), or (b) primarily for and in connection with
433 | specific products or compilations that contain the covered work, unless you
434 | entered into that arrangement, or that patent license was granted, prior to 28
435 | March 2007.
436 |
437 | Nothing in this License shall be construed as excluding or limiting any implied
438 | license or other defenses to infringement that may otherwise be available to you
439 | under applicable patent law. 12. No Surrender of Others' Freedom.
440 |
441 | If conditions are imposed on you (whether by court order, agreement or
442 | otherwise) that contradict the conditions of this License, they do not excuse
443 | you from the conditions of this License. If you cannot convey a covered work so
444 | as to satisfy simultaneously your obligations under this License and any other
445 | pertinent obligations, then as a consequence you may not convey it at all. For
446 | example, if you agree to terms that obligate you to collect a royalty for
447 | further conveying from those to whom you convey the Program, the only way you
448 | could satisfy both those terms and this License would be to refrain entirely
449 | from conveying the Program. 13. Remote Network Interaction; Use with the GNU
450 | General Public License.
451 |
452 | Notwithstanding any other provision of this License, if you modify the Program,
453 | your modified version must prominently offer all users interacting with it
454 | remotely through a computer network (if your version supports such interaction)
455 | an opportunity to receive the Corresponding Source of your version by providing
456 | access to the Corresponding Source from a network server at no charge, through
457 | some standard or customary means of facilitating copying of software. This
458 | Corresponding Source shall include the Corresponding Source for any work covered
459 | by version 3 of the GNU General Public License that is incorporated pursuant to
460 | the following paragraph.
461 |
462 | Notwithstanding any other provision of this License, you have permission to link
463 | or combine any covered work with a work licensed under version 3 of the GNU
464 | General Public License into a single combined work, and to convey the resulting
465 | work. The terms of this License will continue to apply to the part which is the
466 | covered work, but the work with which it is combined will remain governed by
467 | version 3 of the GNU General Public License. 14. Revised Versions of this
468 | License.
469 |
470 | The Free Software Foundation may publish revised and/or new versions of the GNU
471 | Affero General Public License from time to time. Such new versions will be
472 | similar in spirit to the present version, but may differ in detail to address
473 | new problems or concerns.
474 |
475 | Each version is given a distinguishing version number. If the Program specifies
476 | that a certain numbered version of the GNU Affero General Public License "or any
477 | later version" applies to it, you have the option of following the terms and
478 | conditions either of that numbered version or of any later version published by
479 | the Free Software Foundation. If the Program does not specify a version number
480 | of the GNU Affero General Public License, you may choose any version ever
481 | published by the Free Software Foundation.
482 |
483 | If the Program specifies that a proxy can decide which future versions of the
484 | GNU Affero General Public License can be used, that proxy's public statement of
485 | acceptance of a version permanently authorizes you to choose that version for
486 | the Program.
487 |
488 | Later license versions may give you additional or different permissions.
489 | However, no additional obligations are imposed on any author or copyright holder
490 | as a result of your choosing to follow a later version. 15. Disclaimer of
491 | Warranty.
492 |
493 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
494 | EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER
495 | PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
496 | EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
497 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE
498 | QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE
499 | DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
500 | 16. Limitation of Liability.
501 |
502 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY
503 | COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS
504 | PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL,
505 | INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE
506 | THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED
507 | INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE
508 | PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY
509 | HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of
510 | Sections 15 and 16.
511 |
512 | If the disclaimer of warranty and limitation of liability provided above cannot
513 | be given local legal effect according to their terms, reviewing courts shall
514 | apply local law that most closely approximates an absolute waiver of all civil
515 | liability in connection with the Program, unless a warranty or assumption of
516 | liability accompanies a copy of the Program in return for a fee.
517 |
518 | END OF TERMS AND CONDITIONS
--------------------------------------------------------------------------------