diff --git a/.github/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md index 9fc20b52b4..b461c37ca9 100644 --- a/.github/CODE_OF_CONDUCT.md +++ b/.github/CODE_OF_CONDUCT.md @@ -1,24 +1,51 @@ -# p5.js Code of Conduct +## [p5.js community statement](http://p5js.org/community/) + +p5.js is a community interested in exploring the creation of art and design with technology. + +We are a community of, and in solidarity with, people from every gender identity and expression, sexual orientation, race, ethnicity, language, neuro-type, size, disability, class, religion, culture, subculture, political opinion, age, skill level, occupation, and background. We acknowledge that not everyone has the time, financial means, or capacity to actively participate, but we recognize and encourage involvement of all kinds. We facilitate and foster access and empowerment. We are all learners. + +We like these hashtags: #noCodeSnobs (because we value community over efficiency), #newKidLove (because we all started somewhere), #unassumeCore (because we don't assume knowledge), and #BlackLivesMatter (because of course). + +In practice: +* We are not code snobs. We do not assume knowledge or imply there are things that somebody should know. +* We insist on actively engaging with requests for feedback regardless of their complexity. +* We welcome newcomers and prioritize the education of others. We strive to approach all tasks with the enthusiasm of a newcomer. Because we believe that newcomers are just as valuable in this effort as experts. +* We consistently make the effort to actively recognize and validate multiple types of contributions. +* We are always willing to offer help or guidance. + +In times of conflict: +* We listen. +* We clearly communicate while acknowledging other's feelings. +* We admit when we're wrong, apologize, and accept responsibility for our actions. +* We are continuously seeking to improve ourselves and our community. +* We keep our community respectful and open. +* We make everyone feel heard. +* We are mindful and kind in our interactions. + +In the future: +* The future is now. + + +## p5.js Code of Conduct * **Be mindful of your language.** Any of the following behavior is unacceptable: * Offensive comments related to gender identity and expression, sexual orientation, race, ethnicity, language, neuro-type, size, ability, class, religion, culture, subculture, political opinion, age, skill level, occupation, or background * Threats of violence * Deliberate intimidation - * Sexually explicit or violent material + * Sexually explicit or violent material that is not contextualized and preceded by a considerate warning * Unwelcome sexual attention * Stalking or following * Or any other kinds of harassment Use your best judgement. If it will possibly make others uncomfortable, do not post it. -* **Be respectful.** Disagreement is not an opportunity to attack someone else's thoughts or opinions. Although views may differ, remember to approach every situation with patience and care. -* **Be considerate.** Think about how your contribution will affect others in the community. +* **Be respectful.** Disagreement is not an opportunity to attack someone else's thoughts or opinions. Although views may differ, remember to approach every situation with patience and care. +* **Be considerate.** Think about how your contribution will affect others in the community. * **Be open minded.** Embrace new people and new ideas. Our community is continually evolving and we welcome positive change. If you believe someone is violating the code of conduct, we ask that you report it by emailing [hello@p5js.org](mailto:hello@p5js.org). Please include your name and a description of the incident, and we will get back to you ASAP. -Participants asked to stop any harassing behavior are expected to comply immediately. If a participant engages in harassing behavior, the p5.js Team may take any action they deem appropriate, up to and including expulsion from all p5.js spaces and identification of the participant as a harasser to other p5.js members or the general public. - -## Also +Sometimes, participants violating the Code of Conduct are unaware that their behavior is harmful, and an open conversation clears things up to move forward. However, if a participant continues with the behavior, the p5.js team may take any action they deem appropriate, up to and including expulsion from all p5.js spaces and identification of the participant as a harasser to other p5.js members or the general public. -* You can read our [community statement](http://p5js.org/community/) on our website. \ No newline at end of file +--- +This statement is licensed under a [Creative Commons license](https://creativecommons.org/licenses/by-sa/4.0/). Please feel free to share and remix with attribution. \ No newline at end of file diff --git a/.gitignore b/.gitignore index 6fdf06c6b7..f1fd73f1a9 100644 --- a/.gitignore +++ b/.gitignore @@ -6,7 +6,6 @@ node_modules/ npm-debug.log dump.rdb -public/* static/dist/ static/css/app.min.css dist/ diff --git a/Dockerfile b/Dockerfile index 743d7d9037..31f05bea2e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,6 +4,7 @@ ENV APP_HOME=/usr/src/app \ RUN mkdir -p $APP_HOME WORKDIR $APP_HOME EXPOSE 8000 +EXPOSE 8002 FROM base as development ENV NODE_ENV development @@ -15,6 +16,7 @@ COPY ./webpack ./webpack COPY client ./client COPY server ./server COPY translations/locales ./translations/locales +COPY public ./public CMD ["npm", "start"] FROM development as build diff --git a/client/common/Button.jsx b/client/common/Button.jsx index 3009ab338b..f1f6cfe28c 100644 --- a/client/common/Button.jsx +++ b/client/common/Button.jsx @@ -6,8 +6,12 @@ import { Link } from 'react-router'; import { remSize, prop } from '../theme'; const kinds = { + primary: 'primary', + secondary: 'secondary' +}; + +const displays = { block: 'block', - icon: 'icon', inline: 'inline' }; @@ -16,6 +20,7 @@ const kinds = { // general global styles const StyledButton = styled.button` &&& { + font-weight: bold; display: flex; justify-content: center; align-items: center; @@ -23,45 +28,49 @@ const StyledButton = styled.button` width: max-content; text-decoration: none; - color: ${prop('Button.default.foreground')}; - background-color: ${prop('Button.default.background')}; + color: ${({ kind }) => prop(`Button.${kind}.default.foreground`)}; + background-color: ${({ kind }) => + prop(`Button.${kind}.default.background`)}; cursor: pointer; - border: 2px solid ${prop('Button.default.border')}; + border: 2px solid ${({ kind }) => prop(`Button.${kind}.default.border`)}; border-radius: 2px; padding: ${remSize(8)} ${remSize(25)}; line-height: 1; svg * { - fill: ${prop('Button.default.foreground')}; + fill: ${({ kind }) => prop(`Button.${kind}.default.foreground`)}; } &:hover:not(:disabled) { - color: ${prop('Button.hover.foreground')}; - background-color: ${prop('Button.hover.background')}; - border-color: ${prop('Button.hover.border')}; + color: ${({ kind }) => prop(`Button.${kind}.hover.foreground`)}; + background-color: ${({ kind }) => + prop(`Button.${kind}.hover.background`)}; + border-color: ${({ kind }) => prop(`Button.${kind}.hover.border`)}; svg * { - fill: ${prop('Button.hover.foreground')}; + fill: ${({ kind }) => prop(`Button.${kind}.hover.foreground`)}; } } &:active:not(:disabled) { - color: ${prop('Button.active.foreground')}; - background-color: ${prop('Button.active.background')}; + color: ${({ kind }) => prop(`Button.${kind}.active.foreground`)}; + background-color: ${({ kind }) => + prop(`Button.${kind}.active.background`)}; svg * { - fill: ${prop('Button.active.foreground')}; + fill: ${({ kind }) => prop(`Button.${kind}.active.foreground`)}; } } &:disabled { - color: ${prop('Button.disabled.foreground')}; - background-color: ${prop('Button.disabled.background')}; - border-color: ${prop('Button.disabled.border')}; + color: ${({ kind }) => prop(`Button.${kind}.disabled.foreground`)}; + background-color: ${({ kind }) => + prop(`Button.${kind}.disabled.background`)}; + border-color: ${({ kind }) => prop(`Button.${kind}.disabled.border`)}; cursor: not-allowed; svg * { - fill: ${prop('Button.disabled.foreground')}; + fill: ${({ kind }) => prop(`Button.${kind}.disabled.foreground`)}; } } @@ -108,8 +117,8 @@ const StyledIconButton = styled.button` height: ${remSize(32)}px; text-decoration: none; - color: ${prop('Button.default.foreground')}; - background-color: ${prop('Button.hover.background')}; + color: ${({ kind }) => prop(`Button.${kind}.default.foreground`)}; + background-color: ${({ kind }) => prop(`Button.${kind}.hover.background`)}; cursor: pointer; border: 1px solid transparent; border-radius: 50%; @@ -117,26 +126,29 @@ const StyledIconButton = styled.button` line-height: 1; &:hover:not(:disabled) { - color: ${prop('Button.hover.foreground')}; - background-color: ${prop('Button.hover.background')}; + color: ${({ kind }) => prop(`Button.${kind}.hover.foreground`)}; + background-color: ${({ kind }) => + prop(`Button.${kind}.hover.background`)}; svg * { - fill: ${prop('Button.hover.foreground')}; + fill: ${({ kind }) => prop(`Button.${kind}.hover.foreground`)}; } } &:active:not(:disabled) { - color: ${prop('Button.active.foreground')}; - background-color: ${prop('Button.active.background')}; + color: ${({ kind }) => prop(`Button.${kind}.active.foreground`)}; + background-color: ${({ kind }) => + prop(`Button.${kind}.active.background`)}; svg * { - fill: ${prop('Button.active.foreground')}; + fill: ${({ kind }) => prop(`Button.${kind}.active.foreground`)}; } } &:disabled { - color: ${prop('Button.disabled.foreground')}; - background-color: ${prop('Button.disabled.background')}; + color: ${({ kind }) => prop(`Button.${kind}.disabled.foreground`)}; + background-color: ${({ kind }) => + prop(`Button.${kind}.disabled.background`)}; cursor: not-allowed; } @@ -151,10 +163,12 @@ const StyledIconButton = styled.button` */ const Button = ({ children, + display, href, kind, iconBefore, iconAfter, + iconOnly, 'aria-label': ariaLabel, to, type, @@ -170,9 +184,11 @@ const Button = ({ ); let StyledComponent = StyledButton; - if (kind === kinds.inline) { + if (display === displays.inline) { StyledComponent = StyledInlineButton; - } else if (kind === kinds.icon) { + } + + if (iconOnly) { StyledComponent = StyledIconButton; } @@ -180,6 +196,7 @@ const Button = ({ return ( + {content} ); @@ -214,9 +238,11 @@ const Button = ({ Button.defaultProps = { children: null, disabled: false, + display: displays.block, iconAfter: null, iconBefore: null, - kind: kinds.block, + iconOnly: false, + kind: kinds.primary, href: null, 'aria-label': null, to: null, @@ -224,6 +250,7 @@ Button.defaultProps = { }; Button.kinds = kinds; +Button.displays = displays; Button.propTypes = { /** @@ -235,6 +262,10 @@ Button.propTypes = { If the button can be activated or not */ disabled: PropTypes.bool, + /** + * The display type of the button—inline or block + */ + display: PropTypes.string, /** * SVG icon to place after child content */ @@ -243,6 +274,10 @@ Button.propTypes = { * SVG icon to place before child content */ iconBefore: PropTypes.element, + /** + * If the button content is only an SVG icon + */ + iconOnly: PropTypes.bool, /** * The kind of button - determines how it appears visually */ diff --git a/client/common/Button.stories.jsx b/client/common/Button.stories.jsx index a583d8b46d..6ad1ddddb5 100644 --- a/client/common/Button.stories.jsx +++ b/client/common/Button.stories.jsx @@ -59,7 +59,7 @@ export const ButtonWithIconAfter = () => ( ); export const InlineButtonWithIconAfter = () => ( - ); @@ -68,6 +68,6 @@ export const InlineIconOnlyButton = () => ( + + + + + + )} + + ); +} + +export default CookieConsent; diff --git a/client/modules/User/pages/DashboardView.jsx b/client/modules/User/pages/DashboardView.jsx index c44cd69d17..38958b2335 100644 --- a/client/modules/User/pages/DashboardView.jsx +++ b/client/modules/User/pages/DashboardView.jsx @@ -11,6 +11,7 @@ import AssetList from '../../IDE/components/AssetList'; import AssetSize from '../../IDE/components/AssetSize'; import CollectionList from '../../IDE/components/CollectionList'; import SketchList from '../../IDE/components/SketchList'; +import RootPage from '../../../components/RootPage'; import * as ProjectActions from '../../IDE/actions/project'; import { CollectionSearchbar, @@ -133,7 +134,7 @@ class DashboardView extends React.Component { const actions = this.renderActionButton(currentTab, username, this.props.t); return ( -
+
+ ); } } diff --git a/client/modules/User/pages/EmailVerificationView.jsx b/client/modules/User/pages/EmailVerificationView.jsx index 6b96264758..4f9775e5fc 100644 --- a/client/modules/User/pages/EmailVerificationView.jsx +++ b/client/modules/User/pages/EmailVerificationView.jsx @@ -8,6 +8,7 @@ import get from 'lodash/get'; import { Helmet } from 'react-helmet'; import { verifyEmailConfirmation } from '../actions'; import Nav from '../../../components/Nav'; +import RootPage from '../../../components/RootPage'; class EmailVerificationView extends React.Component { static defaultProps = { @@ -39,7 +40,7 @@ class EmailVerificationView extends React.Component { } return ( -
+
- + ); } } diff --git a/client/modules/User/pages/LoginView.jsx b/client/modules/User/pages/LoginView.jsx index 58449067bc..4a81ea726c 100644 --- a/client/modules/User/pages/LoginView.jsx +++ b/client/modules/User/pages/LoginView.jsx @@ -5,11 +5,12 @@ import { useTranslation } from 'react-i18next'; import LoginForm from '../components/LoginForm'; import SocialAuthButton from '../components/SocialAuthButton'; import Nav from '../../../components/Nav'; +import RootPage from '../../../components/RootPage'; function LoginView() { const { t } = useTranslation(); return ( -
+
- + ); } diff --git a/client/modules/User/pages/NewPasswordView.jsx b/client/modules/User/pages/NewPasswordView.jsx index 506471bf5c..3bfeec86ad 100644 --- a/client/modules/User/pages/NewPasswordView.jsx +++ b/client/modules/User/pages/NewPasswordView.jsx @@ -7,6 +7,7 @@ import { useTranslation } from 'react-i18next'; import NewPasswordForm from '../components/NewPasswordForm'; import { validateResetPasswordToken } from '../actions'; import Nav from '../../../components/Nav'; +import RootPage from '../../../components/RootPage'; function NewPasswordView(props) { const { t } = useTranslation(); @@ -27,7 +28,7 @@ function NewPasswordView(props) { user: true }); return ( -
+
- + ); } diff --git a/client/modules/User/pages/ResetPasswordView.jsx b/client/modules/User/pages/ResetPasswordView.jsx index d3af6c125c..d406f185e6 100644 --- a/client/modules/User/pages/ResetPasswordView.jsx +++ b/client/modules/User/pages/ResetPasswordView.jsx @@ -6,6 +6,7 @@ import { Helmet } from 'react-helmet'; import { useTranslation } from 'react-i18next'; import ResetPasswordForm from '../components/ResetPasswordForm'; import Nav from '../../../components/Nav'; +import RootPage from '../../../components/RootPage'; function ResetPasswordView() { const { t } = useTranslation(); @@ -19,7 +20,7 @@ function ResetPasswordView() { user: true }); return ( -
+
- + ); } diff --git a/client/modules/User/pages/SignupView.jsx b/client/modules/User/pages/SignupView.jsx index efd2438eed..ee315c2fb3 100644 --- a/client/modules/User/pages/SignupView.jsx +++ b/client/modules/User/pages/SignupView.jsx @@ -5,11 +5,12 @@ import { useTranslation } from 'react-i18next'; import SignupForm from '../components/SignupForm'; import SocialAuthButton from '../components/SocialAuthButton'; import Nav from '../../../components/Nav'; +import RootPage from '../../../components/RootPage'; function SignupView() { const { t } = useTranslation(); return ( -
+

- {t('SignupView.AlreadyHave')} + By signing up, you agree to the p5.js Editor's{' '} + Terms of Use and{' '} + Privacy Policy. +

+

+ {t('SignupView.AlreadyHave')}{' '} {t('SignupView.Login')}

- + ); } diff --git a/client/modules/User/reducers.js b/client/modules/User/reducers.js index 87953d7810..2832190b28 100644 --- a/client/modules/User/reducers.js +++ b/client/modules/User/reducers.js @@ -41,6 +41,8 @@ const user = (state = { authenticated: false }, action) => { return { ...state, ...action.user }; case ActionTypes.API_KEY_CREATED: return { ...state, ...action.user }; + case ActionTypes.SET_COOKIE_CONSENT: + return { ...state, cookieConsent: action.cookieConsent }; default: return state; } diff --git a/client/routes.jsx b/client/routes.jsx index d405c0c7e4..d7762fc67e 100644 --- a/client/routes.jsx +++ b/client/routes.jsx @@ -17,6 +17,9 @@ import CollectionView from './modules/User/pages/CollectionView'; import DashboardView from './modules/User/pages/DashboardView'; import createRedirectWithUsername from './components/createRedirectWithUsername'; import MobileDashboardView from './modules/Mobile/MobileDashboardView'; +// import PrivacyPolicy from './modules/IDE/pages/PrivacyPolicy'; +// import TermsOfUse from './modules/IDE/pages/TermsOfUse'; +import Legal from './modules/IDE/pages/Legal'; import { getUser } from './modules/User/actions'; import { stopSketch } from './modules/IDE/actions/ide'; import { @@ -117,6 +120,9 @@ const routes = (store) => ( {/* Mobile-only Routes */} + + + ); diff --git a/client/styles/components/_form-container.scss b/client/styles/components/_form-container.scss index 6ec7dcdf48..aebe0cdc73 100644 --- a/client/styles/components/_form-container.scss +++ b/client/styles/components/_form-container.scss @@ -1,9 +1,10 @@ .form-container { text-align: center; - height: 100%; display: flex; flex-direction: column; align-items: center; + justify-content: center; + flex: 1; } .form-container--align-left { diff --git a/client/styles/components/_preferences.scss b/client/styles/components/_preferences.scss index f34b920aba..2d2c1c181e 100644 --- a/client/styles/components/_preferences.scss +++ b/client/styles/components/_preferences.scss @@ -140,6 +140,12 @@ & + & { margin-left: #{45 / $base-font-size}rem; } + &:hover { + @include themify() { + border-bottom: #{4 / $base-font-size}rem solid + getThemifyVariable("button-background-hover-color"); + } + } } .preference__subheading { diff --git a/client/styles/layout/_dashboard.scss b/client/styles/layout/_dashboard.scss index 97e86737f7..a0607cda7f 100644 --- a/client/styles/layout/_dashboard.scss +++ b/client/styles/layout/_dashboard.scss @@ -1,14 +1,3 @@ -.dashboard { - display: flex; - flex-direction: column; - flex-wrap: wrap; - @include themify() { - color: getThemifyVariable('primary-text-color'); - background-color: getThemifyVariable('background-color'); - } - height: 100%; -} - .dashboard-content { display: flex; flex-direction: column; diff --git a/client/styles/layout/_fullscreen.scss b/client/styles/layout/_fullscreen.scss deleted file mode 100644 index 7d76601c7c..0000000000 --- a/client/styles/layout/_fullscreen.scss +++ /dev/null @@ -1,9 +0,0 @@ -.fullscreen-preview { - display: flex; - width: 100%; - height: 100%; - flex-flow: column; - @include themify() { - background-color: getThemifyVariable('background-color'); - } -} diff --git a/client/styles/layout/_ide.scss b/client/styles/layout/_ide.scss index e141846884..3763977268 100644 --- a/client/styles/layout/_ide.scss +++ b/client/styles/layout/_ide.scss @@ -1,14 +1,3 @@ -.ide { - display: flex; - flex-direction: column; - height: 100%; - flex-wrap: wrap; - @include themify() { - color: getThemifyVariable('primary-text-color'); - background-color: getThemifyVariable('background-color'); - } -} - .editor-preview-container { width: 100%; flex: 1 0 0px; diff --git a/client/styles/layout/_user.scss b/client/styles/layout/_user.scss deleted file mode 100644 index 518df72767..0000000000 --- a/client/styles/layout/_user.scss +++ /dev/null @@ -1,23 +0,0 @@ -.user { - display: flex; - flex-direction: column; - height: 100%; - flex-wrap: wrap; - @include themify() { - color: getThemifyVariable('primary-text-color'); - background-color: getThemifyVariable('background-color'); - } -} - -.login, -.signup, -.reset-password-container, -.new-password-container, -.email-verification { - height: 100%; - overflow: auto; - @include themify() { - color: getThemifyVariable('primary-text-color'); - background-color: getThemifyVariable('background-color'); - } -} \ No newline at end of file diff --git a/client/styles/main.scss b/client/styles/main.scss index b9e4fa53c4..c1763fc12a 100644 --- a/client/styles/main.scss +++ b/client/styles/main.scss @@ -57,5 +57,3 @@ @import 'layout/dashboard'; @import 'layout/ide'; -@import 'layout/fullscreen'; -@import 'layout/user'; diff --git a/client/theme.js b/client/theme.js index f22f13adb4..e885902a0f 100644 --- a/client/theme.js +++ b/client/theme.js @@ -8,7 +8,9 @@ export const Theme = { export const colors = { p5jsPink: '#ed225d', - processingBlue: '#007BBB', + processingBlueDark: '#28347D', + processingBlue: '#2D67F6', + processingBlueLight: '#8DADF9', p5jsActivePink: '#f10046', white: '#fff', black: '#000', @@ -45,6 +47,10 @@ export const common = { shadowColor: 'rgba(0, 0, 0, 0.16)' }; +export const device = { + desktop: `(min-width: 770px)` +}; + export const remSize = (size) => `${size / common.baseFontSize}rem`; export const prop = (key) => (props) => { @@ -63,28 +69,53 @@ export default { colors, ...common, primaryTextColor: grays.dark, + inactiveTextColor: grays.middleDark, backgroundColor: grays.lighter, Button: { - default: { - foreground: colors.black, - background: grays.light, - border: grays.middleLight - }, - hover: { - foreground: grays.lightest, - background: colors.p5jsPink, - border: colors.p5jsPink - }, - active: { - foreground: grays.lightest, - background: colors.p5jsActivePink, - border: colors.p5jsActivePink + primary: { + default: { + foreground: colors.black, + background: grays.light, + border: grays.middleLight + }, + hover: { + foreground: grays.lightest, + background: colors.p5jsPink, + border: colors.p5jsPink + }, + active: { + foreground: grays.lightest, + background: colors.p5jsActivePink, + border: colors.p5jsActivePink + }, + disabled: { + foreground: colors.black, + background: grays.light, + border: grays.middleLight + } }, - disabled: { - foreground: colors.black, - background: grays.light, - border: grays.middleLight + secondary: { + default: { + foreground: grays.lightest, + background: colors.p5jsPink, + border: colors.p5jsPink + }, + hover: { + foreground: grays.lightest, + background: colors.p5jsPink, + border: colors.p5jsPink + }, + active: { + foreground: grays.lightest, + background: colors.p5jsActivePink, + border: colors.p5jsActivePink + }, + disabled: { + foreground: colors.black, + background: grays.light, + border: grays.middleLight + } } }, Icon: { @@ -100,7 +131,8 @@ export default { }, Modal: { background: grays.light, - border: grays.middleLight + border: grays.middleLight, + separator: grays.middleDark }, Separator: grays.middleLight, @@ -110,34 +142,62 @@ export default { card: { background: grays.lighter } + }, + Policy: { + link: colors.processingBlue } }, [Theme.dark]: { colors, ...common, primaryTextColor: grays.lightest, + inactiveTextColor: grays.middleLight, backgroundColor: grays.darker, Button: { - default: { - foreground: grays.light, - background: grays.dark, - border: grays.middleDark + primary: { + default: { + foreground: grays.light, + background: grays.dark, + border: grays.middleDark + }, + hover: { + foreground: grays.lightest, + background: colors.p5jsPink, + border: colors.p5jsPink + }, + active: { + foreground: grays.lightest, + background: colors.p5jsActivePink, + border: colors.p5jsActivePink + }, + disabled: { + foreground: grays.light, + background: grays.dark, + border: grays.middleDark + } }, - hover: { - foreground: grays.lightest, - background: colors.p5jsPink, - border: colors.p5jsPink - }, - active: { - foreground: grays.lightest, - background: colors.p5jsActivePink, - border: colors.p5jsActivePink - }, - disabled: { - foreground: grays.light, - background: grays.dark, - border: grays.middleDark + secondary: { + default: { + foreground: grays.lightest, + background: colors.p5jsPink, + border: colors.p5jsPink + }, + hover: { + foreground: grays.lightest, + background: colors.p5jsPink, + border: colors.p5jsPink + }, + active: { + foreground: grays.lightest, + background: colors.p5jsActivePink, + border: colors.p5jsActivePink + }, + disabled: { + foreground: grays.light, + background: grays.dark, + border: grays.middleDark + } } }, Icon: { @@ -153,7 +213,8 @@ export default { }, Modal: { background: grays.dark, - border: grays.middleDark + border: grays.middleDark, + separator: grays.middleLight }, Separator: grays.middleDark, @@ -163,34 +224,62 @@ export default { card: { background: grays.dark } + }, + Policy: { + link: colors.processingBlueLight } }, [Theme.contrast]: { colors, ...common, primaryTextColor: grays.lightest, + inactiveTextColor: grays.light, backgroundColor: grays.darker, Button: { - default: { - foreground: grays.light, - background: grays.dark, - border: grays.middleDark - }, - hover: { - foreground: grays.dark, - background: colors.yellow, - border: colors.yellow - }, - active: { - foreground: grays.dark, - background: colors.p5jsActivePink, - border: colors.p5jsActivePink + primary: { + default: { + foreground: grays.light, + background: grays.dark, + border: grays.middleDark + }, + hover: { + foreground: grays.dark, + background: colors.yellow, + border: colors.yellow + }, + active: { + foreground: grays.dark, + background: colors.p5jsActivePink, + border: colors.p5jsActivePink + }, + disabled: { + foreground: grays.light, + background: grays.dark, + border: grays.middleDark + } }, - disabled: { - foreground: grays.light, - background: grays.dark, - border: grays.middleDark + secondary: { + default: { + foreground: grays.dark, + background: colors.yellow, + border: colors.yellow + }, + hover: { + foreground: grays.dark, + background: colors.yellow, + border: colors.yellow + }, + active: { + foreground: grays.dark, + background: colors.p5jsActivePink, + border: colors.p5jsActivePink + }, + disabled: { + foreground: grays.light, + background: grays.dark, + border: grays.middleDark + } } }, Icon: { @@ -206,7 +295,8 @@ export default { }, Modal: { background: grays.dark, - border: grays.middleDark + border: grays.middleDark, + separator: grays.light }, Separator: grays.middleDark, @@ -216,6 +306,9 @@ export default { card: { background: grays.dark } + }, + Policy: { + link: colors.processingBlueLight } } }; diff --git a/package-lock.json b/package-lock.json index 7c5cd80c8a..8c714c448f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6158,12 +6158,47 @@ "source-map": "~0.6.1" } }, + "mdast-util-to-string": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-1.1.0.tgz", + "integrity": "sha512-jVU0Nr2B9X3MU4tSK7JP1CMkSvOj7X5l/GboG1tKRw52lLF1x2Ju92Ms9tNetCcbfX3hzlM73zYo2NKkWSfF/A==", + "dev": true + }, + "remark-slug": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/remark-slug/-/remark-slug-5.1.2.tgz", + "integrity": "sha512-DWX+Kd9iKycqyD+/B+gEFO3jjnt7Yg1O05lygYSNTe5i5PIxxxPjp5qPBDxPIzp5wreF7+1ROCwRgjEcqmzr3A==", + "dev": true, + "requires": { + "github-slugger": "^1.0.0", + "mdast-util-to-string": "^1.0.0", + "unist-util-visit": "^1.0.0" + } + }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, "optional": true + }, + "unist-util-visit": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-1.4.1.tgz", + "integrity": "sha512-AvGNk7Bb//EmJZyhtRUnNMEpId/AZ5Ph/KUpTI09WHQuDZHKovQ1oEv3mfmKpWKtoMzyMC4GLBm1Zy5k12fjIw==", + "dev": true, + "requires": { + "unist-util-visit-parents": "^2.0.0" + } + }, + "unist-util-visit-parents": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-2.1.2.tgz", + "integrity": "sha512-DyN5vD4NE3aSeB+PXYNKxzGsfocxp6asDc2XXE3b0ekO2BaRUpBicbbUygfSvYfUz1IkmjFR1YF7dPklraMZ2g==", + "dev": true, + "requires": { + "unist-util-is": "^3.0.0" + } } } }, @@ -10177,6 +10212,14 @@ "@types/node": "*" } }, + "@types/hast": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.4.tgz", + "integrity": "sha512-wLEm0QvaoawEDoTRwzTXp4b4jpwiJDvR5KMnFnVodm3scufTlBOWRD6N1OBf9TZMhjlNsSfcO5V+7AF4+Vy+9g==", + "requires": { + "@types/unist": "*" + } + }, "@types/history": { "version": "4.7.5", "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.5.tgz", @@ -10372,6 +10415,14 @@ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.5.tgz", "integrity": "sha512-7+2BITlgjgDhH0vvwZU/HZJVyk+2XUlvxXe8dFMedNX/aMkaOq++rMAFXc0tM7ij15QaWlbdQASBR9dihi+bDQ==" }, + "@types/mdast": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.10.tgz", + "integrity": "sha512-W864tg/Osz1+9f4lrGTZpCSO5/z4608eUp19tbozkq2HJK6i3z1kT0H9tlADXuYIb1YYOBByU4Jsqkk75q48qA==", + "requires": { + "@types/unist": "*" + } + }, "@types/mongodb": { "version": "3.6.12", "resolved": "https://registry.npmjs.org/@types/mongodb/-/mongodb-3.6.12.tgz", @@ -10533,8 +10584,7 @@ "@types/unist": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.3.tgz", - "integrity": "sha512-FvUupuM3rlRsRtCN+fDudtmytGO6iHJuuRKS1Ss0pG5z8oX0diNEw94UEL7hgDbpN94rgaK5R7sWm6RrSkZuAQ==", - "dev": true + "integrity": "sha512-FvUupuM3rlRsRtCN+fDudtmytGO6iHJuuRKS1Ss0pG5z8oX0diNEw94UEL7hgDbpN94rgaK5R7sWm6RrSkZuAQ==" }, "@types/webpack": { "version": "4.41.12", @@ -12685,8 +12735,7 @@ "bail": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz", - "integrity": "sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==", - "dev": true + "integrity": "sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==" }, "balanced-match": { "version": "1.0.0", @@ -13457,14 +13506,12 @@ "character-entities": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz", - "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==", - "dev": true + "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==" }, "character-entities-legacy": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz", - "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==", - "dev": true + "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==" }, "character-parser": { "version": "2.2.0", @@ -13478,8 +13525,7 @@ "character-reference-invalid": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz", - "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==", - "dev": true + "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==" }, "chardet": { "version": "0.7.0", @@ -13860,8 +13906,7 @@ "comma-separated-tokens": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz", - "integrity": "sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==", - "dev": true + "integrity": "sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==" }, "commander": { "version": "2.17.1", @@ -16060,29 +16105,31 @@ } }, "dom-helpers": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.1.4.tgz", - "integrity": "sha512-TjMyeVUvNEnOnhzs6uAn9Ya47GmMo3qq7m+Lr/3ON0Rs5kHvb8I+SQYjLUSYn7qhEm0QjW0yrBkvz9yOrwwz1A==", - "dev": true, + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", "requires": { "@babel/runtime": "^7.8.7", - "csstype": "^2.6.7" + "csstype": "^3.0.2" }, "dependencies": { "@babel/runtime": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.9.6.tgz", - "integrity": "sha512-64AF1xY3OAkFHqOb9s4jpgk1Mm5vDZ4L3acHvAml+53nO1XbXLuDodsVpO4OIUsmemlUHMxNdYMNJmsvOwLrvQ==", - "dev": true, + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.15.4.tgz", + "integrity": "sha512-99catp6bHCaxr4sJ/DbTGgHS4+Rs2RVd2g7iOap6SLGPDknRK9ztKNsE/Fg6QhSeh1FGE5f6gHGQmvvn3I3xhw==", "requires": { "regenerator-runtime": "^0.13.4" } }, + "csstype": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.9.tgz", + "integrity": "sha512-rpw6JPxK6Rfg1zLOYCSwle2GFOOsnjmDYDaBwEcwoOg4qlsIVCN789VkBZDJAGi4T07gI4YSutR43t9Zz4Lzuw==" + }, "regenerator-runtime": { - "version": "0.13.5", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz", - "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==", - "dev": true + "version": "0.13.9", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", + "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" } } }, @@ -20047,21 +20094,9 @@ } }, "github-slugger": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-1.3.0.tgz", - "integrity": "sha512-gwJScWVNhFYSRDvURk/8yhcFBee6aFjye2a7Lhb2bUyRulpIoek9p0I9Kt7PT67d/nUlZbFu8L9RLiA0woQN8Q==", - "dev": true, - "requires": { - "emoji-regex": ">=6.0.0 <=6.1.1" - }, - "dependencies": { - "emoji-regex": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-6.1.1.tgz", - "integrity": "sha1-xs0OwbBkLio8Z6ETfvxeeW2k+I4=", - "dev": true - } - } + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-1.4.0.tgz", + "integrity": "sha512-w0dzqw/nt51xMVmlaV1+JRzN+oCa1KfcgGEWhxUG16wbdA+Xnt/yoFO8Z8x/V82ZcZ0wy6ln9QDup5avbhiDhQ==" }, "glob": { "version": "7.1.4", @@ -21404,8 +21439,7 @@ "inline-style-parser": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz", - "integrity": "sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==", - "dev": true + "integrity": "sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==" }, "inquirer": { "version": "7.3.3", @@ -21713,14 +21747,12 @@ "is-alphabetical": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz", - "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==", - "dev": true + "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==" }, "is-alphanumerical": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz", "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==", - "dev": true, "requires": { "is-alphabetical": "^1.0.0", "is-decimal": "^1.0.0" @@ -21803,8 +21835,7 @@ "is-decimal": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz", - "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==", - "dev": true + "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==" }, "is-descriptor": { "version": "0.1.6", @@ -21901,8 +21932,7 @@ "is-hexadecimal": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz", - "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==", - "dev": true + "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==" }, "is-installed-globally": { "version": "0.3.2", @@ -26474,6 +26504,11 @@ } } }, + "js-cookie": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-2.2.1.tgz", + "integrity": "sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ==" + }, "js-levenshtein": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/js-levenshtein/-/js-levenshtein-1.1.6.tgz", @@ -28149,6 +28184,33 @@ "unist-util-visit": "^2.0.0" } }, + "mdast-util-from-markdown": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-0.8.5.tgz", + "integrity": "sha512-2hkTXtYYnr+NubD/g6KGBS/0mFmBcifAsI0yIWRiRo0PjVs6SSOSOdtzbp6kSGnShDN6G5aWZpKQ2lWRy27mWQ==", + "requires": { + "@types/mdast": "^3.0.0", + "mdast-util-to-string": "^2.0.0", + "micromark": "~2.11.0", + "parse-entities": "^2.0.0", + "unist-util-stringify-position": "^2.0.0" + }, + "dependencies": { + "parse-entities": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz", + "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==", + "requires": { + "character-entities": "^1.0.0", + "character-entities-legacy": "^1.0.0", + "character-reference-invalid": "^1.0.0", + "is-alphanumerical": "^1.0.0", + "is-decimal": "^1.0.0", + "is-hexadecimal": "^1.0.0" + } + } + } + }, "mdast-util-to-hast": { "version": "8.2.0", "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-8.2.0.tgz", @@ -28167,10 +28229,9 @@ } }, "mdast-util-to-string": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-1.1.0.tgz", - "integrity": "sha512-jVU0Nr2B9X3MU4tSK7JP1CMkSvOj7X5l/GboG1tKRw52lLF1x2Ju92Ms9tNetCcbfX3hzlM73zYo2NKkWSfF/A==", - "dev": true + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-2.0.0.tgz", + "integrity": "sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==" }, "mdn-data": { "version": "2.0.4", @@ -28181,8 +28242,7 @@ "mdurl": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", - "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=", - "dev": true + "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=" }, "media-typer": { "version": "0.3.0", @@ -28435,6 +28495,30 @@ "integrity": "sha512-jo1OfR4TaEwd5HOrt5+tAZ9mqT4jmpNAusXtyfNzqVm9uiSYFZlKM1wYL4oU7azZW/PxQW53wM0S6OR1JHNa2g==", "dev": true }, + "micromark": { + "version": "2.11.4", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-2.11.4.tgz", + "integrity": "sha512-+WoovN/ppKolQOFIAajxi7Lu9kInbPxFuTBVEavFcL8eAfVstoc5MocPmqBeAdBOJV00uaVjegzH4+MA0DN/uA==", + "requires": { + "debug": "^4.0.0", + "parse-entities": "^2.0.0" + }, + "dependencies": { + "parse-entities": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz", + "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==", + "requires": { + "character-entities": "^1.0.0", + "character-entities-legacy": "^1.0.0", + "character-reference-invalid": "^1.0.0", + "is-alphanumerical": "^1.0.0", + "is-decimal": "^1.0.0", + "is-hexadecimal": "^1.0.0" + } + } + } + }, "micromatch": { "version": "2.3.11", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", @@ -33831,7 +33915,6 @@ "version": "5.5.0", "resolved": "https://registry.npmjs.org/property-information/-/property-information-5.5.0.tgz", "integrity": "sha512-RgEbCx2HLa1chNgvChcx+rrCWD0ctBmGSE0M7lVm1yyv4UbvbrWoXp/BkVLZefzjrRBGW8/Js6uh/BnlHXFyjA==", - "dev": true, "requires": { "xtend": "^4.0.0" } @@ -34539,6 +34622,11 @@ "use-sidecar": "^1.0.1" } }, + "react-ga": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/react-ga/-/react-ga-3.3.0.tgz", + "integrity": "sha512-o8RScHj6Lb8cwy3GMrVH6NJvL+y0zpJvKtc0+wmH7Bt23rszJmnqEQxRbyrqUzk9DTJIHoP42bfO5rswC9SWBQ==" + }, "react-helmet": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/react-helmet/-/react-helmet-5.2.1.tgz", @@ -34673,6 +34761,41 @@ "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" }, + "react-markdown": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/react-markdown/-/react-markdown-6.0.3.tgz", + "integrity": "sha512-kQbpWiMoBHnj9myLlmZG9T1JdoT/OEyHK7hqM6CqFT14MAkgWiWBUYijLyBmxbntaN6dCDicPcUhWhci1QYodg==", + "requires": { + "@types/hast": "^2.0.0", + "@types/unist": "^2.0.3", + "comma-separated-tokens": "^1.0.0", + "prop-types": "^15.7.2", + "property-information": "^5.3.0", + "react-is": "^17.0.0", + "remark-parse": "^9.0.0", + "remark-rehype": "^8.0.0", + "space-separated-tokens": "^1.1.0", + "style-to-object": "^0.3.0", + "unified": "^9.0.0", + "unist-util-visit": "^2.0.0", + "vfile": "^4.0.0" + }, + "dependencies": { + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" + }, + "remark-parse": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-9.0.0.tgz", + "integrity": "sha512-geKatMwSzEXKHuzBNU1z676sGcDcFoChMK38TgdHJNAYfFtsfHDQG7MoJAjs6sgYMqyLduCYWDIWZIxiPeafEw==", + "requires": { + "mdast-util-from-markdown": "^0.8.0" + } + } + } + }, "react-popper": { "version": "1.3.7", "resolved": "https://registry.npmjs.org/react-popper/-/react-popper-1.3.7.tgz", @@ -34898,10 +35021,9 @@ } }, "react-transition-group": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.1.tgz", - "integrity": "sha512-Djqr7OQ2aPUiYurhPalTrVy9ddmFCCzwhqQmtN+J3+3DzLO209Fdr70QrN8Z3DsglWql6iY1lDWAfpFiBtuKGw==", - "dev": true, + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.2.tgz", + "integrity": "sha512-/RNYfRAMlZwDSr6z4zNKV6xu53/e2BuaBbGhbyYIXTrmgu/bGHzmqOs7mJSJBHy9Ud+ApHx3QjrkKSp1pxvlFg==", "requires": { "@babel/runtime": "^7.5.5", "dom-helpers": "^5.0.1", @@ -35907,37 +36029,56 @@ } } }, - "remark-slug": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/remark-slug/-/remark-slug-5.1.2.tgz", - "integrity": "sha512-DWX+Kd9iKycqyD+/B+gEFO3jjnt7Yg1O05lygYSNTe5i5PIxxxPjp5qPBDxPIzp5wreF7+1ROCwRgjEcqmzr3A==", - "dev": true, + "remark-rehype": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-8.1.0.tgz", + "integrity": "sha512-EbCu9kHgAxKmW1yEYjx3QafMyGY3q8noUbNUI5xyKbaFP89wbhDrKxyIQNukNYthzjNHZu6J7hwFg7hRm1svYA==", "requires": { - "github-slugger": "^1.0.0", - "mdast-util-to-string": "^1.0.0", - "unist-util-visit": "^1.0.0" + "mdast-util-to-hast": "^10.2.0" }, "dependencies": { - "unist-util-visit": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-1.4.1.tgz", - "integrity": "sha512-AvGNk7Bb//EmJZyhtRUnNMEpId/AZ5Ph/KUpTI09WHQuDZHKovQ1oEv3mfmKpWKtoMzyMC4GLBm1Zy5k12fjIw==", - "dev": true, + "mdast-util-definitions": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-4.0.0.tgz", + "integrity": "sha512-k8AJ6aNnUkB7IE+5azR9h81O5EQ/cTDXtWdMq9Kk5KcEW/8ritU5CeLg/9HhOC++nALHBlaogJ5jz0Ybk3kPMQ==", "requires": { - "unist-util-visit-parents": "^2.0.0" + "unist-util-visit": "^2.0.0" } }, - "unist-util-visit-parents": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-2.1.2.tgz", - "integrity": "sha512-DyN5vD4NE3aSeB+PXYNKxzGsfocxp6asDc2XXE3b0ekO2BaRUpBicbbUygfSvYfUz1IkmjFR1YF7dPklraMZ2g==", - "dev": true, + "mdast-util-to-hast": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-10.2.0.tgz", + "integrity": "sha512-JoPBfJ3gBnHZ18icCwHR50orC9kNH81tiR1gs01D8Q5YpV6adHNO9nKNuFBCJQ941/32PT1a63UF/DitmS3amQ==", "requires": { - "unist-util-is": "^3.0.0" + "@types/mdast": "^3.0.0", + "@types/unist": "^2.0.0", + "mdast-util-definitions": "^4.0.0", + "mdurl": "^1.0.0", + "unist-builder": "^2.0.0", + "unist-util-generated": "^1.0.0", + "unist-util-position": "^3.0.0", + "unist-util-visit": "^2.0.0" } } } }, + "remark-slug": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/remark-slug/-/remark-slug-6.1.0.tgz", + "integrity": "sha512-oGCxDF9deA8phWvxFuyr3oSJsdyUAxMFbA0mZ7Y1Sas+emILtO+e5WutF9564gDsEN4IXaQXm5pFo6MLH+YmwQ==", + "requires": { + "github-slugger": "^1.0.0", + "mdast-util-to-string": "^1.0.0", + "unist-util-visit": "^2.0.0" + }, + "dependencies": { + "mdast-util-to-string": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-1.1.0.tgz", + "integrity": "sha512-jVU0Nr2B9X3MU4tSK7JP1CMkSvOj7X5l/GboG1tKRw52lLF1x2Ju92Ms9tNetCcbfX3hzlM73zYo2NKkWSfF/A==" + } + } + }, "remark-squeeze-paragraphs": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/remark-squeeze-paragraphs/-/remark-squeeze-paragraphs-4.0.0.tgz", @@ -36075,8 +36216,7 @@ "replace-ext": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz", - "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=", - "dev": true + "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=" }, "request": { "version": "2.88.2", @@ -37604,8 +37744,7 @@ "space-separated-tokens": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz", - "integrity": "sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==", - "dev": true + "integrity": "sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==" }, "sparse-bitfield": { "version": "3.0.3", @@ -38291,7 +38430,6 @@ "version": "0.3.0", "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.3.0.tgz", "integrity": "sha512-CzFnRRXhzWIdItT3OmF8SQfWyahHhjq3HwcMNCNLn+N7klOOqPjMeG/4JSu77D7ypZdGvSzvkrbyeTMizz2VrA==", - "dev": true, "requires": { "inline-style-parser": "0.1.1" } @@ -39369,8 +39507,7 @@ "trough": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.5.tgz", - "integrity": "sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==", - "dev": true + "integrity": "sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==" }, "true-case-path": { "version": "1.0.3", @@ -39588,7 +39725,6 @@ "version": "9.0.0", "resolved": "https://registry.npmjs.org/unified/-/unified-9.0.0.tgz", "integrity": "sha512-ssFo33gljU3PdlWLjNp15Inqb77d6JnJSfyplGJPT/a+fNRNyCBeveBAYJdO5khKdF6WVHa/yYCC7Xl6BDwZUQ==", - "dev": true, "requires": { "bail": "^1.0.0", "extend": "^3.0.0", @@ -39601,14 +39737,12 @@ "is-buffer": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", - "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", - "dev": true + "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==" }, "is-plain-obj": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", - "dev": true + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==" } } }, @@ -39663,14 +39797,12 @@ "unist-builder": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/unist-builder/-/unist-builder-2.0.3.tgz", - "integrity": "sha512-f98yt5pnlMWlzP539tPc4grGMsFaQQlP/vM396b00jngsiINumNmsY8rkXjfoi1c6QaM8nQ3vaGDuoKWbe/1Uw==", - "dev": true + "integrity": "sha512-f98yt5pnlMWlzP539tPc4grGMsFaQQlP/vM396b00jngsiINumNmsY8rkXjfoi1c6QaM8nQ3vaGDuoKWbe/1Uw==" }, "unist-util-generated": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/unist-util-generated/-/unist-util-generated-1.1.5.tgz", - "integrity": "sha512-1TC+NxQa4N9pNdayCYA1EGUOCAO0Le3fVp7Jzns6lnua/mYgwHo0tz5WUAfrdpNch1RZLHc61VZ1SDgrtNXLSw==", - "dev": true + "integrity": "sha512-1TC+NxQa4N9pNdayCYA1EGUOCAO0Le3fVp7Jzns6lnua/mYgwHo0tz5WUAfrdpNch1RZLHc61VZ1SDgrtNXLSw==" }, "unist-util-is": { "version": "3.0.0", @@ -39681,8 +39813,7 @@ "unist-util-position": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-3.1.0.tgz", - "integrity": "sha512-w+PkwCbYSFw8vpgWD0v7zRCl1FpY3fjDSQ3/N/wNd9Ffa4gPi8+4keqt99N3XW6F99t/mUzp2xAhNmfKWp95QA==", - "dev": true + "integrity": "sha512-w+PkwCbYSFw8vpgWD0v7zRCl1FpY3fjDSQ3/N/wNd9Ffa4gPi8+4keqt99N3XW6F99t/mUzp2xAhNmfKWp95QA==" }, "unist-util-remove": { "version": "2.0.0", @@ -39714,7 +39845,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz", "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==", - "dev": true, "requires": { "@types/unist": "^2.0.2" } @@ -39723,7 +39853,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", - "dev": true, "requires": { "@types/unist": "^2.0.0", "unist-util-is": "^4.0.0", @@ -39733,8 +39862,7 @@ "unist-util-is": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", - "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==", - "dev": true + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" } } }, @@ -39742,7 +39870,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", - "dev": true, "requires": { "@types/unist": "^2.0.0", "unist-util-is": "^4.0.0" @@ -39751,8 +39878,7 @@ "unist-util-is": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", - "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==", - "dev": true + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" } } }, @@ -40125,7 +40251,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.1.0.tgz", "integrity": "sha512-BaTPalregj++64xbGK6uIlsurN3BCRNM/P2Pg8HezlGzKd1O9PrwIac6bd9Pdx2uTb0QHoioZ+rXKolbVXEgJg==", - "dev": true, "requires": { "@types/unist": "^2.0.0", "is-buffer": "^2.0.0", @@ -40137,8 +40262,7 @@ "is-buffer": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", - "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", - "dev": true + "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==" } } }, @@ -40152,7 +40276,6 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz", "integrity": "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==", - "dev": true, "requires": { "@types/unist": "^2.0.0", "unist-util-stringify-position": "^2.0.0" diff --git a/package.json b/package.json index 1610f4e935..02be81e35e 100644 --- a/package.json +++ b/package.json @@ -179,6 +179,7 @@ "i18next-http-backend": "^1.0.21", "is-url": "^1.2.4", "jest-express": "^1.11.0", + "js-cookie": "^2.2.1", "jsdom": "^9.8.3", "jshint": "^2.11.0", "lodash": "^4.17.21", @@ -205,20 +206,24 @@ "react": "^16.12.0", "react-dom": "^16.12.0", "react-final-form": "^6.5.2", + "react-ga": "^3.3.0", "react-helmet": "^5.1.3", "react-hot-loader": "^4.12.19", "react-i18next": "^11.5.0", + "react-markdown": "^6.0.3", "react-redux": "^7.2.0", "react-responsive": "^8.1.0", "react-router": "^3.2.5", "react-split-pane": "^0.1.89", "react-tabs": "^2.3.1", + "react-transition-group": "^4.4.2", "redux": "^3.7.2", "redux-auth-wrapper": "^2.1.0", "redux-devtools": "^3.4.2", "redux-devtools-dock-monitor": "^1.1.3", "redux-devtools-log-monitor": "^1.4.0", "redux-thunk": "^2.3.0", + "remark-slug": "^6.1.0", "reselect": "^4.0.0", "s3-policy-v4": "0.0.3", "sass-extract": "^2.1.0", diff --git a/public/code-of-conduct.md b/public/code-of-conduct.md new file mode 100644 index 0000000000..86617178d7 --- /dev/null +++ b/public/code-of-conduct.md @@ -0,0 +1,51 @@ +# p5.js Community Statement + +p5.js is a community interested in exploring the creation of art and design with technology. + +We are a community of, and in solidarity with, people from every gender identity and expression, sexual orientation, race, ethnicity, language, neuro-type, size, disability, class, religion, culture, subculture, political opinion, age, skill level, occupation, and background. We acknowledge that not everyone has the time, financial means, or capacity to actively participate, but we recognize and encourage involvement of all kinds. We facilitate and foster access and empowerment. We are all learners. + +We like these hashtags: #noCodeSnobs (because we value community over efficiency), #newKidLove (because we all started somewhere), #unassumeCore (because we don't assume knowledge), and #BlackLivesMatter (because of course). + +In practice: +* We are not code snobs. We do not assume knowledge or imply there are things that somebody should know. +* We insist on actively engaging with requests for feedback regardless of their complexity. +* We welcome newcomers and prioritize the education of others. We strive to approach all tasks with the enthusiasm of a newcomer. Because we believe that newcomers are just as valuable in this effort as experts. +* We consistently make the effort to actively recognize and validate multiple types of contributions. +* We are always willing to offer help or guidance. + +In times of conflict: +* We listen. +* We clearly communicate while acknowledging other's feelings. +* We admit when we're wrong, apologize, and accept responsibility for our actions. +* We are continuously seeking to improve ourselves and our community. +* We keep our community respectful and open. +* We make everyone feel heard. +* We are mindful and kind in our interactions. + +In the future: +* The future is now. + + +## p5.js Code of Conduct + +* **Be mindful of your language.** Any of the following behavior is unacceptable: + * Offensive comments related to gender identity and expression, sexual orientation, race, ethnicity, language, neuro-type, size, ability, class, religion, culture, subculture, political opinion, age, skill level, occupation, or background + * Threats of violence + * Deliberate intimidation + * Sexually explicit or violent material that is not contextualized and preceded by a considerate warning + * Unwelcome sexual attention + * Stalking or following + * Or any other kinds of harassment + + Use your best judgement. If it will possibly make others uncomfortable, do not post it. + +* **Be respectful.** Disagreement is not an opportunity to attack someone else's thoughts or opinions. Although views may differ, remember to approach every situation with patience and care. +* **Be considerate.** Think about how your contribution will affect others in the community. +* **Be open minded.** Embrace new people and new ideas. Our community is continually evolving and we welcome positive change. + +If you believe someone is violating the code of conduct, we ask that you report it by emailing [hello@p5js.org](mailto:hello@p5js.org). Please include your name and a description of the incident, and we will get back to you ASAP. + +Sometimes, participants violating the Code of Conduct are unaware that their behavior is harmful, and an open conversation clears things up to move forward. However, if a participant continues with the behavior, the p5.js team may take any action they deem appropriate, up to and including expulsion from all p5.js spaces and identification of the participant as a harasser to other p5.js members or the general public. + +--- +This statement is licensed under a [Creative Commons license](https://creativecommons.org/licenses/by-sa/4.0/). Please feel free to share and remix with attribution. \ No newline at end of file diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 0000000000..b8a929e565 Binary files /dev/null and b/public/favicon.ico differ diff --git a/public/privacy-policy.md b/public/privacy-policy.md new file mode 100644 index 0000000000..6d2bd4b7d4 --- /dev/null +++ b/public/privacy-policy.md @@ -0,0 +1,313 @@ +# p5.js Editor Privacy Policy + + +The Processing Foundation knows that you value your privacy. Your privacy is important to the Processing Foundation, too. This “Privacy Policy” focuses and covers the data practices of editor.p5js.org, including any content, functionality, and services offered on or through editor.p5js.org (“p5.js Editor” or “Website"), the Website on which this policy is posted, which is owned and operated by the Processing Foundation. This Privacy Policy is designed to tell you about our practices regarding collection, use, and disclosure of information that you may provide via the Website. Please take a moment to read our privacy practices and contact the Processing Foundation with any questions or concerns. + +Each time you access the Website, the current version of this policy will apply. Policy changes will be reflected on this page. Users will be notified and are required to accept all changes to this policy in order to access the Website. The Processing Foundation still encourages you to regularly check the date of this policy and review any changes made since the last time you used the Website. + +Effective date: **February 1, 2021** + +______________________________________________________________________ + +1. [What Information May We Collect?](#what-information-may-we-collect) +2. [Automatic Collection of Data](#automatic-collection-of-data) +3. [How we May Use The Information We Collect From You](#how-we-may-use-the-information-we-collect-from-you) +4. [Who Do We Share Personal Data With?](#who-do-we-share-personal-data-with) +5. [Limitations On Data Retention ](#limitations-on-data-retention) +6. [Security For Your Information](#security-for-your-information) +7. [COPPA: Data Collection for Children Under 13](#coppa-data-collection-for-children-under-13) +8. [GDPR: European Union User’s Rights](#gdpr-european-union-users-rights) +9. [Your Choices As A User From The United States](#your-choices-as-a-user-from-the-united-states) +10. [Ways You Can Control Information That Is Collected](#ways-you-can-control-information-that-is-collected) +11. [How We Respond To "Do Not Track" Signals](#how-we-respond-to-do-not-track-signals) +12. [Contact Information](#contact-information) +______________________________________________________________________ + + +## What Information May We Collect? + + +### Generally + +In order to allow p5.js Editor to function and provide the services therein, we collect information. Some information you provide directly to us through the website and some may be collected from third parties. Some of the information we collect will be personally identifiable information, which is information that identifies you, or can be combined with other data, to identify you as a specific individual. + + +### Personal information + +We collect information you provide to us. + +For example, we collect information when you create an account, request support, or otherwise communicate with us. + +The types of personal information you may provide includes: + + + +* Contact information (such as name and email address); +* Payment information (including billing address, and bank account information); and +* Account log-in credentials (username, password). + +We may also collect other information from or about you, such as information provided while donating, your interests, and demographic information. You may also provide us with additional information. + + +### Email information retained + +If you choose to correspond with us through our Website or via email, we may retain the content of your email together with your email address, other included information, and our responses. + + +## Automatic Collection of Data + +Through p5.js Editor, we may automatically collect information about your interactions with the Website, as well as devices on which the Website is used and accessed. This data is necessary for p5.js to work as intended, including our ability to update and facilitate the services within. + + +### Device Information + +When you visit the Website, we may collect certain information from you, including your Internet Protocol (IP) address, the date and time of your visit, browser type, operating system, referral URL, the specific web pages visited during your connection, and the domain name from which you accessed the Website. In addition, we may collect information about your browsing behavior, such as the date and time you visit the Website, the areas or pages of the Website that you visit, the amount of time you spend viewing the Website, the number of times you return to the Website and other clickstream data. + + +### Information from the use of the service + +When you visit the Website, we may track how, and how often you use our Website, including which menus you use, pages you view, or search results you click on. You may interact with our support team during the use of our Website, in which case, we would collect information about your communications. We may also use non-personal information for statistical analysis, research, and other purposes. + + +### Cookies + +Like many commercial websites, we may analyze how visitors use our Website through what is known as “cookie” technology. A cookie is a small text file that is placed on your computer when you access the Website and allows us to recognize you each time you visit the Website. We may use cookies to: (1) enhance or personalize your Website usage; (2) monitor Website usage; (3) manage the Website; and (4) improve the Website. If you choose, you can set your browser to reject cookies or you can manually delete individual or all of the cookies on your computer by following your browser’s help file directions. However, if your browser is set to reject cookies or you manually delete cookies, you may have some trouble accessing and using some of the pages and features that are currently on our Website, or that we may put on our Website in the future. + + +### Web Beacons + +We may also use web beacons on the Website, in our emails, and in our advertisements on other websites. Web beacons are tiny graphic images that are used to collect information about your Website visit, such as the pages you view and the features you use, as well as information about whether you open and/or act upon one of our emails or advertisements. We may also collect the URL or the website you visited immediately before coming to Website. Web beacons help us analyze our Website’s visitors’ behavior and measure the effectiveness of the Website and our advertising. We may work with service providers that help us track, collect, and analyze this and other site usage information. + + +### Combining Information + +We may combine any information we collect, including through cookies and web beacons, with other information we have collected from your use of the Website. + + +### Information sent by your mobile device + +p5.js Editor is accessible from mobile devices. The Processing Foundation may collect certain information that your mobile device sends when you use the Website, like a device identifier, user settings, and the operating system of your device, as well as information about your use of the Website while using your mobile device. + + +### Location information + +Through p5.js Editor, the Processing Foundation may collect and store information about your location when you use the Website and take actions that use the location services made available through your device’s mobile operating system. We may also use location information to improve and personalize the Website for you. + + +### Public profile information + +You may update or modify your profile information and contact information at any time. including removing it from the Website. Profile information may be available publicly on our Website, such as on your profile page or when you share content. In addition to using your contact information to create your account, we may use this information to send you information about our Website, respond to your requests and facilitate use of the Website. + + +## How We May Use The Information We Collect From You + +Although the Processing Foundation may use user information in any way not specifically limited by any governing laws, terms and this Privacy Policy, it is useful to understand how the Processing Foundation typically uses the information collected from users, such as: + + + +* To present p5.js Editor and its content to you; +* Improving p5.js Editor or building new services; +* Personalizing your experience; +* Fulfilling your requests; +* Providing support; +* Creating backups and allow for disaster recovery; +* Complying with legal obligations; +* Facilitating research and studying your information if it is aggregated with others; +* Troubleshooting p5.js Editor or enforcing our terms of service and privacy policy; +* Sending you account notifications and updates about your account; +* Encouraging feedback; +* Maintaining User Accounts; +* Detecting and protecting against error, fraud, malicious activity, or other suspicious or criminal activity; +* Authenticating your identity and access to p5.js Editor; +* Transmitting information to a third party that you authorize to receive your Personal Information through p5.js Editor; +* Creating an export of your Personal Information based on your authorization; +* To fulfill any other purpose for which you provide it. + + +### Successors in interest + +The Processing Foundation may also disclose and transfer your personal information to any successors-in-interest in the unlikely event that the Processing Foundation is acquired by, sold to, merged with, or transferred to a third-party. Some or all of your personal information provided to the Processing Foundation could be amongst the assets transferred. Processing Foundation will make reasonable efforts to give users the opportunity to opt out of any such transfer if the new entity’s planned processing of your information differs materially from that set forth in this privacy policy. + + +## Who Do We Share Personal Data With? + +The Processing Foundation, through p5.js Editor, has the right to disclose, share, or transfer your personal information to others in such cases described below: + + + +* We may share your information with third parties, but only to the extent necessary to provide you with the Website. +* We may share your information with employees or contractors of the Processing Foundation, but only to assist them in fulfilling their functions as employees or contractors. +* When you give your consent to do so. For example, when we tell you that the information you provide will be shared in some way and you provide us that information. +* When we are authorized or legally required to do so or that doing so is necessary or appropriate to comply with the law or legal processes or to respond to lawful requests or legal authorities, including but not limited to subpoenas, warrants, or court orders. +* In connection with any merger, transfer or sale of company assets, financing, acquisition, or similar transaction or circumstance, your information to any successors-in-interest in the unlikely event that the Processing Foundation is acquired by, sold to, merged with, or transferred to a third-party, some or all of your personal information provided to the Processing Foundation could be amongst the assets transferred. +* To enforce or apply our Privacy Policy, our [Terms of Use](https://editor.p5js.org/terms-of-use) or our other policies or agreements. + + +### Sharing content with Third Party Services + +We are not in the business of selling or leasing your information. There are, however, a few limited ways that we share some of the information p5.js Editor collects with others that you should be aware of, as follows: + +p5.js Editor includes features that allow users to communicate with the Website in a variety of ways. Any personally identifiable information that you voluntarily choose to share through p5.js Editor, or in a publicly accessible area on the Website, such as by submitting your content to the Showcase, will be available to other users who access that content. Once you make your personal information available in this way, We cannot control how the recipient uses that Content. + + +### Third Party Service Providers for p5.js Editor + +We work with third party services to provide website development, hosting, and maintenance as well as other services for Us. Only to the extent it is necessary for these service providers to complete their contractual obligations to Us, these third parties may have access to or process limited amounts of your personally identifiable information. Below is a list of some of the main service providers which, subject to their terms of service and privacy policies as linked below, may have access to personal information to process on Our behalf in accordance with Our instructions, Privacy Policy and any other requirements regarding confidentiality, security or integrity: + + + +* [Google Analytics & Google Cloud Engine](https://policies.google.com/privacy?hl=en_US) (Hosting) +* [MongoDB Atlas](https://www.mongodb.com/legal/privacy-policy) +* [Cloudflare](https://www.cloudflare.com/privacypolicy/) +* [Mailgun](https://www.mailgun.com/privacy-policy/) +* [Amazon AWS (S3)](https://aws.amazon.com/privacy/?nc1=f_pr) +* [DockerHub](https://www.docker.com/legal/privacy) +* [GitHub](https://docs.github.com/en/github/site-policy/github-privacy-statement) +* [Release](https://releasehub.com/) +* [BrowserStack](https://www.browserstack.com/) + + +### External sites that the Website links to are not subject to this policy + +P5.js Editor may feature direct integration with a variety of social networking services such as Twitter or Facebook, enabling users to share their creations. The choice to share content with these services is an optional feature for users of p5.js Editor. We will only share information with social networking services that the user chooses to share. Users are responsible for the content they choose to share, and are bound by the respective terms of service and privacy policy for each social networking service. The Processing Foundation has no responsibility to provide or maintain integration with any particular third party service and p5.js. + + +## Limitations On Data Retention + +The Processing Foundation may keep your data as long as is permitted or required under the law. Additionally, data may be retained, backed up, and used in our system to satisfy any of the authorized uses under this Privacy Policy. For example, the Processing Foundation may use retained data to prevent, investigate, or identify possible wrongdoing in connection with p5.js or to comply with legal obligations. Please note that information may exist in backup storage even after it has been removed from the Processing Foundation’s active databases. + + +## Security For Your Information + +Through p5.js Editor, the Processing Foundation takes reasonable measures designed to protect the information that is collected from or about you from accidental or unlawful destruction, accidental loss or unauthorized access, use, modification, interference, or disclosure. Please be aware, however, that no method of transmitting information over the internet or storing information is completely secure. Accordingly, the Processing Foundation cannot guarantee the absolute security of any information. If you have questions about security or possible reason to believe that your interaction with our Website is no longer secure (e.g., you feel that your account’s security may be compromised), please contact us immediately. + + +### Account safety + +We recommend sharing personal information only with individuals and other third parties that you know and trust. In addition, we urge you to take precautionary measures in maintaining the integrity of your data. Please be responsible in making sure no one can see or has access to your personal accounts and log-in username and password information. If you use a public computer, such as the library or a university, or a shared device, always remember to log out of the Website. + +If you access p5.js Editor through your employer’s computer network or through an internet café, library or other potentially non-secure internet connection, such use is at your own risk. It is your responsibility to check beforehand with the company’s privacy and security policy with respect to Internet use. + + +### Your data may be transferred to different jurisdictions + +The Processing Foundation may choose to use multiple servers and computers to store information obtained through p5.js Editor. The Processing Foundation may transfer your information to servers outside of your state or country of residence. Due to technological limitations, the Processing Foundation cannot guarantee absolute security at all times. By using the Website, you are consenting to the transfer of your data to out-of-state and out-of-country servers. + + +## COPPA: Data Collection For Children Under 13 + +The Processing Foundation is a non-profit organization under 501(c)(3) of the US Internal Revenue code. Because of this designation, the Children’s Online Privacy Protection Act of 1998 and its rules (collectively, “COPPA”) **do not** apply to us or our Website. (For more information, feel free to look at the FTC’s [FAQ page](https://www.ftc.gov/tips-advice/business-center/guidance/complying-coppa-frequently-asked-questions-0).) + +However, we still care about the privacy rights and security of our user’s data, and want to inform parents and legal guardians (“Parents”) about our practices for collecting, using, and disclosing personal information from children under the age of 13 (“children”). + +This section notifies parents of: + + + +* The types of information we may collect from children; +* How we use the information we collect from children; and +* How Parents can request access to, correction of, or a limitation of data collection. + +This section only applies to children under the age of 13 and supplements our general privacy policy shown here. + + +### Information We Collect from Children + +When a child creates an account, We suggest Parents, and school districts where applicable, thoroughly read and familiarize themselves with this Privacy Policy and our Terms of Use. We may ask for information, including identifiable information, to personalize and improve your child’s use of p5.js Editor. As described above, p5.js Editor may also use cookies to enable your child to sign in, to help personalize the Website, and to help the Processing Foundation administer the Website. + + +### Accessing and Correcting Your Child’s Personal Information + +Parents and authorized school officials may request to review the child’s personal information maintained by us, request we correct or delete the personal information, and/or request we halt any further collection or use of your child’s information. + +You can review, change, or delete your child’s personal information by: + + + +* Logging into your child’s account and visiting his or her account profile page. +* Sending us an email at [privacy@p5js.org](mailto:privacy@p5js.org). + +To protect your child’s privacy and security, we may require you to take certain steps or provide additional information to verify your identity and relationship with the child before we provide any information to make corrections. + + +## GDPR: European Union User’s Rights + +If you are within the European Union, the following may apply: + + +### Rights to access and correct + +You may be entitled to certain information and have certain rights under the General Data Protection Regulation as it applies to your data. You may have the right to request access to your data that the Processing Foundation stores. You may have the right to either correct or request deletion of your personal data from our Website. Be aware that nothing can be completely removed from the Internet. The Processing Foundation will take reasonable steps, as required by law, to honor any request for deletion of your personal information from our Website, but we cannot and do not guarantee that your data will be entirely removed. The Processing Foundation is not responsible for third parties’ policies, practices, or compliance regarding your data. If you provide third parties with personal data and wish to have it removed, you must contact those parties directly. + +For any requests, contact us here: [privacy@p5js.org](mailto:privacy@p5js.org) + + +### Right to remove + +You may have the right to seek restrictions on the Processing Foundation’s processing of your data. To the extent that you provided consent to the Processing Foundation’s processing of your personal data, you have the right to withdraw that consent. For EU Users, the Processing Foundation requires only the information that is reasonably necessary to provide you with our Website. + +For any requests, contact us here: [privacy@p5js.org](mailto:privacy@p5js.org) + + +### Small-business exception under Article 30(5) + +The Processing Foundation employs less than 250 people. Accordingly, the Processing Foundation is exempt from Article 30(1) & (2), which requires organizations to “maintain a record of processing activities under its responsibility.” + + +## Your Choices As A User From The United States + +The Processing Foundation is a non-profit organization under 501(c)(3) of the US Internal Revenue code. Because of this, data laws such as the CCPA **do not** apply. However, we still care about the privacy rights and security of our user’s data, and want to inform users of possible choices regarding the collection, use, and sharing of data. Contact the Processing Foundation here, [privacy@p5js.org](mailto:privacy@p5js.org), with any remaining questions, comments, or requests. + +Please note that if you decide not to provide the Processing Foundation with the information that is requested, you may not be able to access some or all of the features of the Website. + + +### Rescinding your consent + +You may have the right to refuse further collection, use, and/or disclosure of your information by notifying the Processing Foundation of your rescission of consent. If you have consented to your access to and use of the Website, but wish to rescind such consent, please contact the Processing Foundation at the contact information below with the request. + +The Processing Foundation will, within a reasonable amount of time, discontinue your access to and use of the Website such that no additional information may be collected. Please note, however, that if you refuse further collection, use, and/or disclosure of your information, you may not be able to access and use all or a portion of the Website. + + +### Requests to delete your data + +In applicable jurisdictions, you may have the right to request that the Processing Foundation delete data collected from you. The Processing Foundation will comply with such requests in a reasonable time as required by law. However, to the extent allowed in the jurisdiction, the Processing Foundation may still retain some or all of your data in order to: (a) comply with state and federal law, (b) to prevent or assist in the prosecution of criminal or illegal conduct, (c) fulfil its service to you and complete your transactions with the Processing Foundation, (d) diagnose, debug, or otherwise repair problems related to our Website, and (e) whenever necessary to protect or ensure the privacy of your data. + + +### Notice to California users + +Under Cal. Civ. Code § 1798.80, a user residing in the State of California has the right to request from the Processing Foundation a list of all third parties to which the Processing Foundation has disclosed personal information during the preceding year for direct marketing purposes (if any). For questions about this policy, please contact the Processing Foundation using the contact information provided. + + +## Ways You Can Control Information That Is Collected + +We strive to provide you with choices regarding the Personal Information you provide to us. The following are some ways you may have control over your information: + + +### Tracking technologies + +You can set your browser to refuse all or some browser cookies, or to alert you when cookies are being sent. If you disable or refuse cookies, please note that some parts of the Website may then be inaccessible or not function properly. + + +### Location + +Mobile browsers may collect real-time information about the location of your device for geo-fencing, mileage tracking, or similar purposes. If you do not want us to collect this information, you may decline our request or disable location services in your mobile device’s settings, if requested. However, opting out of the collection of location information will cause location-based features to be disabled and the online and/or mobile browsing may not function properly. + + +### Analytics + +We may use third-party web analytics (Google Analytics) to better understand the users that interact with our Website. You can opt out of analytics by installing the [Google Analytics Opt-out Browser Add-on](https://tools.google.com/dlpage/gaoptout), which prohibits data transmission to Google Analytics. + + +### Promotional offers from the Processing Foundation + +If you do not wish to have your email address or other contact information used by the Processing Foundation to promote our own yearly donation drive and other promotional events, you can contact us to opt-out. If we have sent you a promotional email, you may opt out using the unsubscribe or opt-out link in the email, if applicable, or by sending us a return email asking to be omitted from future email distributions. This opt out does not apply to information provided to p5.js as a result of your use of the Website or other transactions. + + +## How We Respond To "Do Not Track" Signals + +Your online browser settings may allow you to automatically transmit a “Do Not Track” signal to websites and online services you visit. Our Website does not respond to a “Do Not Track” signal from a visitor’s browser because this [browser feature has been deprecated](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/doNotTrack). If you would like to find out more about “Do Not Track,” please visit [www.allaboutdnt.com](http://www.allaboutdnt.com). + + +## Contact information + +To ask questions or comment about this privacy policy and our privacy practices, contact us at: [privacy@p5js.org](mailto:privacy@p5js.org) diff --git a/public/terms-of-use.md b/public/terms-of-use.md new file mode 100644 index 0000000000..2302ab3e1f --- /dev/null +++ b/public/terms-of-use.md @@ -0,0 +1,297 @@ +# p5.js Editor Terms of Use + +These terms of use are entered into by and between You and the Processing Foundation ("Processing Foundation," "We," “Our,” or "Us"). The following terms and conditions ("Terms of Use") constitute a contractual agreement (“Agreement”) between You and the Processing Foundation. The Agreement governs access to and use of p5js.org, including any content, functionality, and services offered on or through p5js.org (“p5.js” or "Website"), and applies to anyone who uses the Website (referred to as “Users”, “User”, “You”, or “Your” as applicable). + +Please read the Terms of Use carefully before You start to use the Website. By using the Website as a guest or by creating an account and clicking to accept and agree to the Terms of Use when this option is made available to you, You accept and agree to be bound and abide by these Terms of Use and our Privacy Policy, found at [https://editor.p5js.org/privacy-policy](https://editor.p5js.org/privacy-policy), incorporated herein by reference. **If you do not want to agree to these Terms of Use or Privacy Policy, you must not access or use the Website**. + +**The Effective Date of this Agreement is February 1, 2021** + +______________________________________________________________________ + + + +1. [Modifications to the Terms of Use](#modifications-to-the-terms-of-use) +2. [Data Collection and Use](#data-collection-and-use) +3. [Integration with Third-Party Services](#integration-with-third-party-services) +4. [Accessing the Website and Account Security](#accessing-the-website-and-account-security) +5. [General Conditions](#general-conditions) +6. [User Contributions](#user-contributions) +7. [Content Standards](#content-standards) +8. [Prohibited Uses](#prohibited-uses) +9. [End User Licenses](#end-user-licenses) +10. [DMCA Infringement Notices](#dmca-infringement-notices) +11. [Indemnification](#indemnification) +12. [Limitation on Liability](#limitation-on-liability) +13. [Dispute Resolution](#dispute-resolution) +14. [Waiver and Severability](#waiver-and-severability) +15. [Entire Agreement](#entire-agreement) +16. [Your Comments and Concerns](#your-comments-and-concerns) + +______________________________________________________________________ + + +## Modifications to the Terms of Use + +We reserve the right, in Our sole discretion, to modify or add to this Agreement at any time, for any reason (“Updated Terms”). The Updated Terms shall be included in a revised version of this Agreement accessible through the Website. We may provide notice of significant changes to this Agreement as required by law. + +Your continued use of the Website as a guest, or by creating an account and clicking to accept and agree to the Updated Terms when this option is made available to you, following the posting of any Updated Terms constitutes Your unconditional acceptance and agreement to be bound by those changes. If You do not agree to be bound by the Updated Terms You must cease using the Website immediately, or when prompted, do not click accept. + +The Updated Terms will be effective as of the time of posting, or such later date as may be specified in the Updated Terms, and will apply to Your use of the Website from that point forward. + + +## Data Collection and Use + + +### Acknowledgement of Our Privacy Policy + +You expressly consent to the use and disclosure of personally identifiable information and other data and information as described in this Privacy Policy. Notwithstanding anything in the Privacy Policy, the Processing Foundation shall have the right to collect, extract, compile, synthesize, and analyze non-personally identifiable data or information (data or information that does not identify an entity or natural person as the source) resulting from Your access to and use of the Website. To the extent any such data or information is collected or generated by p5.js, the data and information will be solely owned by the Processing Foundation. + + +### International Storage + +The Processing Foundation may access or store personal information in multiple countries and states, including countries and states outside of Your own country or state to the extent permitted by applicable law. + + + + +### Communications Required by Law + +The Processing Foundation may be required by law to send You communications about the Website or third-party products. You agree that We may send these communications via email or by posting them on p5.js or by messaging You directly via email or the Website. + + +## Integration with Third-Party Services + +The Website may connect to other websites and other third party services. Before using any third-party integrations, You are encouraged to review their terms of use and to review personal and technical security of the product or service that is the subject of the integration. The Processing Foundation shall rely on the fact that You have reviewed those materials and consented to their terms in their entirety. + +The Processing Foundation shall not be held liable to and shall not accept any liability, obligation or responsibility whatsoever for any loss or damage in connection with the third-party integrations. We have no control over such third parties and are not responsible for the content of their services. We provide You with third party integrations only for Your convenience. This does not imply any endorsement or any association with such third parties. We do not warrant the use of the third-party integrations will be uninterrupted or error free. Any concern regarding the third-party services should be directed to the responsible third party. + +By using any of third-party integrations, You agree that We may allow the providers of those third-party applications access to Your data as required for the integration of such third-party applications with Our Website. We shall not be responsible for any disclosure, modification or deletion of Your data resulting from any such access by third-party application providers. + +By using any of third party integrations, You acknowledge and agree that: + + + +* The Processing Foundation may transfer necessary data to the providers of those third-party applications; +* The Processing Foundation shall not be held liable to and shall not accept any liability, obligation or responsibility whatsoever for any loss or damage in connection with the data We provide to such third parties. + +**User accepts and understands this risk and waives all rights to hold the Processing Foundation responsible in any way, financially or otherwise, for third party errors and results.** + + +## Accessing the Website and Account Security + +We reserve the right to withdraw or amend this Website, and any service or material we provide on the Website, in Our sole discretion without notice. We will not be liable if for any reason all or any part of the Website is unavailable at any time or for any period. From time to time, we may restrict access to some parts of the Website, or the entire Website, to Users, including registered Users. + +You are responsible for both: + + + +* Making all arrangements necessary for You to have access to the Website. +* Ensuring that all persons who access the Website through Your internet connection are aware of these Terms of Use and comply with them. + +To access the Website or some of the resources it offers, You may be asked to provide certain registration details or other information. It is a condition of Your use of the Website that all the information You provide on the Website is correct, current, and complete. You agree that all information You provide, directly and indirectly, when creating an account on p5.js, including, but not limited to, Your name, email, and device information, is governed by Our _[Privacy Policy](https://editor.p5js.org/privacy-policy)_, and You consent to all actions we take with respect to Your information consistent with Our Privacy Policy. + +If You choose, or are provided with, a username, password, or any other piece of information as part of our security procedures, You must treat such information as confidential, and You must not disclose it to any other person or entity. You also acknowledge that Your account is personal to You and agree not to provide any other person with access to this Website or portions of it using Your user name, password, or other security information. You agree to notify Us immediately of any unauthorized access to or use of Your username or password or any other breach of security. You also agree to ensure that You exit from Your account at the end of each session. You should use particular caution when accessing Your account from a public or shared computer so that others are not able to view or record Your password or other personal information. + + +## General Conditions + +You agree to the following conditions for Your use of the Website: + + + +* We reserve the right to add or remove features from the Website at any time. +* We reserve the right to refuse access to Our Website to anyone for any reason at any time. +* We reserve the right to force forfeiture of any username or account that becomes inactive, contains profanity, violates this Agreement, defames, or may mislead other users. +* We may limit or terminate the Agreement, Your account, and seek other remedies. + + +## User Contributions + +The Website may contain personal web pages or profiles, forums, bulletin boards and other interactive features (collectively, "Interactive Services") that allow Users to post, submit, publish, display, or transmit to other Users or other persons (hereinafter, "post") content or materials (collectively, "User Contributions") on or through p5.js Editor. + +All User Contributions must comply with the Content Standards set out in these Terms of Use. + +Any User Contribution You post to the site will be considered non-confidential. By uploading any User Contribution to the Website, You grant Us, Our affiliates and service providers, and each of their and Our respective licensees, successors, and assigns the right to reproduce and display those User Contributions and any such material therein for any purpose. + +You represent and warrant that: + + + +* You own or control all rights in and to the User Contributions and have the right to grant the license granted above to Us and Our affiliates and service providers, and each of their and Our respective licensees, successors, and assigns. +* All of Your User Contributions do and will comply with these Terms of Use. + +You understand and acknowledge that You are responsible for any User Contributions You submit or contribute, and You, not the Processing Foundation, have full responsibility for such content, including its legality, reliability, accuracy, and appropriateness. + +We are not responsible or liable to any third party for the content or accuracy of any User Contributions posted by You or any other User of the Website. + + +## Content Standards + +These content standards apply to any and all User Contributions and use of Interactive Services. User Contributions must in their entirety comply with all applicable federal, state, local, and international laws and regulations. Without limiting the foregoing, User Contributions must not: + + + +* Contain any material that is defamatory, obscene, indecent, abusive, offensive, harassing, violent, hateful, inflammatory, or otherwise objectionable; +* Promote sexually explicit or pornographic material, violence, or discrimination based on race, sex, religion, nationality, disability, sexual orientation, or age; +* Infringe any patent, trademark, trade secret, copyright, or other intellectual property or other rights of any other person; +* Violate the legal rights (including the rights of publicity and privacy) of others or contain any material that could give rise to any civil or criminal liability under applicable laws or regulations or that otherwise may be in conflict with these Terms of Use and our [Privacy Policy](https://editor.p5js.org/privacy-policy); +* Be likely to deceive any person; +* Promote any illegal activity, or advocate, promote, or assist any unlawful act; +* Cause annoyance, inconvenience, or needless anxiety or be likely to upset, embarrass, alarm, or annoy any other person; +* Impersonate any person, or misrepresent Your identity or affiliation with any person or organization; +* Give the impression that they emanate from or are endorsed by Us or any other person or entity, if this is not the case. + + +## Prohibited Uses + +You may use the Website only for lawful purposes and in accordance with these Terms of Use. You agree not to use the Website: + + + +* In any way that violates any applicable federal, state, local, or international law or regulation (including, without limitation, any laws regarding the export of data or software to and from the US or other countries). +* For the purpose of exploiting, harming, or attempting to exploit or harm minors in any way by exposing them to inappropriate content, asking for personally identifiable information, or otherwise. +* To send, knowingly receive, upload, download, use, or re-use any material that does not comply with the Content Standards set out above in these Terms of Use. +* To transmit, or procure the sending of, any advertising or promotional material including any "junk mail," "chain letter," "spam," or any other similar solicitation. +* To impersonate or attempt to impersonate the Processing Foundation, an employee of the Processing Foundation, another User, or any other person or entity (including, without limitation, by using email addresses or screen names associated with any of the foregoing). +* To engage in any other conduct that restricts or inhibits anyone's use or enjoyment of the Website, or which, as determined by us, may harm the Processing Foundation or Users of the Website, or expose them to liability. + +Additionally, You agree not to: + + + +* Use the Website in any manner that could disable, overburden, damage, or impair the site or interfere with any other party's use of the Website, including their ability to engage in real time activities through the Website. +* Use any robot, spider, or other automatic device, process, or means to access the Website for any purpose, including monitoring or copying any of the material on the Website. +* Use any manual process to monitor or copy any of the material on the Website, or for any other purpose not expressly authorized in these Terms of Use, without Our prior written consent. +* Use any device, software, or routine that interferes with the proper working of the Website. +* Introduce any viruses, Trojan horses, worms, logic bombs, or other material that is malicious or technologically harmful. +* Attempt to gain unauthorized access to, interfere with, damage, or disrupt any parts of the Website, the server on which the Website is stored, or any server, computer, or database connected to the Website. +* Attack the Website via a denial-of-service attack or a distributed denial-of-service attack. +* Otherwise attempt to interfere with the proper working of the Website. + + +## End User Licenses + + +### Your License to the Website + +Subject to Your compliance with this Agreement, We will permit You to access and use the Website solely for lawful purposes and only in accordance with the terms of this Agreement and any other agreement You may have entered into with the Processing Foundation. + + + + +### Your License to the Content + +Unless otherwise noted on the Website, all content, data, or other information provided through the Website made by the Processing Foundation (collectively “Content”) is owned by the Processing Foundation. By accepting this Agreement, the Processing Foundation grants to You a non-exclusive, non-transferable, and revocable license to use the Website and Content only for the purposes for which these Terms of Use allow. You may not, in whole or in part, copy, modify, delete, add to, remove, publish, transmit, augment, transfer, create derivative works, sell, or participate in the sale or transfer of the Website, or in any other way exploit any of the Content, software, products, trademarks or services contained in the Website without the prior written consent from the Processing Foundation. If You would like to use the Content in a manner not permitted by this Agreement, please contact the Processing Foundation. + + + + +### Our License to User Content + +All user-generated content you submit to Processing Foundation is licensed to and through Processing Foundation under the Creative Commons Attribution-ShareAlike 2.0 license (located at [https://creativecommons.org/licenses/by-sa/2.0/](https://creativecommons.org/licenses/by-sa/2.0/) ). This allows others to view and remix your content. This license also allows the Processing Foundation to display, distribute, and reproduce your content on the p5.js website, through social media channels, and elsewhere. If you do not want to license your content under this license, then do not share it with Processing Foundation. + + +## DMCA Infringement Notices + +The Processing Foundation respects Your copyrights and other intellectual property rights, as well as those of third parties. If You believe in good faith that Your copyrighted work has been reproduced on the Website without Your authorization in a way that constitutes copyright infringement, You may notify Our designated copyright agent by email at: + +[dmca@p5js.org](mailto:dmca@p5js.org) + + + +Please provide the following information to Our Copyright Infringement Agent: + + + +* The identity of the infringed work, and of the allegedly infringing work; +* Your name, address, daytime phone number, and email address (if an email is available +* a statement that You have a good-faith belief that the use of the copyrighted work is not authorized by the owner, his or her agent, or the law; +* a statement that the information in the notification is accurate and, under penalty of perjury, that You are authorized to act on behalf of the owner; and +* Your electronic or physical signature + +Please also note that for copyright infringements under Section 512(f) of the Copyright Act, any person who knowingly materially misrepresents that material or activity is infringing may be subject to liability. + +We will notify You that we have removed or disabled access to copyright-protected material that You provided, if such removal is pursuant to a valid DMCA take-down notice that we have received. If You receive such a notice from Us, You may provide Us with a counter-notification in writing to Our designated agent that includes all of the following information: + + + +* Your physical or electronic signature; +* Identification of the material that has been removed or to which access has been disabled, and the location at which the material appeared before it was removed or access to it was disabled; +* A statement from You under the penalty of perjury, that You have a good faith belief that the material was removed or disabled as a result of a mistake or misidentification of the material to be removed or disabled; and +* Your name, physical address and telephone number, and a statement that You consent to the jurisdiction of a court for the judicial district in which your physical address is located, or if your physical address is outside of the United States, for any judicial district in which the Processing Foundation may be located, and that You will accept service of process from the person who provided notification of allegedly infringing material or an agent of such person. + +The Processing Foundation reserves the right, in its sole discretion, to terminate the account or access of any User of the Website who is the subject or repeated DMCA or other infringement notifications. + + +## Indemnification + +You agree to defend, indemnify, and hold harmless the Processing Foundation, its affiliates, licensors, and service providers, and its and their respective officers, directors, employees, contractors, agents, licensors, suppliers, successors, and assigns from and against any claims, liabilities, damages, judgments, awards, losses, costs, expenses, or fees (including reasonable attorneys' fees) arising out of or relating to Your violation of these Terms of Use or Your use of the Website, including, but not limited to, Your User Contributions, any use of the Content, Website, and products other than as expressly authorized in these Terms of Use, or Your use of any information obtained from the Website. + + +## Limitation on Liability + +**To the fullest extent provided by law, in no event will the Processing Foundation, its affiliates, or their licensors, service providers, employees, agents, officers, or directors be liable for damages of any kind, under any legal theory, arising out of or in connection with your use, or inability to use, the website, any websites linked to it, any content on the website or such other websites, including any direct, indirect, special, incidental, consequential, or punitive damages, including but not limited to, personal injury, pain and suffering, emotional distress, loss of revenue, loss of profits, loss of business or anticipated savings, loss of use, loss of goodwill, loss of data, and whether caused by tort (including negligence), breach of contract, or otherwise, even if foreseeable.** + +The limitation of liability set out above does not apply to liability resulting from Our gross negligence or willful misconduct. + +**The foregoing does not affect any liability that cannot be excluded or limited under applicable law.** + + +## Dispute Resolution + +For any dispute arising under this Agreement, parties agree to contact each other and attempt to resolve disputes for no less than 30 days prior to seeking an alternative method of dispute resolution. + + +### Mediation + +If settlement cannot be reached within the 30 day period, parties agree to try in good faith to settle the dispute by mediation. + + +### Venue + +Any meeting or proceeding shall take place in New York, New York. + + +### Arbitration + +If settlement can not be reached through good faith negotiations or mediation, then any unsettled dispute shall be resolved by arbitration. + + +### Governing Law + +Dispute resolution shall be governed by New York law. + + +### Administration + +Arbitration claims shall be heard by a single arbitrator, who has expertise in contracts. Parties shall come together to pick a single arbitrator within 15 days after the commencement of arbitration. If the parties fail to agree upon a single arbitrator, the arbitration provider will pick a single arbitrator who has expertise in contracts. If the parties fail to agree upon an arbitration provider within 30 days of the end of the good faith resolution period, the American Arbitration Association will be the arbitration provider. + + +### Fees + +Each party agrees to pay its half of all the applicable filing fees and arbitrator fees. Each party shall bear its own attorneys’ fees and costs upfront. The prevailing party shall be entitled to recover its attorneys’ fees and costs. + +Nothing in this section shall prevent either party from seeking injunctive or equitable relief from the courts for matters related to intellectual property rights or unauthorized access to the Service. + +**To the extent permitted by law, all claims must be brought in the parties’ individual capacity, and not as a plaintiff or class member in any purported class or representative proceeding, and, unless the parties agree otherwise, the arbitrator may not consolidate more than one person’s claims. You agree that, by entering into these terms, you and the Processing Foundation are each waiving the right to a trial by jury or to participate in a class action.** + + +## Waiver and Severability + +Any waiver by Us of any term or condition set out in these Terms of Use shall not be deemed a further or continuing waiver of such term or condition or a waiver of any other term or condition, and any failure by Us to assert a right or provision under these Terms of Use shall not constitute a waiver of such right or provision. + +If any provision of these Terms of Use is held by a court or other tribunal of competent jurisdiction to be invalid, illegal, or unenforceable for any reason, such provision shall be eliminated or limited to the minimum extent such that the remaining provisions of the Terms of Use will continue in full force and effect. + + +## Entire Agreement + +The Terms of Use and Our Privacy Policy, constitute the sole and entire agreement between You and the Processing Foundation regarding the Website and supersede all prior and contemporaneous understandings, agreements, representations, and warranties, both written and oral, regarding the Website. + + +## Your Comments and Concerns + +This website is operated by the Processing Foundation, 400 Jay Street, #175 + +Brooklyn, NY 11201. + +All other feedback, comments, requests for technical support, and other communications relating to the Website should be directed to: [hello@p5js.org](mailto:hello@p5js.org). diff --git a/server/controllers/user.controller.js b/server/controllers/user.controller.js index 19d5b6a823..bc3e179662 100644 --- a/server/controllers/user.controller.js +++ b/server/controllers/user.controller.js @@ -17,7 +17,8 @@ export function userResponse(user) { id: user._id, totalSize: user.totalSize, github: user.github, - google: user.google + google: user.google, + cookieConsent: user.cookieConsent }; } @@ -412,3 +413,20 @@ export function unlinkGoogle(req, res) { message: 'You must be logged in to complete this action.' }); } + +export function updateCookieConsent(req, res) { + User.findById(req.user.id, (err, user) => { + if (err) { + res.status(500).json({ error: err }); + return; + } + if (!user) { + res.status(404).json({ error: 'Document not found' }); + return; + } + + const { cookieConsent } = req.body; + user.cookieConsent = cookieConsent; + saveUser(res, user); + }); +} diff --git a/server/models/user.js b/server/models/user.js index 1ff4132b60..0ffe79c6c5 100644 --- a/server/models/user.js +++ b/server/models/user.js @@ -76,7 +76,12 @@ const userSchema = new Schema( language: { type: String, default: 'en-US' }, autocloseBracketsQuotes: { type: Boolean, default: true } }, - totalSize: { type: Number, default: 0 } + totalSize: { type: Number, default: 0 }, + cookieConsent: { + type: String, + enum: ['none', 'essential', 'all'], + default: 'none' + } }, { timestamps: true, usePushEach: true } ); diff --git a/server/routes/server.routes.js b/server/routes/server.routes.js index a0b608188d..3647230bc9 100644 --- a/server/routes/server.routes.js +++ b/server/routes/server.routes.js @@ -133,4 +133,16 @@ router.get('/:username/collections', (req, res) => { ); }); +router.get('/privacy-policy', (req, res) => { + res.send(renderIndex()); +}); + +router.get('/terms-of-use', (req, res) => { + res.send(renderIndex()); +}); + +router.get('/code-of-conduct', (req, res) => { + res.send(renderIndex()); +}); + export default router; diff --git a/server/routes/user.routes.js b/server/routes/user.routes.js index a52facf963..a507c328bd 100644 --- a/server/routes/user.routes.js +++ b/server/routes/user.routes.js @@ -18,6 +18,12 @@ router.post('/reset-password/:token', UserController.updatePassword); router.put('/account', isAuthenticated, UserController.updateSettings); +router.put( + '/cookie-consent', + isAuthenticated, + UserController.updateCookieConsent +); + router.post('/account/api-keys', isAuthenticated, UserController.createApiKey); router.delete( diff --git a/server/server.js b/server/server.js index bffd7ab544..cb9244cae3 100644 --- a/server/server.js +++ b/server/server.js @@ -131,6 +131,7 @@ app.use( (process.env.NODE_ENV === 'production' ? '1d' : '0') }) ); +app.use(Express.static(path.resolve(__dirname, '../public'))); app.use(passport.initialize()); app.use(passport.session()); diff --git a/server/views/index.js b/server/views/index.js index f7e5b4b229..3bf23e32c6 100644 --- a/server/views/index.js +++ b/server/views/index.js @@ -12,7 +12,7 @@ export function renderIndex() { ${process.env.NODE_ENV === 'production' ? `` : ''} - +
- `; diff --git a/translations/locales/en-US/translations.json b/translations/locales/en-US/translations.json index 6d23572c46..6b3f74c228 100644 --- a/translations/locales/en-US/translations.json +++ b/translations/locales/en-US/translations.json @@ -96,7 +96,10 @@ "Resources": "Resources", "Libraries": "Libraries", "Forum": "Forum", - "Examples": "Examples" + "Examples": "Examples", + "PrivacyPolicy": "Privacy Policy", + "TermsOfUse": "Terms of Use", + "CodeOfConduct": "Code of Conduct" }, "Toast": { "OpenedNewSketch": "Opened new sketch.", @@ -599,5 +602,16 @@ }, "Explorer": { "Files": "Files" + }, + "Cookies": { + "Header": "Cookies", + "Body": "The p5.js Editor uses cookies. Some are essential to the website functionality and allow you to manage an account and preferences. Others are not essential—they are used for analytics and allow us to learn more about our community. We never sell this data or use it for advertising. You can decide which cookies you would like to allow, and learn more in our <0>Privacy Policy<0>.", + "AllowAll": "Allow All", + "AllowEssential": "Allow Essential" + }, + "Legal": { + "PrivacyPolicy": "Privacy Policy", + "TermsOfUse": "Terms of Use", + "CodeOfConduct": "Code of Conduct" } } diff --git a/webpack/config.prod.js b/webpack/config.prod.js index dae6452848..16dd00dbb3 100644 --- a/webpack/config.prod.js +++ b/webpack/config.prod.js @@ -173,7 +173,8 @@ module.exports = { }), new CopyWebpackPlugin({ patterns: [ - { from: path.resolve(__dirname, '../translations/locales'), to: path.resolve(__dirname, '../dist/static/locales') } + { from: path.resolve(__dirname, '../translations/locales'), to: path.resolve(__dirname, '../dist/static/locales') }, + { from: path.resolve(__dirname, '../public'), to: path.resolve(__dirname, '../dist/static') } ] } )