Initial site commit

This commit is contained in:
Jocelyn Badgley (Twipped) 2020-02-20 14:38:25 -08:00
parent 0a6bdb2544
commit 1c45fdaf33
136 changed files with 24538 additions and 146 deletions

3
.browserlistrc Normal file
View File

@ -0,0 +1,3 @@
last 2 major version
not dead
not ie < 12

12
.editorconfig Normal file
View File

@ -0,0 +1,12 @@
root = true
[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.md]
trim_trailing_whitespace = false

1
.eslintignore Normal file
View File

@ -0,0 +1 @@
/dist

14
.eslintrc Normal file
View File

@ -0,0 +1,14 @@
{
"extends": "twipped/node",
"rules": {
"node/no-unpublished-require": 0,
"promise/no-native": 0,
'indent': [ 2, 2, {
'MemberExpression': 1,
} ],
'node/no-unsupported-features/es-syntax': [ 'error' ],
'node/no-unsupported-features/es-builtins': [ 'error' ],
'node/no-unsupported-features/node-builtins': [ 'error' ],
'require-atomic-updates': 0
}
}

16
.gitignore vendored Normal file
View File

@ -0,0 +1,16 @@
node_modules
/dist
/aws.json
/twitter.json
/rev-manifest.json
/.awspublish-*
/bs-manifest.json
/bs-cache
/posts.json
/posts-sans.json
/if-*
/twitter-cache.json
/terraform/*.tfstate*
/terraform/.terraform
/terraform/files/*.zip
/twitter-media.json

53
LICENSE.txt Normal file
View File

@ -0,0 +1,53 @@
Attribution-NonCommercial-ShareAlike 2.0 Generic (CC BY-NC-SA 2.0)
THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED.
BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE. THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS.
1. Definitions
"Collective Work" means a work, such as a periodical issue, anthology or encyclopedia, in which the Work in its entirety in unmodified form, along with a number of other contributions, constituting separate and independent works in themselves, are assembled into a collective whole. A work that constitutes a Collective Work will not be considered a Derivative Work (as defined below) for the purposes of this License.
"Derivative Work" means a work based upon the Work or upon the Work and other pre-existing works, such as a translation, musical arrangement, dramatization, fictionalization, motion picture version, sound recording, art reproduction, abridgment, condensation, or any other form in which the Work may be recast, transformed, or adapted, except that a work that constitutes a Collective Work will not be considered a Derivative Work for the purpose of this License. For the avoidance of doubt, where the Work is a musical composition or sound recording, the synchronization of the Work in timed-relation with a moving image ("synching") will be considered a Derivative Work for the purpose of this License.
"Licensor" means the individual or entity that offers the Work under the terms of this License.
"Original Author" means the individual or entity who created the Work.
"Work" means the copyrightable work of authorship offered under the terms of this License.
"You" means an individual or entity exercising rights under this License who has not previously violated the terms of this License with respect to the Work, or who has received express permission from the Licensor to exercise rights under this License despite a previous violation.
"License Elements" means the following high-level license attributes as selected by Licensor and indicated in the title of this License: Attribution, Noncommercial, ShareAlike.
2. Fair Use Rights. Nothing in this license is intended to reduce, limit, or restrict any rights arising from fair use, first sale or other limitations on the exclusive rights of the copyright owner under copyright law or other applicable laws.
3. License Grant. Subject to the terms and conditions of this License, Licensor hereby grants You a worldwide, royalty-free, non-exclusive, perpetual (for the duration of the applicable copyright) license to exercise the rights in the Work as stated below:
to reproduce the Work, to incorporate the Work into one or more Collective Works, and to reproduce the Work as incorporated in the Collective Works;
to create and reproduce Derivative Works;
to distribute copies or phonorecords of, display publicly, perform publicly, and perform publicly by means of a digital audio transmission the Work including as incorporated in Collective Works;
to distribute copies or phonorecords of, display publicly, perform publicly, and perform publicly by means of a digital audio transmission Derivative Works;
The above rights may be exercised in all media and formats whether now known or hereafter devised. The above rights include the right to make such modifications as are technically necessary to exercise the rights in other media and formats. All rights not expressly granted by Licensor are hereby reserved, including but not limited to the rights set forth in Sections 4(e) and 4(f).
4. Restrictions.The license granted in Section 3 above is expressly made subject to and limited by the following restrictions:
You may distribute, publicly display, publicly perform, or publicly digitally perform the Work only under the terms of this License, and You must include a copy of, or the Uniform Resource Identifier for, this License with every copy or phonorecord of the Work You distribute, publicly display, publicly perform, or publicly digitally perform. You may not offer or impose any terms on the Work that alter or restrict the terms of this License or the recipients' exercise of the rights granted hereunder. You may not sublicense the Work. You must keep intact all notices that refer to this License and to the disclaimer of warranties. You may not distribute, publicly display, publicly perform, or publicly digitally perform the Work with any technological measures that control access or use of the Work in a manner inconsistent with the terms of this License Agreement. The above applies to the Work as incorporated in a Collective Work, but this does not require the Collective Work apart from the Work itself to be made subject to the terms of this License. If You create a Collective Work, upon notice from any Licensor You must, to the extent practicable, remove from the Collective Work any reference to such Licensor or the Original Author, as requested. If You create a Derivative Work, upon notice from any Licensor You must, to the extent practicable, remove from the Derivative Work any reference to such Licensor or the Original Author, as requested.
You may distribute, publicly display, publicly perform, or publicly digitally perform a Derivative Work only under the terms of this License, a later version of this License with the same License Elements as this License, or a Creative Commons iCommons license that contains the same License Elements as this License (e.g. Attribution-NonCommercial-ShareAlike 2.0 Japan). You must include a copy of, or the Uniform Resource Identifier for, this License or other license specified in the previous sentence with every copy or phonorecord of each Derivative Work You distribute, publicly display, publicly perform, or publicly digitally perform. You may not offer or impose any terms on the Derivative Works that alter or restrict the terms of this License or the recipients' exercise of the rights granted hereunder, and You must keep intact all notices that refer to this License and to the disclaimer of warranties. You may not distribute, publicly display, publicly perform, or publicly digitally perform the Derivative Work with any technological measures that control access or use of the Work in a manner inconsistent with the terms of this License Agreement. The above applies to the Derivative Work as incorporated in a Collective Work, but this does not require the Collective Work apart from the Derivative Work itself to be made subject to the terms of this License.
You may not exercise any of the rights granted to You in Section 3 above in any manner that is primarily intended for or directed toward commercial advantage or private monetary compensation. The exchange of the Work for other copyrighted works by means of digital file-sharing or otherwise shall not be considered to be intended for or directed toward commercial advantage or private monetary compensation, provided there is no payment of any monetary compensation in connection with the exchange of copyrighted works.
If you distribute, publicly display, publicly perform, or publicly digitally perform the Work or any Derivative Works or Collective Works, You must keep intact all copyright notices for the Work and give the Original Author credit reasonable to the medium or means You are utilizing by conveying the name (or pseudonym if applicable) of the Original Author if supplied; the title of the Work if supplied; to the extent reasonably practicable, the Uniform Resource Identifier, if any, that Licensor specifies to be associated with the Work, unless such URI does not refer to the copyright notice or licensing information for the Work; and in the case of a Derivative Work, a credit identifying the use of the Work in the Derivative Work (e.g., "French translation of the Work by Original Author," or "Screenplay based on original Work by Original Author"). Such credit may be implemented in any reasonable manner; provided, however, that in the case of a Derivative Work or Collective Work, at a minimum such credit will appear where any other comparable authorship credit appears and in a manner at least as prominent as such other comparable authorship credit.
For the avoidance of doubt, where the Work is a musical composition:
Performance Royalties Under Blanket Licenses. Licensor reserves the exclusive right to collect, whether individually or via a performance rights society (e.g. ASCAP, BMI, SESAC), royalties for the public performance or public digital performance (e.g. webcast) of the Work if that performance is primarily intended for or directed toward commercial advantage or private monetary compensation.
Mechanical Rights and Statutory Royalties. Licensor reserves the exclusive right to collect, whether individually or via a music rights agency or designated agent (e.g. Harry Fox Agency), royalties for any phonorecord You create from the Work ("cover version") and distribute, subject to the compulsory license created by 17 USC Section 115 of the US Copyright Act (or the equivalent in other jurisdictions), if Your distribution of such cover version is primarily intended for or directed toward commercial advantage or private monetary compensation.
Webcasting Rights and Statutory Royalties. For the avoidance of doubt, where the Work is a sound recording, Licensor reserves the exclusive right to collect, whether individually or via a performance-rights society (e.g. SoundExchange), royalties for the public digital performance (e.g. webcast) of the Work, subject to the compulsory license created by 17 USC Section 114 of the US Copyright Act (or the equivalent in other jurisdictions), if Your public digital performance is primarily intended for or directed toward commercial advantage or private monetary compensation.
5. Representations, Warranties and Disclaimer
UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS, WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU.
6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
7. Termination
This License and the rights granted hereunder will terminate automatically upon any breach by You of the terms of this License. Individuals or entities who have received Derivative Works or Collective Works from You under this License, however, will not have their licenses terminated provided such individuals or entities remain in full compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will survive any termination of this License.
Subject to the above terms and conditions, the license granted here is perpetual (for the duration of the applicable copyright in the Work). Notwithstanding the above, Licensor reserves the right to release the Work under different license terms or to stop distributing the Work at any time; provided, however that any such election will not serve to withdraw this License (or any other license that has been, or is required to be, granted under the terms of this License), and this License will continue in full force and effect unless terminated as stated above.
8. Miscellaneous
Each time You distribute or publicly digitally perform the Work or a Collective Work, the Licensor offers to the recipient a license to the Work on the same terms and conditions as the license granted to You under this License.
Each time You distribute or publicly digitally perform a Derivative Work, Licensor offers to the recipient a license to the original Work on the same terms and conditions as the license granted to You under this License.
If any provision of this License is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this License, and without further action by the parties to this agreement, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable.
No term or provision of this License shall be deemed waived and no breach consented to unless such waiver or consent shall be in writing and signed by the party to be charged with such waiver or consent.
This License constitutes the entire agreement between the parties with respect to the Work licensed here. There are no understandings, agreements or representations with respect to the Work not specified here. Licensor shall not be bound by any additional provisions that may appear in any communication from You. This License may not be modified without the mutual written agreement of the Licensor and You.

6
README.md Normal file
View File

@ -0,0 +1,6 @@
Gulp.js Codebase for the [Gender Dysphoria Bible](https://genderdysphoria.fyi).
Code for this site is distributed as MIT licensed.
Site content such as essays and photo materials are copyright Jocelyn Badgley & other contributors, and are *not* licensed for public redistribution.

BIN
favicon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

12
gulp/_template.js Normal file
View File

@ -0,0 +1,12 @@
const format = require('date-fns/format');
module.exports = exports = ({ id, date }) => `---
id: "${id}"
date: "${date.toISOString()}"
title: ""
description: "Outfit of the Day for ${format(date, 'MMM do, yyyy')}"
tags:
- OOTD
---
`;

13
gulp/clean.js Normal file
View File

@ -0,0 +1,13 @@
const { src } = require('gulp');
const clean = require('gulp-clean');
module.exports = exports = function cleanDistribution () {
return src([ 'dist', 'rev-manifest.json', 'posts.json', 'posts-sans.json' ], { read: false, allowEmpty: true })
.pipe(clean());
};
exports.dev = function cleanDistributionForDev () {
return src([ 'dist/**.{js|json|jsx}', 'rev-manifest.json', 'posts.json', 'posts-sans.json' ], { read: false, allowEmpty: true })
.pipe(clean());
};

48
gulp/cloudfront.js Normal file
View File

@ -0,0 +1,48 @@
const log = require('fancy-log');
const aws = require('aws-sdk');
var credentials = require('../aws.json');
var Promise = require('bluebird');
async function invalidate (wait) {
var cloudfront = new aws.CloudFront();
cloudfront.config.update({ credentials });
var poll = async function (id) {
const res = await cloudfront.getInvalidation({
DistributionId: credentials.distribution,
Id: id,
}).promise();
if (res.Invalidation.Status === 'Completed') {
return;
}
return Promise.delay(5000).then(() => poll(id));
};
const { Invalidation } = await cloudfront.createInvalidation({
DistributionId: credentials.distribution,
InvalidationBatch: {
CallerReference: Date.now().toString(),
Paths: {
Quantity: 1,
Items: [ '/*' ],
},
},
}).promise();
const id = Invalidation.Id;
log('Invalidation created, waiting for it to complete.', id);
if (wait) await poll(id);
}
module.exports = exports = function invalidateCloudfrontAndWait () {
return invalidate(true);
};
exports.prod = function invalidateCloudfront () {
return invalidate(false);
};

579
gulp/contents.js Normal file
View File

@ -0,0 +1,579 @@
const path = require('path');
const fs = require('fs-extra');
const { chunk, uniq, keyBy, difference, omit } = require('lodash');
const log = require('fancy-log');
const glob = require('./lib/glob');
const getDimensions = require('./lib/dimensions');
const memoize = require('memoizepromise');
const { URL } = require('url');
const { minify: htmlMinify } = require('html-minifier-terser');
const { src, dest } = require('gulp');
const frontmatter = require('gulp-front-matter');
const collect = require('gulp-collect');
const asyncthrough = require('./lib/through');
const ROOT = path.dirname(__dirname);
const DEST = 'dist';
const { siteInfo } = require('../package.json');
const markdown = require('markdown-it');
const striptags = require('string-strip-html');
const tweetparse = require('./lib/tweetparse');
const slugs = require('slugify');
const slugify = (s) => slugs(s, { remove: /[*+~.,()'"!?:@/\\]/g }).toLowerCase();
const handlebars = require('handlebars');
const HandlebarsKit = require('hbs-kit');
HandlebarsKit.load(handlebars);
const md = markdown({
html: true,
linkify: true,
typographer: true,
}).enable('image')
.use(require('markdown-it-anchor'), {
permalink: true,
permalinkClass: 'header-link',
permalinkSymbol: '<img src="/images/svg/paragraph.svg">',
slugify,
})
.use(require('./lib/markdown-raw-html'))
;
const mdPreview = markdown({
html: false,
linkify: false,
typographer: true,
})
.use(require('./lib/markdown-token-filter'))
;
let twitterClient;
const Twitter = require('twitter-lite');
try {
twitterClient = new Twitter(require('../twitter.json'));
} catch (e) {
twitterClient = null;
}
function twitter (tweetids) {
if (!twitterClient) return [];
return twitterClient.get('statuses/lookup', { id: tweetids.join(','), tweet_mode: 'extended' })
.catch((e) => { log.error(e); return []; });
}
async function reloadLayouts () {
const layouts = {
layout: 'templates/layout.hbs.html',
};
let pending = Object.entries(layouts)
.map(async ([ name, file ]) =>
[ name, (await fs.readFile(path.resolve(ROOT, file))).toString('utf8') ],
);
pending = await Promise.all(pending);
pending.forEach(([ name, file ]) => handlebars.registerPartial(name, handlebars.compile(file)));
const injections = {};
handlebars.registerHelper('inject', function (tpath, ...args) {
const { hash } = args.pop();
const context = handlebars.createFrame(args[0] || this);
Object.assign(context, hash || {});
if (tpath[0] === '/') tpath = path.join(this.local.root, tpath);
else if (tpath[0] === '~') tpath = path.join(this.local.root, 'templates', tpath.slice(2));
else tpath = path.resolve(this.local.cwd, tpath);
tpath += '.hbs';
if (!injections[tpath]) {
if (!fs.existsSync(tpath)) {
log.error('Template does not exist for injection ' + path.relative(ROOT, tpath));
return '';
}
try {
injections[tpath] = handlebars.compile(fs.readFileSync(tpath).toString('utf8'));
} catch (e) {
log.error('Could not load injection template ' + path.relative(ROOT, tpath), e);
return '';
}
}
try {
return new handlebars.SafeString(injections[tpath](context));
} catch (e) {
log.error('Could not execute injection template ' + path.relative(ROOT, tpath), e);
return '';
}
});
handlebars.registerHelper('icon', function (name, ...args) {
const { hash } = args.pop();
const tpath = path.join(this.local.root, 'svg', name + '.svg');
if (!injections[tpath]) {
if (!fs.existsSync(tpath)) {
log.error('Template does not exist for injection ' + path.relative(ROOT, tpath));
return '';
}
try {
const svg = fs.readFileSync(tpath).toString('utf8');
injections[tpath] = handlebars.compile(`<span class="svg-icon" {{#if size}}style="width:{{size}}px;height:{{size}}px"{{/if}}>${svg}</span>`);
} catch (e) {
log.error('Could not load injection template ' + path.relative(ROOT, tpath), e);
return '';
}
}
try {
return new handlebars.SafeString(injections[tpath]({ size: hash && hash.size }));
} catch (e) {
log.error('Could not execute injection template ' + path.relative(ROOT, tpath), e);
return '';
}
});
handlebars.registerHelper('markdown', function (...args) {
const { fn } = args.pop();
let original;
if (fn) {
original = fn(this);
const match = original.match(/^[^\S\n]*(?=\S)/gm);
const indent = match && Math.min(...match.map((el) => el.length));
if (indent) {
const regexp = new RegExp(`^.{${indent}}`, 'gm');
original = original.replace(regexp, '');
}
} else {
let tpath = args.shift();
if (!tpath) throw new Error('No content was provided for the Markdown helper');
if (tpath[0] === '/') tpath = path.join(this.local.root, tpath);
else tpath = path.resolve(this.local.cwd, tpath);
tpath += '.md';
if (!injections[tpath]) {
if (!fs.existsSync(tpath)) {
log.error('Markdown does not exist for injection ' + path.relative(ROOT, tpath));
return '';
}
try {
original = fs.readFileSync(tpath).toString('utf8');
injections[tpath] = original;
} catch (e) {
log.error('Could not load markdown file ' + path.relative(ROOT, tpath), e);
return '';
}
}
}
original = md.render(original);
return new handlebars.SafeString(original);
});
}
exports.loadLayout = async function loadLayout () {
await reloadLayouts();
handlebars.registerHelper('rev', (url) => {
if (!url) return '';
if (url[0] === '/') url = url.substr(1);
return '/' + url;
});
handlebars.registerHelper('prod', function (options) {
if (!options.inverse) return false;
return options.inverse(this);
});
};
exports.loadLayout.prod = async function loadLayoutForProd () {
const manifest = await fs.readJson(path.join(ROOT, 'rev-manifest.json')).catch(() => {}).then((r) => r || {});
await reloadLayouts();
handlebars.registerHelper('rev', (url) => {
if (!url) return '';
if (url[0] === '/') url = url.substr(1);
if (manifest[url]) return '/' + manifest[url];
return '/' + url;
});
handlebars.registerHelper('prod', function (options) {
if (!options.fn) return true;
return options.fn(this);
});
};
exports.pages = function buildPages ({ minify }) {
var postTemplate = handlebars.compile(String(fs.readFileSync(path.join(ROOT, '/templates/post.hbs.html'))));
const minifyConfig = {
conservativeCollapse: true,
collapseWhitespace: true,
minifyCSS: true,
removeComments: true,
removeRedundantAttributes: true,
};
return src([ 'pages/**/*.{md,html,xml}', '!pages/**/_*.{md,html}' ])
.pipe(frontmatter({
property: 'meta',
}))
.pipe(parseMeta())
.pipe(parseTweets())
.pipe(asyncthrough(async (stream, file) => {
const cwd = path.dirname(file.path);
let original = file.contents.toString('utf8').trim();
var data = {
...file.meta,
meta: file.meta,
page: {
domain: siteInfo.domain,
title: file.meta.title
? (file.meta.title + (file.meta.subtitle ? ', ' + file.meta.subtitle : '') + ' :: ' + siteInfo.title)
: siteInfo.title,
},
local: {
cwd,
root: ROOT,
basename: file.basename,
},
};
if ([ '.html', '.md' ].includes(file.extname)) {
const datajs = file.clone();
datajs.contents = Buffer.from(JSON.stringify(omit(file.meta, [ 'destination' ]), null, 2));
datajs.basename = path.basename(file.path, file.extname) + '.json';
stream.push(datajs);
}
if ([ '.html', '.xml' ].includes(file.extname)) {
// is a handlebars template
try {
const template = handlebars.compile(original);
let html = template(data);
if (minify) {
html = htmlMinify(html, minifyConfig);
}
file.contents = Buffer.from(html);
stream.push(file);
} catch (err) {
log.error('Encountered a crash while compiling ' + file.path, err);
}
return;
}
original = original.replace(/\{!\{([\s\S]*?)\}!\}/mg, (match, contents) => {
try {
const result = handlebars.compile(contents)(data);
return '|||' + result + '|||';
} catch (e) {
log.error(e);
return '';
}
});
if (file.extname === '.md') {
let contents, preview;
try {
contents = md.render(original.replace(/<!--[[\]]-->/g, '')).trim();
data.contents = contents;
preview = striptags(original
.replace(/<!--\[[\s\S]*?\]-->/g, '')
.replace(/|||[\s\S]*?|||/gi, ''),
).trim();
if (preview.length > 1000) preview = preview.slice(0, 1000) + '…';
preview = preview ? mdPreview.render(preview) : '';
data.preview = preview;
} catch (e) {
log.error(`Error while rendering ${file.path}`, e);
contents = preview = '';
}
if (preview) {
file.flags.add('has-preview');
if (preview.length < 400) file.flags.add('short-preview');
} else {
file.flags.add('no-preview');
}
const classes = Array.from(file.flags);
const flags = classes.reduce((res, item) => {
var camelCased = item.replace(/-([a-z])/g, (g) => g[1].toUpperCase());
res[camelCased] = true;
return res;
}, {});
data.classes = data.meta.classes = classes;
data.flags = data.meta.flags = flags;
file.path = file.meta.destination;
// is a markdown file
try {
let html = postTemplate(data);
if (minify) {
html = htmlMinify(html, minifyConfig);
}
file.contents = Buffer.from(html);
stream.push(file);
} catch (err) {
log.error(`Error while rendering html for ${file.path}`, err);
}
return;
}
}))
.pipe(dest(DEST));
};
exports.pages.prod = function buildPagesProd () { return exports.pages({ minify: true }); };
/** **************************************************************************************************************** **/
function parseMeta () {
const getFileData = memoize(async (cwd, siteCwd) => {
const imageFiles = (await glob('{*,_images/*}.{jpeg,jpg,png,gif,mp4}', { cwd }));
const images = (await Promise.all(imageFiles.map(async (imgpath) => {
const ext = path.extname(imgpath);
let basename = path.basename(imgpath, ext);
if (basename === 'titlecard') return;
if (ext === '.mp4') {
return {
name: basename,
type: 'movie',
full: path.join(siteCwd, `${basename}${ext}`),
};
}
const dimensions = await getDimensions(path.resolve(cwd, imgpath));
const { width, height } = dimensions;
dimensions.ratioH = Math.round((height / width) * 100);
dimensions.ratioW = Math.round((width / height) * 100);
if (dimensions.ratioH > 100) {
dimensions.orientation = 'tall';
} else if (dimensions.ratioH === 100) {
dimensions.orientation = 'square';
} else {
dimensions.orientation = 'wide';
}
if (basename[0] === '_') {
basename = basename.slice(1);
}
const filetype = {
'.jpeg': 'jpeg',
'.jpg': 'jpeg',
'.png': 'png',
'.gif': 'gif',
}[ext];
const sizes = [
{
url: path.join(siteCwd, `${basename}.${filetype}`),
width: dimensions.width,
height: dimensions.height,
},
];
for (const w of [ 2048, 1024, 768, 576, 300, 100 ]) {
if (w > dimensions.width) continue;
sizes.push({
url: path.join(siteCwd, `${basename}.${w}w.${filetype}`),
width: w,
height: Math.ceil((w / dimensions.width) * dimensions.height),
});
}
sizes.reverse();
return {
name: basename,
type: 'image',
sizes,
};
}))).filter(Boolean);
const titlecard = (await glob('titlecard.{jpeg,jpg,png,gif}', { cwd }))[0];
return {
images: keyBy(images, 'name'),
titlecard: titlecard ? path.join(siteCwd, titlecard) : false,
};
});
return asyncthrough(async (stream, file) => {
if (!file || (file.meta && file.meta.ignore)) return;
if (!file.meta) file.meta = {};
// if metadata has a date value, us it.
// otherwise use creation date
var date = new Date(file.meta.date);
if (!date) date = file.stat.ctime;
file.meta.data = date;
var cwd = path.dirname(file.path);
var siteCwd = file.meta.cwd = '/' + path.relative(path.join(ROOT, 'pages'), cwd);
var base = file.meta.base = path.basename(file.path, file.extname);
var flags = file.flags = new Set(file.meta.classes || []);
var isIndexPage = file.meta.isIndex = (base === 'index');
var isRootPage = file.meta.isRoot = (file.meta.cwd === '/');
if (isRootPage && isIndexPage) {
file.meta.slug = '';
file.meta.destination = path.join(path.dirname(file.path), 'index.html');
} else if (isRootPage || !isIndexPage) {
file.meta.slug = base;
file.meta.destination = path.join(path.dirname(file.path), base, 'index.html');
} else if (!isRootPage && isIndexPage) {
file.meta.slug = '';
file.meta.destination = path.join(path.dirname(file.path), 'index.html');
} else {
file.meta.slug = path.basename(cwd);
file.meta.destination = path.join(path.dirname(file.path), 'index.html');
}
const url = new URL(siteInfo.rss.site_url);
file.meta.url = url.pathname = path.join(siteCwd, file.meta.slug);
file.meta.fullurl = url.toString();
// file.meta.originalpath = path.relative(file.cwd, file.path);
const { images, titlecard } = await getFileData(cwd, siteCwd);
file.meta.images = images;
file.meta.titlecard = titlecard;
flags.add(titlecard ? 'has-titlecard' : 'no-titlecard');
if (file.meta['no-title']) {
flags.add('hide-title');
} else if (file.meta.title || file.meta.description) {
flags.add('show-title');
} else {
flags.add('hide-title');
}
flags.add(file.meta.title ? 'has-title' : 'no-title');
flags.add(file.meta.subtitle ? 'has-subtitle' : 'no-subtitle');
flags.add(file.meta.description ? 'has-descrip' : 'no-descrip');
stream.push(file);
});
}
function parseTweets () {
const tweeturl = /https?:\/\/twitter\.com\/(?:#!\/)?(?:\w+)\/status(?:es)?\/(\d+)/i;
const tweetidcheck = /^\d+$/;
function parseTweetId (tweetid) {
// we can't trust an id that isn't a string
if (typeof tweetid !== 'string') return false;
const match = tweetid.match(tweeturl);
if (match) return match[1];
if (tweetid.match(tweetidcheck)) return tweetid;
return false;
}
return collect.list(async (files) => {
const twitterBackup = (await fs.readJson(path.join(ROOT, 'twitter-backup.json')).catch(() => {})) || {};
const twitterCache = (await fs.readJson(path.join(ROOT, 'twitter-cache.json')).catch(() => {})) || {};
const needed = [];
// first loop through all posts and gather + validate all tweet ids
for (const file of files) {
if (!file.meta.tweets && !file.meta.tweet) continue;
const tweets = [];
if (file.meta.tweet) {
file.meta.tweet = [ file.meta.tweet ].flat(1).map(parseTweetId);
tweets.push(...file.meta.tweet);
}
if (file.meta.tweets) {
file.meta.tweets = file.meta.tweets.map(parseTweetId);
tweets.push(...file.meta.tweets);
}
for (const id of tweets) {
if (!twitterCache[id]) {
needed.push(id);
}
}
file.meta.tweets = tweets;
}
// if we have tweets we need to add to the cache, do so
if (needed.length) {
log('Fetching tweets: ' + needed.join(', '));
const arriving = await Promise.all(chunk(uniq(needed), 99).map(twitter));
const loaded = [];
for (const tweet of arriving.flat(1)) {
if (!twitterBackup[tweet.id_str]) twitterBackup[tweet.id_str] = tweet;
twitterCache[tweet.id_str] = tweetparse(tweet);
loaded.push(tweet.id_str);
}
const absent = difference(needed, loaded);
for (const id of absent) {
if (twitterBackup[id]) {
log('Pulled tweet from backup ' + id);
twitterCache[id] = tweetparse(twitterBackup[id]);
continue;
}
log.error('Could not find tweet ' + id);
}
}
const media = [];
// now loop through posts and substitute the tweet data for the ids
for (const file of files) {
if (!file.meta.tweets) continue;
file.meta.tweets = file.meta.tweets.reduce((dict, tweetid) => {
const tweet = twitterCache[tweetid];
if (!tweet) log.error(`Tweet ${tweetid} is missing from the cache.`);
dict[tweetid] = tweet;
media.push( ...tweet.media );
return dict;
}, {});
}
await fs.writeFile(path.join(ROOT, 'twitter-media.json'), JSON.stringify(media, null, 2));
await fs.writeFile(path.join(ROOT, 'twitter-cache.json'), JSON.stringify(twitterCache, null, 2));
await fs.writeFile(path.join(ROOT, 'twitter-backup.json'), JSON.stringify(twitterBackup, null, 2));
return files;
});
}
/** **************************************************************************************************************** **/

48
gulp/files.js Normal file
View File

@ -0,0 +1,48 @@
const path = require('path');
const { src, dest } = require('gulp');
const rev = require('gulp-rev');
const asyncthrough = require('./lib/through');
const changed = require('gulp-changed');
const merge = require('merge-stream');
const ROOT = path.dirname(__dirname);
const DEST = 'dist';
module.exports = exports = function fileCopy () {
const pageFiles = src([ 'pages/**/*', '!pages/**/*.{md,hbs,xml,html,jpeg,jpg,png,gif,mp4}' ])
.pipe(changed(DEST))
.pipe(dest(DEST))
;
const svgs = src('svg/**/*.svg')
// .pipe(changed(DEST))
.pipe(dest(path.join(DEST, 'images/svg')))
.pipe(asyncthrough(async (stream, file) => {
file.base = path.resolve(file.base, '../..');
stream.push(file);
}))
;
return merge(pageFiles, svgs);
};
exports.prod = function fileCopyForProd () {
return exports()
.pipe(rev())
.pipe(dest(DEST))
.pipe(asyncthrough(async (stream, file) => {
// Change rev's original base path back to the public root so that it uses the full
// path as the original file name key in the manifest
var base = path.resolve(ROOT, DEST);
file.revOrigBase = base;
file.base = base;
stream.push(file);
}))
.pipe(rev.manifest({
merge: true, // Merge with the existing manifest if one exists
}))
.pipe(dest('.'))
;
};

155
gulp/imgflow/actions.js Normal file
View File

@ -0,0 +1,155 @@
const path = require('path');
const fs = require('fs-extra');
const gm = require('gm');
const Promise = require('bluebird');
const fetch = require('make-fetch-happen');
const ico = require('png-to-ico');
const CWD = path.resolve(__dirname, '../..');
const actions = {
async copy ({ input, output }) {
await fs.copy(input, output);
return fs.readFile(input);
},
async transcode ({ input, output, cache }) {
const result = await actions.image({
input,
output,
format: 'jpeg',
});
await fs.writeFile(cache, result);
return result;
},
async fetch ({ input, output, cache }) {
const res = await fetch(input);
const body = await res.buffer();
await fs.writeFile(output, body);
await fs.writeFile(cache, body);
return body;
},
async image (options) {
const input = path.resolve(CWD, options.input);
const output = path.resolve(CWD, options.output);
const contents = await fs.readFile(input);
let gmfile = gm(contents, input);
const size = await Promise.fromCallback((cb) => gmfile.size(cb));
if (options.height || options.width) {
// if upscale is not requested, restrict size
if (!options.upscale) {
if (!isNaN(options.width)) {
options.width = Math.min(options.width, size.width);
}
if (!isNaN(options.height)) {
options.height = Math.min(options.height, size.height);
}
}
// if one dimension is not set - we fill it proportionally
if (!options.height) {
if (options.crop) {
options.height = size.height;
} else {
options.height = Math.ceil((options.width / size.width) * size.height);
}
}
if (!options.width) {
if (options.crop) {
options.width = size.width;
} else {
options.width = Math.ceil((options.height / size.height) * size.width);
}
}
if (options.fill === 'crop') {
if (size.height < options.height || size.width < options.width) {
gmfile = gmfile
.geometry(options.width, options.height, '^')
.borderColor(options.bgColor || '#FFFFFF')
.border(options.width, options.height)
.gravity(options.gravity)
.crop(options.width, options.height);
} else {
gmfile = gmfile
.geometry(options.width, options.height, '^')
.gravity(options.gravity)
.crop(options.width, options.height);
}
} else if (options.fill === 'cover') {
gmfile = gmfile
.geometry(options.width, options.height, '^');
} else if (options.fill === 'box') {
gmfile = gmfile
.geometry(options.width, options.height)
.borderColor(options.bgColor || '#FFFFFF')
.border(options.width, options.height)
.gravity(options.gravity)
.crop(options.width, options.height);
} else if (options.fill === 'contain') {
gmfile = gmfile
.geometry(options.width, options.height);
} else {
gmfile = gmfile
.geometry(options.width, options.height, '!');
}
} else if (options.percentage) {
gmfile = gmfile
.geometry(options.percentage, null, '%');
}
if (options.format) {
gmfile = gmfile
.setFormat(options.format === 'ico' ? 'png' : options.format);
}
if (options.quality) {
gmfile = gmfile.quality(Math.floor(options.quality));
} else {
gmfile = gmfile.quality(Math.floor(95));
}
if (options.samplingFactor) {
gmfile = gmfile
.samplingFactor(options.samplingFactor[0], options.samplingFactor[1]);
}
if (options.sharpen) {
options.sharpen = (typeof options.sharpen === 'string') ? options.sharpen : '1.5x1+0.7+0.02';
gmfile = gmfile.unsharp(options.sharpen);
}
if (options.flatten) {
gmfile = gmfile.flatten();
}
if (options.interlace) {
gmfile = gmfile.interlace('Line');
}
if (options.background) {
gmfile = gmfile.background(options.background);
}
if (options.noProfile) {
gmfile = gmfile.noProfile();
}
await fs.ensureDir(path.dirname(output));
let result = await Promise.fromCallback((cb) => gmfile.toBuffer(cb));
if (options.format === 'ico') result = await ico(result);
await fs.writeFile(output, result);
if (options.cache) await fs.writeFile(options.cache, result);
return result;
},
};
module.exports = exports = actions;

326
gulp/imgflow/index.js Normal file
View File

@ -0,0 +1,326 @@
const path = require('path');
const glob = require('../lib/glob');
const { groupBy, sortBy, omitBy, uniqBy } = require('lodash');
const Promise = require('bluebird');
const fs = require('fs-extra');
const log = require('fancy-log');
const actions = require('./actions');
const getDimensions = require('../lib/dimensions');
const CWD = path.resolve(__dirname, '../..');
const PAGES = path.join(CWD, 'pages');
const SOURCE = path.resolve(CWD, 'pages/**/*.{jpeg,jpg,png,gif,mp4}');
const MANIFEST_PATH = path.resolve(CWD, 'if-manifest.json');
const REV_MANIFEST_PATH = path.resolve(CWD, 'rev-manifest.json');
const MEDIA_INDEX = path.resolve(CWD, 'twitter-media.json');
const CACHE = 'if-cache';
const revHash = require('rev-hash');
const revPath = require('rev-path');
const LOG = {
new: true,
update: true,
skip: true,
rebuild: true,
cached: false,
copy: false,
};
module.exports = exports = async function postImages ({ rev = false }) {
var manifest;
try {
manifest = JSON.parse(await fs.readFile(MANIFEST_PATH));
} catch (e) {
manifest = {};
}
await fs.ensureDir(path.resolve(CWD, CACHE));
const allfiles = (await glob(SOURCE));
const tasks = [];
for (const filepath of allfiles) {
const input = path.relative(CWD, filepath);
const output = path.relative(PAGES, filepath).replace('/_images', '');
const file = path.parse(output);
// console.log(input, output);
// is a titlecard image or a video
if (file.name === 'titlecard' || file.ext === '.mp4') {
tasks.push({
input,
output,
action: actions.copy,
});
continue;
}
// is a file we've pre-sized and do not want processed
if (file.name[0] === '_') {
tasks.push({
input,
output: path.format({ ...file, base: file.base.substring(1) }),
action: actions.copy,
});
continue;
}
const format = {
'.jpeg': 'jpeg',
'.jpg': 'jpeg',
'.png': 'png',
'.gif': 'gif',
}[file.ext];
if (!format) throw new Error('Got an unexpected format: ' + file.ext);
const dimensions = await getDimensions(filepath);
tasks.push({
input: filepath,
output: `${file.dir}/${file.name}.${format}`,
format,
action: actions.image,
});
for (const w of [ 2048, 1024, 768, 576, 300, 100 ]) {
if (w > dimensions.width) continue;
tasks.push({
input: filepath,
output: `${file.dir}/${file.name}.${w}w.${format}`,
format,
width: w,
action: actions.image,
});
}
}
const filtered = await filter(manifest, tasks);
await execute(manifest, filtered, rev);
};
exports.prod = function imagesProd () { return exports({ rev: true }); };
exports.twitter = async function twitterImages ({ rev = false }) {
await fs.ensureDir(path.resolve(CWD, CACHE));
var manifest;
try {
manifest = JSON.parse(await fs.readFile(MANIFEST_PATH));
} catch (e) {
manifest = {};
}
var media;
try {
media = JSON.parse(await fs.readFile(MEDIA_INDEX));
} catch (e) {
media = [];
}
media = uniqBy(media, 'output');
const tasks = media.map((m) => ({ ...m, action: actions.fetch }));
const filtered = await filter(manifest, tasks);
await execute(manifest, filtered, rev);
};
exports.twitter.prod = function imagesProd () { return exports.twitter({ rev: true }); };
exports.favicon = async function favicon ({ rev = false }) {
await fs.ensureDir(path.resolve(CWD, CACHE));
const input = path.resolve(CWD, 'favicon.png');
var manifest;
try {
manifest = JSON.parse(await fs.readFile(MANIFEST_PATH));
} catch (e) {
manifest = {};
}
const tasks = [ 32, 57, 64, 76, 96, 114, 120, 128, 144, 152, 180, 192, 196, 228 ].map((width) => ({
input,
output: `favicon${width}.png`,
format: 'png',
width,
action: actions.image,
}));
tasks.push({
input,
output: 'favicon.ico',
format: 'ico',
action: actions.image,
});
const filtered = await filter(manifest, tasks);
await execute(manifest, filtered, rev);
};
exports.favicon.prod = function imagesProd () { return exports.favicon({ rev: true }); };
async function filter (manifest, tasks) {
const statMap = new Map();
async function stat (f) {
if (statMap.has(f)) return statMap.get(f);
const p = fs.stat(path.resolve(CWD, f))
.catch(() => null)
.then((stats) => (stats && Math.floor(stats.mtimeMs / 1000)));
statMap.set(f, p);
return p;
}
return Promise.filter(tasks, async (task) => {
const local = task.input.slice(0, 4) !== 'http';
const hash = task.action.name + '.' + revHash(task.input) + '|' + revHash(task.output);
const cachePath = path.join(CACHE, `${hash}${path.extname(task.output)}`);
const [ inTime, outTime, cachedTime ] = await Promise.all([
local && stat(path.resolve(CWD, task.input)),
stat(path.resolve(CWD, 'dist', task.output)),
stat(path.resolve(CWD, cachePath)),
]);
task.manifest = manifest[hash];
task.hash = hash;
task.cache = cachePath;
// how did this happen?
if (local && !inTime) {
log.error('Input file could not be found?', task.input);
return false;
}
// never seen this file before
if (!task.manifest) {
task.apply = {
hash,
input: task.input,
output: task.output,
mtime: inTime,
};
task.log = [ 'new', task.input, task.output, hash ];
return true;
}
// file modification time does not match last read, rebuild
if (local && inTime > task.manifest.mtime) {
task.log = [ 'update', task.input, task.output ];
task.apply = {
mtime: inTime,
};
return true;
}
task.apply = {
mtime: local ? inTime : Math.floor(Date.now() / 1000),
};
// target file exists, nothing to do
if (outTime) {
return false;
// task.log = [ 'skip', task.input, task.output, inTime, task.manifest.mtime ];
// task.action = null;
// return true;
}
// file exists in the cache, change the task to a copy action
if (cachedTime) {
task.log = [ 'cached', task.input, task.output ];
task.action = actions.copy;
task.input = cachePath;
return true;
}
// task is a file copy
if (task.action === actions.copy) {
task.log = [ 'copy', task.input, task.output ];
return true;
}
// file does not exist in cache, build it
task.log = [ 'rebuild', task.input, task.output ];
return true;
});
}
async function execute (manifest, tasks, rev) {
const lastSeen = Math.floor(Date.now() / 1000);
const revManifest = {};
let writeCounter = 0;
let lastWriteTime = 0;
async function writeManifest (force) {
if (!force && rev) return; // disable interim writes during prod builds.
if (!force && ++writeCounter % 100) return;
const now = Date.now();
if (!force && now - lastWriteTime < 10000) return;
lastWriteTime = now;
await fs.writeFile(MANIFEST_PATH, JSON.stringify(manifest, null, 2));
}
await Promise.map(sortBy(tasks, [ 'input', 'output' ]), async (task) => {
const output = path.resolve(CWD, 'dist', task.output);
const result = task.action && await task.action({ ...task, output });
const apply = task.apply || {};
if (task.log && LOG[task.log[0]]) log.info(...task.log);
apply.lastSeen = lastSeen;
apply.lastSeenHuman = new Date();
if (!result) log('Nothing happened?', task);
const rhash = result && revHash(result);
const hashedPath = revPath(task.output, rhash);
apply.revHash = rhash;
apply.revPath = hashedPath;
if (rev && rhash) {
const rOutPath = task.output;
const rNewPath = hashedPath;
revManifest[rOutPath] = rNewPath;
await fs.copy(output, path.resolve(CWD, 'dist', hashedPath));
}
manifest[task.hash] = { ...manifest[task.hash], ...apply };
await writeManifest();
}, { concurrency: rev ? 20 : 10 });
// filter unseen files from history
// manifest = omitBy(manifest, (m) => m.lastSeen !== lastSeen);
await writeManifest(true);
if (rev) {
let originalManifest = {};
try {
if (await fs.exists(REV_MANIFEST_PATH)) {
originalManifest = JSON.parse(await fs.readFile(REV_MANIFEST_PATH));
}
} catch (e) {
// do nothing
}
Object.assign(originalManifest, revManifest);
await fs.writeFile(REV_MANIFEST_PATH, JSON.stringify(originalManifest, null, 2));
}
}
if (require.main === module) {
exports().catch(console.error).then(() => process.exit()); // eslint-disable-line
}

113
gulp/index.js Normal file
View File

@ -0,0 +1,113 @@
const { series, parallel, watch } = require('gulp');
/** **************************************************************************************************************** **/
var { loadLayout, pages } = require('./contents');
var contentTask = series( loadLayout, pages );
exports.pages = series( loadLayout, pages );
exports.content = contentTask;
var images = require('./imgflow');
exports.twimages = images.twitter;
exports.images = images;
exports['images-prod'] = images.prod;
exports['twimages-prod'] = images.twitter.prod;
exports.favicon = images.favicon;
const filesTask = require('./files');
exports.files = filesTask;
exports['files-prod'] = filesTask.prod;
var scssTask = require('./scss');
exports.scss = scssTask;
var jsTask = require('./scripts');
exports.js = jsTask;
var jsRollupTask = require('./rollup');
exports.jsr = jsRollupTask;
var cleanTask = require('./clean');
exports.clean = cleanTask;
const pushToProd = require('./publish');
exports.push = pushToProd;
const cloudfront = require('./cloudfront');
exports.cloudfront = cloudfront;
/** **************************************************************************************************************** **/
exports.new = require('./new');
var buildTask = series(
images.prod,
images.favicon.prod,
scssTask.prod,
jsTask.prod,
filesTask.prod,
loadLayout.prod,
pages.prod,
images.twitter.prod,
);
var devBuildTask = series(
parallel(
images,
images.favicon,
scssTask,
jsTask,
filesTask,
),
loadLayout,
pages,
images.twitter,
);
exports.dev = devBuildTask;
exports.prod = buildTask;
exports.publish = series(
cleanTask,
buildTask,
pushToProd,
cloudfront.prod,
);
exports.testpush = pushToProd.dryrun;
/** **************************************************************************************************************** **/
function watcher () {
watch([
'pages/**/*.{md,hbs,html}',
'templates/*.{md,hbs,html}',
], series(contentTask, images.twitter));
watch('page/**/*.{jpeg,jpg,png,gif}', images);
watch('scss/*.scss', scssTask);
watch('js/*.js', jsTask);
var forever = require('forever');
var srv = new forever.Monitor('server.js');
srv.start();
forever.startServer(srv);
}
function server () {
var forever = require('forever');
var srv = new forever.Monitor('server.js');
srv.start();
forever.startServer(srv);
}
exports.watch = series(contentTask, watcher);
exports.uat = series(cleanTask, buildTask, server);
/** **************************************************************************************************************** **/
exports.default = series(cleanTask.dev, devBuildTask, watcher);

31
gulp/lib/crass.js Normal file
View File

@ -0,0 +1,31 @@
const through = require('./through');
const crass = require('crass');
const PluginError = require('plugin-error');
module.exports = exports = function (options) {
options = {
pretty: false,
o1: true,
...options,
};
return through(async (stream, file) => {
if (file.isNull()) {
stream.push(file);
return;
}
try {
var parsed = crass.parse(file.contents.toString());
parsed = parsed.optimize({ O1: !!options.o1 });
if (options.pretty) parsed = parsed.pretty();
file.contents = Buffer.from(parsed.toString());
} catch (err) {
this.emit('error', new PluginError('gulp-crass', err));
}
stream.push(file);
});
};

32
gulp/lib/debug.js Normal file
View File

@ -0,0 +1,32 @@
const through = require('./through');
const log = require('fancy-log');
const { get } = require('lodash');
module.exports = exports = function debug (...targets) {
return through(async (stream, file) => {
var data;
const { path, relative, base, basename, extname } = file;
if (targets.length === 1 && Array.isArray(targets[0])) {
targets = targets[0];
}
if (targets.length) {
data = targets.reduce((result, target) => {
if (target === 'contents') {
result.contents = file.contents.toString();
return result;
}
result[target] = get(file, target);
return result;
}, {});
} else {
data = { ...file, path, relative, base, basename, extname };
}
log(data);
stream.push(file);
});
};

3
gulp/lib/dimensions.js Normal file
View File

@ -0,0 +1,3 @@
var { promisify } = require('util');
module.exports = exports = promisify(require('image-size'));

18
gulp/lib/filter.js Normal file
View File

@ -0,0 +1,18 @@
const filter = require('gulp-filter');
module.exports = exports = function filter2 (pattern, options) {
if (pattern instanceof RegExp) {
return filter((file) => pattern.test(file.path), options);
}
return filter(pattern, options);
};
exports.not = function notfilter2 (pattern, options) {
if (pattern instanceof RegExp) {
return filter((file) => !pattern.test(file.path), options);
}
throw new Error('filter.not only takes regular expressions');
};

4
gulp/lib/glob.js Normal file
View File

@ -0,0 +1,4 @@
var { promisify } = require('util');
const glob = require('glob');
module.exports = exports = promisify(glob);

26
gulp/lib/load.js Normal file
View File

@ -0,0 +1,26 @@
const through = require('./through');
const fs = require('fs-extra');
const log = require('fancy-log');
const parallelize = require('concurrent-transform');
module.exports = exports = function load () {
return parallelize(through(async (stream, file) => {
if (file.contents) {
// file already has contents, ignore
stream.push(file);
return;
}
const exists = await fs.pathExists(file.path);
// if (!exists) return;
log('[loading]', file.path, exists);
file.contents = await fs.readFile(file.path);
stream.push(file);
}), 20);
};

View File

@ -0,0 +1,181 @@
module.exports = exports = function (md, options) {
options = {
fence: '|||',
...options,
};
function debug (...args) {
if (options.debug) console.log(...args); // eslint-disable-line
}
const fenceLen = options.fence.length;
// const fenceFirst = options.fence.charCodeAt(0);
function scanAhead (state, line, pos) {
const position = state.src.indexOf(options.fence, pos);
if (position === -1) {
// there are no html blocks in this entire file
state.discreteHtmlScan = {
present: false,
};
return false;
}
while (position > state.eMarks[line]) {
line++;
}
state.discreteHtmlScan = {
present: true,
position,
line,
};
return true;
}
md.block.ruler.before('fence', 'raw', (state, startLine, lastLine) => {
let pos = state.bMarks[startLine] + state.tShift[startLine];
let endOfLine = state.eMarks[startLine];
// if we have yet to do a scan of this file, perform one.
if (!state.discreteHtmlScan && !scanAhead(state, startLine, pos)) {
debug('First scan, nothing found');
return false;
}
if (!state.discreteHtmlScan.present) {
debug('Have scanned, did not find');
return false;
}
// add one to the line here in case there is a line break in a paragraph.
if (state.discreteHtmlScan.line > startLine + 1) {
debug('Have scanned, found, but after this line', { startLine, targetLine: state.discreteHtmlScan.line });
return false;
}
if (startLine > state.discreteHtmlScan.line) {
// we dun fucked up
debug('We somehow got ahead of ourselves', { startLine, line: state.discreteHtmlScan.line, lastLine, pos, endOfLine, tokens: state.tokens });
throw new Error('markdown-it-discrete-html encountered a parsing error.');
}
// at this point we should be on a line that contains a fence mark
debug({ l: 67, startLine, scan: state.discreteHtmlScan });
let openIndex, closer, nextLine;
openIndex = state.discreteHtmlScan.position;
do {
let token, closeIndex;
const tokens = [];
const preBlock = openIndex > pos && state.src.slice(pos, openIndex);
debug({ l: 75, preBlock, startLine, lastLine });
openIndex += fenceLen;
pos = openIndex;
if (preBlock && !!preBlock.trim()) {
md.block.parse(preBlock, md, state.env, tokens);
switch (tokens[tokens.length - 1].type) {
case 'heading_close':
case 'paragraph_close':
closer = tokens.pop();
// fallthrough
default:
state.tokens.push(...tokens);
}
}
debug({ l: 92, tokens });
// find terminating fence
if (!scanAhead(state, startLine, pos)) {
debug({ l: 96, remaining: state.src.slice(pos) });
// console.error(state.src)
throw new Error(`Could not find terminating "${options.fence}" for a raw html block.`);
}
closeIndex = state.discreteHtmlScan.position;
nextLine = state.discreteHtmlScan.line;
if (nextLine === startLine) nextLine++;
endOfLine = state.eMarks[nextLine];
const content = state.src.substring(openIndex, closeIndex);
closeIndex += fenceLen;
pos = closeIndex;
if (content.trim()) {
token = state.push(closer ? 'html_inline' : 'html_block', '', 0);
token.map = [ startLine, nextLine ];
token.content = content;
token.block = true;
debug({ l: 115, tokens: [ token ], nextLine, pos, endOfLine: state.eMarks[nextLine], len: state.src.length, remaining: state.src.slice(pos) }); // eslint-disable-line
}
if (pos === endOfLine) {
// we have ended this line, nothing more to do here.
if (closer) {
state.tokens.push(closer);
debug({ l: 122, tokens: [ closer ] });
}
state.discreteHtmlScan = null;
state.line = nextLine + 1;
return true;
}
// still more left in this line, see if there is another block
if (scanAhead(state, nextLine, pos)) {
// we found another block, but it isn't on this line, so break out.
if (state.discreteHtmlScan.line > nextLine) {
if (closer) {
state.tokens.push(closer);
debug({ l: 135, tokens: [ closer ] });
}
state.line = nextLine + 1;
return true;
}
// next block is on this line, grab everything between here and there
openIndex = state.discreteHtmlScan.position;
} else {
// no more blocks on this line, grab everything between here and the end of the line
openIndex = endOfLine;
}
debug({ l: 147, pos, openIndex, remaining: state.src.slice(pos) });
const postBlock = state.src.slice(pos, openIndex);
token = null;
if (postBlock.trim()) {
token = state.push('inline', '', 0);
token.content = postBlock;
token.map = [ nextLine, nextLine ];
token.children = [];
tokens.push(token);
}
debug({ l: 158, tokens: [ token ], postBlock, pos, openIndex, closeIndex, endOfLine });
pos = openIndex;
startLine = nextLine + 1;
endOfLine = state.eMarks[startLine];
debug({ l: 164, pos, startLine, endOfLine, remaining: state.src.slice(pos) });
} while (pos + fenceLen < endOfLine);
if (closer) {
state.tokens.push(closer);
debug({ l: 169, tokens: [ closer ] });
}
openIndex += fenceLen;
pos = openIndex;
state.line = startLine;
return true;
});
};

View File

@ -0,0 +1,46 @@
const { flatten } = require('lodash');
module.exports = exports = function (md) {
md.core.ruler.push(
'modify-token',
(state) => {
state.tokens = flatten(state.tokens.map(descend).filter(Boolean));
return false;
},
);
};
function descend (token) {
switch (token.type) {
case 'link_open':
case 'link_close':
case 'html_block':
return false;
case 'heading_open':
token.type = 'paragraph_open';
token.tag = 'p';
token.markup = '';
return token;
case 'heading_close':
token.type = 'paragraph_close';
token.tag = 'p';
token.markup = '';
return token;
case 'image':
case 'container':
return token.children;
default:
if (token.children && token.children.length) {
token.children = flatten(token.children.map(descend).filter(Boolean));
}
return token;
}
}

47
gulp/lib/random.js Normal file
View File

@ -0,0 +1,47 @@
'use strict';
var crypto = require('crypto');
var uuid = require('uuid').v4;
// based on code from http://stackoverflow.com/a/25690754/110189
function randomString (length, chars) {
if (!chars) {
throw new Error('Argument \'chars\' is undefined');
}
var charsLength = chars.length;
if (charsLength > 256) {
throw new Error('Length must be less than 256 characters');
}
var randomBytes = crypto.randomBytes(length);
var result = new Array(length);
var cursor = 0;
for (var i = 0; i < length; i++) {
cursor += randomBytes[i];
result[i] = chars[cursor % charsLength];
}
return result.join('');
}
module.exports = exports = function (min, max) {
if (Array.isArray(min)) return exports.from(min);
if (typeof max === 'undefined') {
if (min > 0) {
max = min;
min = 0;
} else {
max = 0;
}
}
return Math.floor((Math.random() * (max - min + 1)) + min);
};
exports.alphanumeric = (length) => randomString(length, 'ABCDEFGHIJKLMNOPQRSTUWXYZ0123456789');
exports.alpha = (length) => randomString(length, 'ABCDEFGHIJKLMNOPQRSTUWXYZ');
exports.fromCharSet = randomString;
exports.from = (array) => array[exports(array.length - 1)];
exports.id = (length) => uuid().replace(/-/g, '').substr(0, length);

27
gulp/lib/sort.js Normal file
View File

@ -0,0 +1,27 @@
const through = require('./through');
const sortBy = require('lodash/sortBy');
function sleep (ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
module.exports = exports = function (iteratees) {
var files = [];
return through(
async (stream, file) => {
if (file.isNull()) return;
files.push(file);
},
async (stream) => {
const queue = sortBy(files, iteratees);
files = null;
for (const file of queue) {
stream.push(file);
await sleep(100);
}
}
);
};

19
gulp/lib/through.js Normal file
View File

@ -0,0 +1,19 @@
const log = require('fancy-log');
var through = require('through2');
module.exports = exports = function asyncthrough (...args) {
const [ fn, donefn ] = args;
args[0] = function (file, enc, next) {
fn(this, file, enc).then(() => next(), (err) => { log.error(err, 'Error thrown'); next(err); });
};
if (donefn) {
args[1] = function (next) {
donefn(this).then(() => next(), (err) => { log.error(err, 'Error thrown'); next(err); });
};
}
return through.obj(...args);
};

140
gulp/lib/tweetparse.js Normal file
View File

@ -0,0 +1,140 @@
var twemoji = require('twemoji' );
const { deepPick, has } = require('./util');
const schema = {
id_str: true,
created_at: true,
user: {
screen_name: true,
avatar: true,
name_html: true,
verified: true,
protected: true,
},
html: true,
quoted_status: {
user: {
screen_name: true,
avatar: true,
name_html: true,
verified: true,
protected: true,
},
},
entities: { media: [ {
type: true,
media_url_https: true,
video_info: { variants: [ {
url: true,
content_type: true,
} ] },
} ] },
media: true,
};
var entityProcessors = {
hashtags (tags, tweet) {
tags.forEach((tagObj) => {
tweet.html = tweet.html.replace('#' + tagObj.text, `<a href="https://twitter.com/hashtag/{tagObj.text}" class="hashtag">#${tagObj.text}</a>`);
});
},
symbols (/* symbols, tweet */) {
},
user_mentions (users, tweet) {
users.forEach((userObj) => {
var regex = new RegExp('@' + userObj.screen_name, 'gi' );
tweet.html = tweet.html.replace(regex, `<a href="https://twitter.com/${userObj.screen_name}" class="mention">@${userObj.screen_name}</a>`);
});
},
urls (urls, tweet) {
urls.forEach((urlObj) => {
var quotedTweetHtml = '';
var indices = urlObj.indices;
var urlToReplace = (tweet.full_text || tweet.text).substring(indices[0], indices[1]);
var finalText = quotedTweetHtml || urlObj.display_url.link(urlObj.expanded_url);
tweet.html = tweet.html.replace(urlToReplace, finalText);
});
},
media (media, tweet) {
media.forEach((mediaObj) => {
tweet.html = tweet.html.replace(mediaObj.url, '');
return;
// if (mediaObj.type === 'photo') {
// // Use HTTPS if available
// var src = mediaObj.media_url_https ? mediaObj.media_url_https : mediaObj.media_url;
// if (options &&
// options.photoSize &&
// mediaObj.sizes &&
// mediaObj.sizes[options.photoSize]) {
// // If specified size is available, patch image src to use it
// src = src + ':' + options.photoSize;
// }
// tweet.html = tweet.html.replace(mediaObj.url, `<img src="${src}" alt=""/>`);
// } else if (mediaObj.type === 'video') {
// var source = '';
// mediaObj.video_info.variants.forEach((info) => {
// source += `<source src="${info.url}" type="${info.content_type}">`;
// });
// var video = `<video controls poster="${mediaObj.media_url}">${source}</video>`;
// tweet.html = tweet.html.replace(mediaObj.url, video);
// }
});
},
};
module.exports = exports = function (tweets) {
return Array.isArray(tweets) ? tweets.map(parseTweet) : parseTweet(tweets);
function parseTweet (tweet) {
// clone the tweet so we're not altering the original
tweet = JSON.parse(JSON.stringify(tweet));
tweet.user.avatar = {
input: tweet.user.profile_image_url_https,
output: 'tweets/' + tweet.user.screen_name + '.jpg',
};
tweet.media = [
tweet.user.avatar,
];
// Copying text value to a new property html. The final output will be set to this property
tweet.html = (tweet.full_text || tweet.text)
.split(/(\r\n|\n\r|\r|\n)+/)
.map((s) => s.trim() && '<p>' + s + '</p>')
.filter(Boolean)
.join('');
if (tweet.quoted_status) {
tweet.quoted_status = parseTweet(tweet.quoted_status);
}
if (has(tweet, 'entities.media') && has(tweet, 'extended_entities.media')) {
tweet.entities.media = tweet.extended_entities.media;
delete tweet.extended_entities;
}
// Process entities
if (Object.getOwnPropertyNames(tweet.entities).length) {
for (let [ entityType, entity ] of Object.entries(tweet.entities)) { // eslint-disable-line prefer-const
entityProcessors[entityType](entity, tweet);
}
}
// Process Emoji's
tweet.html = twemoji.parse(tweet.html);
tweet.user.name_html = twemoji.parse(tweet.user.name);
return deepPick(tweet, schema);
}
};

1480
gulp/lib/util.js Normal file

File diff suppressed because it is too large Load Diff

35
gulp/new.js Normal file
View File

@ -0,0 +1,35 @@
const argv = require('minimist')(process.argv.slice(2));
const format = require('date-fns/format');
const parse = require('date-fns/parse');
const random = require('./lib/random');
const path = require('path');
const fs = require('fs-extra');
const log = require('fancy-log');
const template = require('./_template');
const ROOT = path.dirname(__dirname);
module.exports = exports = async function newPost () {
var date = argv.date ? parse(argv.date, 'yyyy-MM-dd', new Date()) : new Date();
if (!date.getHours()) {
const now = new Date();
date.setHours(now.getHours());
date.setMinutes(now.getMinutes());
}
// console.log(date);return;
var id = random.id().substr(-6).toUpperCase();
var fname = format(date, 'yyyy-MM-dd.HHmm.') + id;
var target = path.join(ROOT, 'posts', fname);
await fs.ensureDir(target);
var contents = template({ id, date });
await fs.writeFile(path.join(target, 'index.md'), contents);
log('Created new post at posts/' + fname);
};

83
gulp/publish.js Normal file
View File

@ -0,0 +1,83 @@
const { src } = require('gulp');
const awspublish = require('gulp-awspublish');
const awsrouter = require('gulp-awspublish-router');
const parallelize = require('concurrent-transform');
// const cloudfront = require('gulp-cloudfront-invalidate-aws-publish');
const debug = require('./lib/debug');
// const path = require('path');
// const ROOT = path.dirname(__dirname);
const DEST = 'dist';
var credentials = require('../aws.json');
const routes = {
'p\\/.*\\.(?:jpeg|jpg|png|gif)$': {
cacheTime: 86400, // one day on client
sharedCacheTime: 2592000, // 30 days on server
},
'^(?:index|tags|drafts)\\.html$': {
cacheTime: 60, // one minute on client
sharedCacheTime: 60, // one minute on server
},
'^(?:sitemap|atom)\\.xml$': {
cacheTime: 3600, // one hour on client
sharedCacheTime: 86400, // one day on server
},
'^404\\.html$': {
cacheTime: 2592000, // 30 days on server
sharedCacheTime: 2592000, // 30 days on server
},
'\\.html$': {
cacheTime: 3600, // 1 hour on client
sharedCacheTime: 3600, // 1 hour on server
},
'\\.(?:js|css)$': {
cacheTime: 604800, // one week on client
sharedCacheTime: 2592000, // one month on server
},
// pass-through for anything that wasn't matched by routes above, to be uploaded with default options
'^.+$': '$&',
};
module.exports = exports = function s3deploy () {
var publisher = awspublish.create(credentials);
return src(`${DEST}/**/*`)
.pipe(awsrouter({
cache: {
gzip: true,
cacheTime: 1800, // 30 minutes on client
sharedCacheTime: 86400, // one day on server
},
routes,
}))
.pipe(parallelize(publisher.publish(), 10))
.pipe(publisher.sync())
.pipe(publisher.cache())
.pipe(awspublish.reporter({
states: [ 'create', 'update', 'delete' ],
}));
};
exports.dryrun = function s3DryRun () {
return src(`${DEST}/**/*`)
.pipe(awsrouter({
cache: {
gzip: true,
cacheTime: 1800, // 30 minutes on client
sharedCacheTime: 86400, // one day on server
},
routes,
}))
.pipe(debug('s3'))
;
};

72
gulp/rollup.js Normal file
View File

@ -0,0 +1,72 @@
const path = require('path');
const { src, dest } = require('gulp');
const rollup = require('gulp-better-rollup');
const { string } = require('rollup-plugin-string');
const resolveNodeModules = require('rollup-plugin-node-resolve');
const commonJs = require('rollup-plugin-commonjs');
const json = require('rollup-plugin-json');
// const alias = require('rollup-plugin-alias');
const minify = require('gulp-minify');
const rev = require('gulp-rev');
const asyncthrough = require('./lib/through');
const ROOT = path.dirname(__dirname);
const DEST = 'dist/js';
function rollupPipe () {
return src('js-rollup/*.js')
.pipe(rollup({
// There is no `input` option as rollup integrates into the gulp pipeline
plugins: [
string({
include: '**/*.html',
}),
resolveNodeModules(),
commonJs(),
json(),
],
external: [ 'jquery', 'lodash', 'underscore' ],
}, {
// Rollups `sourcemap` option is unsupported. Use `gulp-sourcemaps` plugin instead
format: 'iife',
globals: {
jquery: '$',
lodash: '_',
backbone: 'Backbone',
underscore: '_',
},
}));
};
module.exports = exports = function rollupJS () {
return rollupPipe()
.pipe(dest(DEST));
};
exports.prod = function rollupJSForProd () {
return rollupPipe()
.pipe(minify({
ext: { min: '.js' },
noSource: true,
}))
.pipe(dest(DEST))
.pipe(rev())
.pipe(dest(DEST))
.pipe(asyncthrough(async (stream, file) => {
// Change rev's original base path back to the public root so that it uses the full
// path as the original file name key in the manifest
var base = path.resolve(ROOT, 'dist');
file.revOrigBase = base;
file.base = base;
stream.push(file);
}))
.pipe(rev.manifest({
merge: true, // Merge with the existing manifest if one exists
}))
.pipe(dest('.'))
;
};

52
gulp/scripts.js Normal file
View File

@ -0,0 +1,52 @@
const path = require('path');
const { src, dest } = require('gulp');
const minify = require('gulp-minify');
const rev = require('gulp-rev');
const concat = require('gulp-concat');
const merge = require('merge-stream');
const asyncthrough = require('./lib/through');
const ROOT = path.dirname(__dirname);
const DEST = 'dist/js';
module.exports = exports = function sourceJS () {
return merge(
src([ 'js/*.js', 'js/_*.js' ]),
src([
require.resolve('jquery'),
require.resolve('magnific-popup'),
require.resolve('popper.js/dist/umd/popper.js'),
require.resolve('bootstrap/js/dist/util.js'),
require.resolve('bootstrap/js/dist/dropdown.js'),
'js/_*.js',
]).pipe(concat('global.js')),
).pipe(dest(DEST));
};
exports.prod = function sourceJSForProd () {
return exports()
.pipe(minify({
ext: { min: '.js' },
noSource: true,
}))
.pipe(dest(DEST))
.pipe(rev())
.pipe(dest(DEST))
.pipe(asyncthrough(async (stream, file) => {
// Change rev's original base path back to the public root so that it uses the full
// path as the original file name key in the manifest
var base = path.resolve(ROOT, 'dist');
file.revOrigBase = base;
file.base = base;
stream.push(file);
}))
.pipe(rev.manifest({
merge: true, // Merge with the existing manifest if one exists
}))
.pipe(dest('.'))
;
};

59
gulp/scss.js Normal file
View File

@ -0,0 +1,59 @@
const path = require('path');
const { src, dest } = require('gulp');
const scss = require('gulp-sass');
const rev = require('gulp-rev');
const asyncthrough = require('./lib/through');
const crass = require('./lib/crass');
const concat = require('gulp-concat');
const merge = require('merge-stream');
const postcss = require('gulp-postcss');
const autoprefixer = require('autoprefixer');
// const minifyCSS = require('gulp-minify-css');
const ROOT = path.dirname(__dirname);
const DEST = 'dist/css';
module.exports = exports = function buildScss () {
const scssStream = src([ 'scss/*.scss', '!scss/_*.scss' ])
.pipe(scss({
includePaths: [ path.join(ROOT, 'node_modules') ],
}));
return merge(
scssStream,
src([
require.resolve('magnific-popup/dist/magnific-popup.css'),
]),
)
.pipe(concat('style.css'))
.pipe(postcss([
autoprefixer(),
]))
.pipe(dest(DEST));
};
exports.prod = function buildScssForProd () {
return exports()
.pipe(crass())
.pipe(dest(DEST))
.pipe(rev())
.pipe(dest(DEST))
.pipe(asyncthrough(async (stream, file) => {
// Change rev's original base path back to the public root so that it uses the full
// path as the original file name key in the manifest
var base = path.resolve(ROOT, 'dist');
file.revOrigBase = base;
file.base = base;
stream.push(file);
}))
.pipe(rev.manifest({
merge: true, // Merge with the existing manifest if one exists
}))
.pipe(dest('.'))
;
};

2
gulpfile.js Normal file
View File

@ -0,0 +1,2 @@
module.exports = exports = require('./gulp');

12
js/.eslintrc Normal file
View File

@ -0,0 +1,12 @@
{
"extends": "twipped/browser",
"env": {"es6": true, "jquery": true},
"rules": {
'indent': [ 2, 2, {
'MemberExpression': 1,
} ],
'prefer-arrow-callback': 0,
'object-shorthand': 0,
'node/no-unsupported-features/node-builtins': 0
}
}

10
js/_header.js Normal file
View File

@ -0,0 +1,10 @@
$(function () {
let active = false;
window.addEventListener('scroll', function () {
const state = window.scrollY > 10;
if (active !== state) {
$('header').toggleClass('active', state);
active = state;
}
});
});

26
js/_lightbox.js Normal file
View File

@ -0,0 +1,26 @@
(function ($) {
$('.lightbox, .gutter').each(function () {
$(this).magnificPopup({
delegate: 'a.lb',
type: 'image',
closeOnContentClick: false,
closeBtnInside: false,
mainClass: 'mfp-with-zoom mfp-img-mobile',
image: {
verticalFit: true,
},
gallery: {
enabled: true,
},
zoom: {
enabled: true,
duration: 300, // don't foget to change the duration also in CSS
opener: function (element) {
return element.find('img');
},
},
});
});
}(window.jQuery));

92
js/i.js Normal file
View File

@ -0,0 +1,92 @@
(function (window, document, navigator) {
const me = document.currentScript;
const url = me.getAttribute('data-url');
const iOS = !!navigator.platform && /iPad|iPhone|iPod/.test(navigator.platform);
const vendor = navigator.vendor;
const doNotTrack = navigator.doNotTrack || navigator.msDoNotTrack || window.doNotTrack;
let tid = !doNotTrack && window.localStorage.getItem('tid');
if (!tid && !doNotTrack) {
tid = Math.round(Math.random() * 1000000000);
window.localStorage.setItem('tid', tid);
}
const body = document.body;
const html = document.documentElement;
const SESSION_DATA = {
tid,
start: Date.now(),
end: null,
max_scroll: 0,
language: navigator.userLanguage || navigator.language,
href: window.location.pathname,
referrer: document.referrer,
};
// listen for all the exit events
window.addEventListener('pagehide', endSession);
window.addEventListener('beforeunload', endSession);
window.addEventListener('unload', endSession);
// for iOS when the focus leaves the tab
if (iOS) window.addEventListener('blur', endSession);
window.addEventListener('load', sendSession);
// scroll tracking
window.addEventListener('scroll', function () {
const page_height = Math.max(
body.scrollHeight,
body.offsetHeight,
html.clientHeight,
html.scrollHeight,
html.offsetHeight,
);
const viewport_height = Math.max(html.clientHeight, window.innerHeight || 0);
const max_scroll = Math.max(SESSION_DATA.max_scroll, window.scrollY);
const viewed = max_scroll === 0 ? 0 : Math.round(((max_scroll + viewport_height) / page_height) * 100);
Object.assign(SESSION_DATA, { page_height, viewport_height, max_scroll, viewed });
});
let skip;
function endSession () {
if (skip) return;
skip = true;
SESSION_DATA.end = Date.now();
sendSession();
}
// call this function on exit
function sendSession () {
const params = new URLSearchParams(SESSION_DATA);
const data = params.toString();
// Instead, send an async request
// Except for iOS :(
const async = !iOS;
const request = new XMLHttpRequest();
request.open('GET', url + '?' + data, async); // 'false' makes the request synchronous
request.setRequestHeader('Content-Type', 'application/json');
request.send(data);
// Synchronous request cause a slight delay in UX as the browser waits for the response
// I've found it more performant to do an async call and use the following hack to keep the loop open while waiting
// Chrome doesn't care about waiting
if (!async || ~vendor.indexOf('Google')) return;
// Latency calculated from navigator.performance
const latency = data.latency || 0;
const t = Date.now() + Math.max(300, latency + 200);
while (Date.now() < t) {
// postpone the JS loop for 300ms so that the request can complete
// a hack necessary for Firefox and Safari refresh / back button
}
}
}(window, document, navigator));

10533
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

94
package.json Normal file
View File

@ -0,0 +1,94 @@
{
"name": "genderdysphoria.fyi",
"version": "1.0.0",
"description": "Code for construction of the GenderDysphoria.fyi website",
"scripts": {
"test": "eslint ./ --fix"
},
"engines": {
"node": ">=12.14.0"
},
"author": "Jocelyn Badgley <joc@twipped.com> (http://twipped.com/)",
"siteInfo": {
"title": "That's Gender Dysphoria, FYI",
"domain": "genderdysphoria.fyi",
"rss": {
"title": "That's Gender Dysphoria, FYI",
"feed_url": "https://genderdysphoria.fyi/atom.xml",
"site_url": "https://genderdysphoria.fyi",
"image_url": "https://genderdysphoria.fyi/favicon228.png"
}
},
"license": "MIT",
"devDependencies": {
"autoprefixer": "~9.7.4",
"aws-sdk": "~2.616.0",
"backbone": "~1.4.0",
"bluebird": "~3.7.2",
"bootstrap": "~4.4.1",
"concurrent-transform": "~1.0.0",
"crass": "~0.12.3",
"date-fns": "~2.9.0",
"eslint": "~6.8.0",
"eslint-config-twipped": "~3.3.0",
"eslint-plugin-node": "~11.0.0",
"eslint-plugin-promise": "~4.2.1",
"express": "~4.17.1",
"fancy-log": "~1.3.3",
"forever": "~2.0.0",
"fs-extra": "~8.1.0",
"glob": "~7.1.6",
"gm": "~1.23.1",
"gulp": "~4.0.2",
"gulp-awspublish": "~4.0.1",
"gulp-awspublish-router": "~0.2.0",
"gulp-better-rollup": "~4.0.1",
"gulp-changed": "~4.0.2",
"gulp-clean": "~0.4.0",
"gulp-cloudfront-invalidate-aws-publish": "~1.0.0",
"gulp-collect": "~0.1.0",
"gulp-concat": "~2.6.1",
"gulp-filter": "~6.0.0",
"gulp-front-matter": "~1.3.0",
"gulp-minify": "~3.1.0",
"gulp-postcss": "~8.0.0",
"gulp-rev": "~9.0.0",
"gulp-sass": "~4.0.2",
"handlebars": "~4.7.3",
"hbs-kit": "~1.2.0",
"html-minifier-terser": "~5.0.4",
"image-size": "~0.8.3",
"jquery": "~3.4.1",
"lodash": "~4.17.15",
"magnific-popup": "~1.1.0",
"make-fetch-happen": "~7.1.1",
"markdown-it": "~10.0.0",
"markdown-it-anchor": "~5.2.5",
"memoizepromise": "~2.0.0",
"merge-stream": "~2.0.0",
"minimist": "~1.2.0",
"morgan": "~1.9.1",
"node-sass": "~4.13.1",
"plugin-error": "~1.0.1",
"png-to-ico": "~2.0.6",
"popper.js": "~1.16.0",
"rev-hash": "~3.0.0",
"rev-path": "~2.0.0",
"rollup": "~1.31.0",
"rollup-plugin-alias": "~2.2.0",
"rollup-plugin-commonjs": "~10.1.0",
"rollup-plugin-json": "~4.0.0",
"rollup-plugin-node-resolve": "~5.2.0",
"rollup-plugin-string": "~3.0.0",
"rss": "~1.2.2",
"serve-index": "~1.9.1",
"slugify": "~1.3.6",
"string-strip-html": "~4.3.16",
"through2": "~3.0.1",
"twemoji": "~12.1.5",
"twitter-lite": "~0.9.4",
"uuid": "~3.4.0",
"vinyl": "~2.2.0"
},
"dependencies": {}
}

4
pages/_disclaimer.hbs Normal file
View File

@ -0,0 +1,4 @@
<div class="disclaimer">
<strong>The Gender Dysphoria Bible is a Living Document</strong>
<p>The contents of this site will change over time as new additions and revisions are made to further expand upon the full breadth of Gender Dysphoria. In its current iteration it is severely lacking in AFAB narratives, non-binary, agender &amp; genderfluid specific dysphoria, and Third Gender narratives. The GDB is an open source and publicly funded project, <a href="https://github.com/GenderDysphoria/GenderDysphoria.fyi">content</a> and <a href="https://patreon.com/curvyandtrans">fiscal</a> contributions are extremely welcome.</p>
</div>

Binary file not shown.

After

Width:  |  Height:  |  Size: 951 KiB

View File

Before

Width:  |  Height:  |  Size: 6.0 KiB

After

Width:  |  Height:  |  Size: 6.0 KiB

View File

Before

Width:  |  Height:  |  Size: 115 KiB

After

Width:  |  Height:  |  Size: 115 KiB

View File

Before

Width:  |  Height:  |  Size: 273 KiB

After

Width:  |  Height:  |  Size: 273 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 KiB

View File

Before

Width:  |  Height:  |  Size: 1.3 MiB

After

Width:  |  Height:  |  Size: 1.3 MiB

View File

Before

Width:  |  Height:  |  Size: 74 KiB

After

Width:  |  Height:  |  Size: 74 KiB

View File

Before

Width:  |  Height:  |  Size: 123 KiB

After

Width:  |  Height:  |  Size: 123 KiB

View File

Before

Width:  |  Height:  |  Size: 63 KiB

After

Width:  |  Height:  |  Size: 63 KiB

View File

Before

Width:  |  Height:  |  Size: 58 KiB

After

Width:  |  Height:  |  Size: 58 KiB

View File

Before

Width:  |  Height:  |  Size: 221 KiB

After

Width:  |  Height:  |  Size: 221 KiB

View File

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 48 KiB

View File

Before

Width:  |  Height:  |  Size: 84 KiB

After

Width:  |  Height:  |  Size: 84 KiB

21
pages/gdb/_menu.hbs Normal file
View File

@ -0,0 +1,21 @@
<div class="dropdown-menu" aria-labelledby="nav-gdb">
<a href="/gdb/" class="{{#is meta.url '/gdb/index' '/' }}active {{/is}}dropdown-item">Introduction</a>
<a href="/gdb/what-is-gender" class="{{#is meta.url '/gdb/what-is-gender' }}active {{/is}}dropdown-item">What is Gender?</a>
<a href="/gdb/history" class="{{#is meta.url '/gdb/history' }}active {{/is}}dropdown-item">The History of Gender Dysphoria</a>
<a href="/gdb/euphoria" class="{{#is meta.url '/gdb/euphoria' }}active {{/is}}dropdown-item">Gender Euphoria</a>
<a href="/gdb/physical-dysphoria" class="{{#is meta.url '/gdb/physical-dysphoria' }}active {{/is}}dropdown-item">Physical Dysphoria</a>
<a href="/gdb/biochemical-dysphoria" class="{{#is meta.url '/gdb/biochemical-dysphoria' }}active {{/is}}dropdown-item">Biochemical Dysphoria</a>
<a href="/gdb/social-dysphoria" class="{{#is meta.url '/gdb/social-dysphoria' }}active {{/is}}dropdown-item">Social Dysphoria</a>
<a href="/gdb/societal-dysphoria" class="{{#is meta.url '/gdb/societal-dysphoria' }}active {{/is}}dropdown-item">Societal Dysphoria</a>
<a href="/gdb/sexual-dysphoria" class="{{#is meta.url '/gdb/sexual-dysphoria' }}active {{/is}}dropdown-item">Sexual Dysphoria</a>
<a href="/gdb/presentational-dysphoria" class="{{#is meta.url '/gdb/presentational-dysphoria'}}active {{/is}}dropdown-item">Presentational Dysphoria</a>
<a href="/gdb/historical-dysphoria" class="{{#is meta.url '/gdb/historical-dysphoria' }}active {{/is}}dropdown-item">Historical Dysphoria</a>
<a href="/gdb/managed-dysphoria" class="{{#is meta.url '/gdb/managed-dysphoria' }}active {{/is}}dropdown-item">Managed Dysphoria</a>
<a href="/gdb/impostor-syndrome" class="{{#is meta.url '/gdb/impostor-syndrome' }}active {{/is}}dropdown-item">Impostor Syndrome</a>
<a href="/gdb/diagnoses" class="{{#is meta.url '/gdb/diagnoses' }}active {{/is}}dropdown-item">Clinical Diagnoses</a>
<a href="/gdb/treatment" class="{{#is meta.url '/gdb/treatment' }}active {{/is}}dropdown-item">Treating Gender Dysphoria</a>
<a href="/gdb/causes" class="{{#is meta.url '/gdb/causes' }}active {{/is}}dropdown-item">Causes of Gender Dysphoria</a>
<a href="/gdb/chromosomes" class="{{#is meta.url '/gdb/chromosomes' }}active {{/is}}dropdown-item">Chromosomes</a>
<a href="/gdb/conclusion" class="{{#is meta.url '/gdb/conclusion' }}active {{/is}}dropdown-item">Conclusion</a>
</div>

View File

@ -1,37 +1,43 @@
<div class="pager"> <div class="pager {{className}}">
{{#is step 0 1 }}<span class="filler"></span>{{/is}} <div class="back">
{{#is step 2}}<a href="/gdb/what-is-gender" class="btn btn-primary">{{icon 'chevron-left'}} What Is Gender?</a>{{/is}} {{#is meta.url '/gdb/what-is-gender' }}<a href="/gdb/" class="btn btn-primary left">{{icon 'chevron-left'}} Introduction</a>{{/is}}
{{#is step 3}}<a href="/gdb/gd-history" class="btn btn-primary">{{icon 'chevron-left'}} The History of Gender Dysphoria</a>{{/is}} {{#is meta.url '/gdb/history' }}<a href="/gdb/what-is-gender" class="btn btn-primary left">{{icon 'chevron-left'}} What Is Gender?</a>{{/is}}
{{#is step 4}}<a href="/gdb/euphoria" class="btn btn-primary">{{icon 'chevron-left'}} Gender Euphoria</a>{{/is}} {{#is meta.url '/gdb/euphoria' }}<a href="/gdb/history" class="btn btn-primary left">{{icon 'chevron-left'}} The History of Gender Dysphoria</a>{{/is}}
{{#is step 5}}<a href="/gdb/physical-dysphoria" class="btn btn-primary">{{icon 'chevron-left'}} Physical Dysphoria</a>{{/is}} {{#is meta.url '/gdb/physical-dysphoria' }}<a href="/gdb/euphoria" class="btn btn-primary left">{{icon 'chevron-left'}} Gender Euphoria</a>{{/is}}
{{#is step 6}}<a href="/gdb/biochemical-dysphoria" class="btn btn-primary">{{icon 'chevron-left'}} Biochemical Dysphoria</a>{{/is}} {{#is meta.url '/gdb/biochemical-dysphoria' }}<a href="/gdb/physical-dysphoria" class="btn btn-primary left">{{icon 'chevron-left'}} Physical Dysphoria</a>{{/is}}
{{#is step 7}}<a href="/gdb/social-dysphoria" class="btn btn-primary">{{icon 'chevron-left'}} Social Dysphoria</a>{{/is}} {{#is meta.url '/gdb/social-dysphoria' }}<a href="/gdb/biochemical-dysphoria" class="btn btn-primary left">{{icon 'chevron-left'}} Biochemical Dysphoria</a>{{/is}}
{{#is step 8}}<a href="/gdb/societal-dysphoria" class="btn btn-primary">{{icon 'chevron-left'}} Societal Dysphoria</a>{{/is}} {{#is meta.url '/gdb/societal-dysphoria' }}<a href="/gdb/social-dysphoria" class="btn btn-primary left">{{icon 'chevron-left'}} Social Dysphoria</a>{{/is}}
{{#is step 9}}<a href="/gdb/sexual-dysphoria" class="btn btn-primary">{{icon 'chevron-left'}} Sexual Dysphoria</a>{{/is}} {{#is meta.url '/gdb/sexual-dysphoria' }}<a href="/gdb/societal-dysphoria" class="btn btn-primary left">{{icon 'chevron-left'}} Societal Dysphoria</a>{{/is}}
{{#is step 10}}<a href="/gdb/presentational-dysphoria" class="btn btn-primary">{{icon 'chevron-left'}} Presentational Dysphoria</a>{{/is}} {{#is meta.url '/gdb/presentational-dysphoria'}}<a href="/gdb/sexual-dysphoria" class="btn btn-primary left">{{icon 'chevron-left'}} Sexual Dysphoria</a>{{/is}}
{{#is step 11}}<a href="/gdb/historical-dysphoria" class="btn btn-primary">{{icon 'chevron-left'}} Historical Dysphoria</a>{{/is}} {{#is meta.url '/gdb/historical-dysphoria' }}<a href="/gdb/presentational-dysphoria" class="btn btn-primary left">{{icon 'chevron-left'}} Presentational Dysphoria</a>{{/is}}
{{#is step 12}}<a href="/gdb/managed-dysphoria" class="btn btn-primary">{{icon 'chevron-left'}} Managed Dysphoria</a>{{/is}} {{#is meta.url '/gdb/managed-dysphoria' }}<a href="/gdb/historical-dysphoria" class="btn btn-primary left">{{icon 'chevron-left'}} Historical Dysphoria</a>{{/is}}
{{#is step 13}}<a href="/gdb/impostor-syndrome" class="btn btn-primary">{{icon 'chevron-left'}} Impostor Syndrome</a>{{/is}} {{#is meta.url '/gdb/impostor-syndrome' }}<a href="/gdb/managed-dysphoria" class="btn btn-primary left">{{icon 'chevron-left'}} Managed Dysphoria</a>{{/is}}
{{#is step 14}}<a href="/gdb/diagnoses" class="btn btn-primary">{{icon 'chevron-left'}} Clinical Diagnoses</a>{{/is}} {{#is meta.url '/gdb/diagnoses' }}<a href="/gdb/impostor-syndrome" class="btn btn-primary left">{{icon 'chevron-left'}} Impostor Syndrome</a>{{/is}}
{{#is step 15}}<a href="/gdb/treatment" class="btn btn-primary">{{icon 'chevron-left'}} Treating Gender Dysphoria</a>{{/is}} {{#is meta.url '/gdb/treatment' }}<a href="/gdb/diagnoses" class="btn btn-primary left">{{icon 'chevron-left'}} Clinical Diagnoses</a>{{/is}}
{{#is step 16}}<a href="/gdb/causes" class="btn btn-primary">{{icon 'chevron-left'}} Causes of Gender Dysphoria</a>{{/is}} {{#is meta.url '/gdb/causes' }}<a href="/gdb/treatment" class="btn btn-primary left">{{icon 'chevron-left'}} Treating Gender Dysphoria</a>{{/is}}
{{#is step 17}}<a href="/gdb/chromosomes" class="btn btn-primary">{{icon 'chevron-left'}} Disorders of Sexual Development</a>{{/is}} {{#is meta.url '/gdb/chromosomes' }}<a href="/gdb/causes" class="btn btn-primary left">{{icon 'chevron-left'}} Causes of Gender Dysphoria</a>{{/is}}
{{#is meta.url '/gdb/conclusion' }}<a href="/gdb/chromosomes" class="btn btn-primary left">{{icon 'chevron-left'}} Disorders of Sexual Development</a>{{/is}}
</div>
<div class="forward">
{{#is meta.url '/gdb' '/' }}<a href="/gdb/what-is-gender" class="btn btn-primary right">Continue Reading {{icon 'chevron-right'}}</a>{{/is}}
{{#is meta.url '/gdb/what-is-gender' }}<a href="/gdb/history" class="btn btn-primary right">The History of Gender Dysphoria {{icon 'chevron-right'}}</a>{{/is}}
{{#is meta.url '/gdb/history' }}<a href="/gdb/euphoria" class="btn btn-primary right">Gender Euphoria {{icon 'chevron-right'}}</a>{{/is}}
{{#is meta.url '/gdb/euphoria' }}<a href="/gdb/physical-dysphoria" class="btn btn-primary right">Physical Dysphoria {{icon 'chevron-right'}}</a>{{/is}}
{{#is meta.url '/gdb/physical-dysphoria' }}<a href="/gdb/biochemical-dysphoria" class="btn btn-primary right">Biochemical Dysphoria {{icon 'chevron-right'}}</a>{{/is}}
{{#is meta.url '/gdb/biochemical-dysphoria' }}<a href="/gdb/social-dysphoria" class="btn btn-primary right">Social Dysphoria {{icon 'chevron-right'}}</a>{{/is}}
{{#is meta.url '/gdb/social-dysphoria' }}<a href="/gdb/societal-dysphoria" class="btn btn-primary right">Societal Dysphoria {{icon 'chevron-right'}}</a>{{/is}}
{{#is meta.url '/gdb/societal-dysphoria' }}<a href="/gdb/sexual-dysphoria" class="btn btn-primary right">Sexual Dysphoria {{icon 'chevron-right'}}</a>{{/is}}
{{#is meta.url '/gdb/sexual-dysphoria' }}<a href="/gdb/presentational-dysphoria" class="btn btn-primary right">Presentational Dysphoria {{icon 'chevron-right'}}</a>{{/is}}
{{#is meta.url '/gdb/presentational-dysphoria'}}<a href="/gdb/historical-dysphoria" class="btn btn-primary right">Historical Dysphoria {{icon 'chevron-right'}}</a>{{/is}}
{{#is meta.url '/gdb/historical-dysphoria' }}<a href="/gdb/managed-dysphoria" class="btn btn-primary right">Managed Dysphoria {{icon 'chevron-right'}}</a>{{/is}}
{{#is meta.url '/gdb/managed-dysphoria' }}<a href="/gdb/impostor-syndrome" class="btn btn-primary right">Impostor Syndrome {{icon 'chevron-right'}}</a>{{/is}}
{{#is meta.url '/gdb/impostor-syndrome' }}<a href="/gdb/diagnoses" class="btn btn-primary right">Clinical Diagnoses {{icon 'chevron-right'}}</a>{{/is}}
{{#is meta.url '/gdb/diagnoses' }}<a href="/gdb/treatment" class="btn btn-primary right">Treating Gender Dysphoria {{icon 'chevron-right'}}</a>{{/is}}
{{#is meta.url '/gdb/treatment' }}<a href="/gdb/causes" class="btn btn-primary right">Causes of Gender Dysphoria {{icon 'chevron-right'}}</a>{{/is}}
{{#is meta.url '/gdb/causes' }}<a href="/gdb/chromosomes" class="btn btn-primary right">But... but... the chromosomes! {{icon 'chevron-right'}}</a>{{/is}}
{{#is meta.url '/gdb/chromosomes' }}<a href="/gdb/conclusion" class="btn btn-primary right">Conclusion {{icon 'chevron-right'}}</a>{{/is}}
</div>
{{#is step 0}}<a href="/gdb/what-is-gender" class="btn btn-primary">Continue Reading {{icon 'chevron-right'}}</a>{{/is}}
{{#is step 1}}<a href="/gdb/gd-history" class="btn btn-primary">{{icon 'chevron-left'}} The History of Gender Dysphoria</a>{{/is}}
{{#is step 2}}<a href="/gdb/euphoria" class="btn btn-primary">{{icon 'chevron-left'}} Gender Euphoria</a>{{/is}}
{{#is step 3}}<a href="/gdb/physical-dysphoria" class="btn btn-primary">{{icon 'chevron-left'}} Physical Dysphoria</a>{{/is}}
{{#is step 4}}<a href="/gdb/biochemical-dysphoria" class="btn btn-primary">{{icon 'chevron-left'}} Biochemical Dysphoria</a>{{/is}}
{{#is step 5}}<a href="/gdb/social-dysphoria" class="btn btn-primary">{{icon 'chevron-left'}} Social Dysphoria</a>{{/is}}
{{#is step 6}}<a href="/gdb/societal-dysphoria" class="btn btn-primary">{{icon 'chevron-left'}} Societal Dysphoria</a>{{/is}}
{{#is step 7}}<a href="/gdb/sexual-dysphoria" class="btn btn-primary">{{icon 'chevron-left'}} Sexual Dysphoria</a>{{/is}}
{{#is step 8}}<a href="/gdb/presentational-dysphoria" class="btn btn-primary">{{icon 'chevron-left'}} Presentational Dysphoria</a>{{/is}}
{{#is step 9}}<a href="/gdb/historical-dysphoria" class="btn btn-primary">{{icon 'chevron-left'}} Historical Dysphoria</a>{{/is}}
{{#is step 10}}<a href="/gdb/managed-dysphoria" class="btn btn-primary">{{icon 'chevron-left'}} Managed Dysphoria</a>{{/is}}
{{#is step 11}}<a href="/gdb/impostor-syndrome" class="btn btn-primary">{{icon 'chevron-left'}} Impostor Syndrome</a>{{/is}}
{{#is step 12}}<a href="/gdb/diagnoses" class="btn btn-primary">{{icon 'chevron-left'}} Clinical Diagnoses</a>{{/is}}
{{#is step 13}}<a href="/gdb/treatment" class="btn btn-primary">{{icon 'chevron-left'}} Treating Gender Dysphoria</a>{{/is}}
{{#is step 14}}<a href="/gdb/causes" class="btn btn-primary">{{icon 'chevron-left'}} Causes of Gender Dysphoria</a>{{/is}}
{{#is step 15}}<a href="/gdb/chromosomes" class="btn btn-primary">{{icon 'chevron-left'}} Disorders of Sexual Development</a>{{/is}}
</div> </div>

View File

@ -0,0 +1,135 @@
---
date: "2020-01-26T20:41:55.827Z"
title: "How Gender Dysphoria Manifests: Biochemical Dysphoria"
description: "The very real and biological factors of Gender Dysphoria that cause mental disturbance."
tweets:
- '1215716438972993536'
- '1215736608055537670'
- '1215738145473474560'
- '1215740224325783553'
- '1222738910821978113'
- '1222739427312750594'
- '1222740261178105856'
- '1222742135067303937'
- '1222743360034758656'
- '1222743749920464896'
---
# Biochemical Dysphoria
The primary sexual features of the body begin development during the 8th week of human gestation. Typically by week 11 it is possible to determine the genitals of a fetus via ultrasound. The brain, however, forms itself in [between weeks 14 and 24](https://www.ncbi.nlm.nih.gov/pmc/articles/PMC2989000/#Sec5title). Current prevailing understanding of neurological development suggests that it is during these 10 weeks when the brain will either masculinize or feminize based upon the presence of testosterone in the infant's bloodstream (initiated by the SRY gene on the Y chromosome, or introduced from other sources). This process locks the brain into a pattern of either desiring estrogens or androgens.
If your brain is wired for one gonadal hormones (such as testosterone) and your body produces the other hormone (such as estradiol), this can result in a biochemical malfunction within your brain chemistry. This produces a sort of brain fog, a reduction in mental capacity, and a general state of anxiety and unease. This is the source of the first two symptoms that often alleviate with medical hormonal therapy, Depersonalization and Derealization (DPDR).
{!{
<div class="gutter">
<a class="card ig-card" href="https://www.instagram.com/p/B4fwhWAH2F-/">
<div class="ig-header">
<div class="ig-avatar" style="background-image: url(theredgrrl.jpg);"></div>
<div class="ig-name">
<strong>Brea</strong>
<span>theredgrrl</span>
</div>
</div>
{{#with images.brea_eyes}}
<img
src="{{rev sizes.0.url}}"
alt="{{alt}}"
srcset="{{#join sizes}}{{rev url}} {{width}}w{{/join}}"
sizes="{{#if srcSizes}}{{srcSizes}}{{else}}(max-width: 576px) 100vw, 576px{{/if}}"
class="ig-image"
>
{{/with}}
<p class="ig-caption">
#TransformationTuesday - As Ive often said on posts like this, our eyes reflect our lives. The biggest difference I see in how trans people look after transition is always the eyes; often looking sad or distant in the past, and being bright and full of life in the present
</p>
<p class="ig-footer">
<time datetime="2019-11-05T19:54:45+00:00">Nov 5, 2019</time>
</p>
</a>
</div>
}!}
**Depersonalization** is a disconnect from your own body, an inability to believe that the person you see in the mirror is actually yourself. You feel like you are watching someone else in your body. You may find yourself not caring about what happens to your body, lack of concern with weight changes or improving your fitness because you have no ownership of this fleshy vehicle that transports you around your life.
Zinnia Jones [gives these descriptions for Depersonalization](https://web.archive.org/web/20190406141617/https://genderanalysis.net/2017/06/depersonalization-in-gender-dysphoria-widespread-and-widely-unrecognized/):
- A sense of detachment or estrangement from your own thoughts, feelings, or body: “I know I have feelings but I dont feel them”
- Feeling split into two parts, with one going through the motions of participating in the world and one observing quietly: “There is this body that walks around and somebody else just watches”
- Feeling as if you have an “unreal” or absent self: “I have no self”
- Experiencing the world as distant, dreamlike, foggy, lifeless, colorless, artificial, like a picture with no depth, or less than real
- Being absorbed in yourself and experiencing a compulsive self-scrutiny or extreme rumination
- Having an ongoing and coherent dialog with yourself
- Feeling like a veil or glass wall separates you from the world
- Emotional or physical numbness, such as a feeling of having a head filled with cotton
- Lacking a sense of agency feeling flat, robotic, dead, or like a “zombie”
- Inability to imagine things
- Being able to think clearly, but feeling as if some essential quality is lacking from your thoughts or experience of the world
- A sense of disconnectedness from life, impeding you from creative and open involvement with the world
You may put little care into your physical appearance, reaching for only the basic utilitarian needs in clothing and personal hygiene. Alternatively, you may hyperfocus on your appearance, attempting to try to spark some kind of joy, any kind of feeling of pride in your own body, only to be met with more hollowness.
You may be unconcerned with the state of your body, perhaps not even fearing death, because you have so little attachment to your life.
{!{ <div class="gutter">{{inject '~/tweet' ids=(array
'1215716438972993536'
'1215736608055537670'
'1215738145473474560'
'1215740224325783553'
) tweets=meta.tweets className="collapse" }}</div> }!}
**Derealization** is a detachment from the world around you, a mental sense that everything you perceive is false.
- Your surroundings seem alien or unfamiliar, even if you've always been there, like someone has swapped out your house for a stage replica.
- Moving through the world feels like you're walking on a treadmill, with the buildings moving around you instead of you through them.
- Feeling emotionally disconnected from people you care about, as if you were separated by a glass wall, or like they are just actors pretending to be the people they claim to be.
- Surroundings that appear distorted, blurry, colorless, two-dimensional or artificial, or a heightened awareness and clarity of your surroundings. Leaves on trees feel like they have extra sharp edges, for example.
- Distortions in perception of time, such as recent events feeling like distant past.
- Distortions of distance and the size and shape of objects
- Feeling like a passive observer in the events of your life
If you found yourself strongly relating to The Matrix or The Truman Show, you might be experiencing derealization. This can also manifest as a feeling of otherworldliness, like you don't belong in this society. You're just walking around waiting for your super powers to appear, or for an owl to fly up with your letter to Hogwarts. As a teen I was obsessed with an episode of The Outer Limits where a boy discovers a spaceship under his house and learns that he and his parents aren't actually human.
DPDR sometimes comes with an emotional stunting. You are able to laugh and find humor, but rarely ever genuine joy. Moments of sadness or grief cause you to just go numb, dissociated by the event that caused it. This can also go in the opposite direction, where the person is under so much anxiety that their emotional response is extremely disproportionate to the catalyst, resulting in severe crying or violent outbursts from seemingly small events.
It's important to note that DPDR is not exclusive to Gender Dysphoria. This condition is co-morbid with several other mental health issues, including chronic depression, obsessive compulsive disorder and borderline personality disorder. DPDR should not be taken as a sign of Gender Dysphoria purely on its own, it's just a big alarm signal that something is very wrong. It's also usually pretty easy to spot externally, once you know how to watch for it. People with DPDR tend to have a mile long stare as they move about in the world; eyes so gloomy and dead that they look like a shell. One of the most common comments on transition timelines is how the eyes gain so much spark.
### The Ebb and Flow
The intensity of physical and biochemical dysphoria is highly influenced by other factors in the body. Because it is a function of endocrine balance, it is also manipulated by those balances. This means that it can rise and fall from day to day. For example:
- If your blood sugar is out of whack, or you have a thyroid condition, it could cause your dysphoria to spike.
- If you are having dopamine withdrawl because of ceasing stimulants, that can make it worse.
- If you start on an SSRI Antidepressant and start running with more serotonin, that can make it less intense.
- Transfeminine AMABs (people assigned male at birth) with testicles experience surges in testosterone in relation to attraction and desire, which can make them more dysphoric.
- Transmasculine AFABs (people assigned female at birth) with unsuppressed ovaries experience rises and falls in estrogen and progesterone over the course of their menstrual cycle, making their dysphoria worsen and lesson based on what day of the cycle they are one.
There are dozens of systems in the body that all work in tandem, and they all fluctuate from day to day, manipulating general mental state. This general dysphoria can amplify the affect of all other dysphoria. One day you can shrug off misgendering like it's nothing, and then the next it hurts like a stab in the heart every time. One day you see yourself in the mirror, the next you're staring at the old you.
Some people experience this in a genderfluid way, with some days leaning male, same days leaning female, and other days not feeling any gender, or both. Others just feel it like a seasonal river; sometimes it swells because of rains up stream, sometimes it slows to a trickle because of drought.
All of this is valid, and just because you feel very dysphoric one day and not dysphoric the next does not mean that you aren't really trans.
### This Happens Both Ways
{!{ <div class="gutter">{{inject '~/tweet' ids=(array
'1222738910821978113'
'1222739427312750594'
'1222740261178105856'
'1222742135067303937'
'1222743360034758656'
'1222743749920464896'
) tweets=meta.tweets className="oneblock" }}</div> }!}
Sometimes you will hear naysayers suggesting that taking hormone therapy always improves mental health. I heard this myself when I came out to my mother. "Estrogen makes everyone happier." This is flat out false. When cis people are put on cross hormone therapy it always results in dysphoria. This is one reason why Spironolactone is rarely ever prescribed to men, because the anti-androgen factor causes mental instability. Five to ten percent of cis women suffer from Polycystic Ovarian Syndrome (PCOS), a condition which causes the ovaries to produce testosterone instead of estrogen. Ask any one of them how their mental health has been, and they will give you an ear full.
One very potent demonstration of this is the tragic case of [David Reimer](https://en.wikipedia.org/wiki/David_Reimer). At seven months of age David and his twin brother were given circumcisions to treat a bad case of phimosis (a skin condition on the foreskin). David's went horribly wrong, and the penis was destroyed. The decision was made to perform vaginoplasty and raise him as a girl, including estrogen therapy at pubescence. By the age of 13 he was deep into suicidal depression and suffering greatly, as no amount of coaching and encouraging can make a boy enjoy being a girl. When his parents informed him of what had happened, he returned to a male presentation, switched to testosterone therapy, and over the course of his teen years had multiple operations in order to transition back to male.
People know when they're living the wrong gender.
Psychologist John Money oversaw David's case and was largely responsible for the decisions that were made in David's upbringing. Money, seeking to make a name for himself, massively misreported on David's case, calling it a complete success in his reports. The result of this echoes to this day, as Money's reports were used as an example of why performing genital corrective surgeries on intersex infants was an appropriate course of action. Fifty years later there are still doctors who believe that you can just change a child's genitals and raise them as that gender, and it will stick.
This is the tragedy of the [intersex](https://en.wikipedia.org/wiki/Intersex) community. Roughly one in every 60 births results in some kind of intersex condition (tho not all of these are related to genitalia). Often times the "corrective" procedures used on intersex children results in a loss of function and/or sensation. Far too frequently, doctors would opt towards forced female assignment because it was easier to construct a vulva than a penis.
{!{ {{inject '_pager'}} }!}

68
pages/gdb/causes.md Normal file
View File

@ -0,0 +1,68 @@
---
date: "2020-01-26T20:41:55.827Z"
title: "What is the Cause of Gender Incongruence"
description: "It's the hormones, baby."
tweets:
- https://twitter.com/LisaTMullin/status/1224039568971710464
- https://twitter.com/LisaTMullin/status/1224040716365524993
- https://twitter.com/LisaTMullin/status/1224041800513380352
- https://twitter.com/LisaTMullin/status/1224041800513380352
- https://twitter.com/LisaTMullin/status/1224042620164296705
- https://twitter.com/LisaTMullin/status/1224043995413639168
- https://twitter.com/LisaTMullin/status/1224044949160611840
---
#What is the Cause of Gender Incongruence?
Here is what we know today. If youve seen Jurassic Park then you may remember this scene:
{!{ {{inject '~/img' images.jurassicpark className="card borderless center span34" alt="All vertebrate embryos are inherently female anyway. They just require an extra hormone given at the right developmental stage to make them male."}} }!}
This isn't science fiction, tho it is very dumbed down. In human fetuses the gonads initially develop in a bi-potential state, meaning they can become either ovaries or testes. The SRY gene on the Y chromosome releases a protein called [Testis Determining Factor](https://en.wikipedia.org/wiki/Testis-determining_factor) (TDF). This protein then starts a chain reaction with SOX9 production (another protein), which causes the gonadal cells to form into the Sertoli and Leydig cells that make up the testes. If TDF is never produced or is interfered with then the gonad cells form into the Theca cells and follicles which comprise the ovaries.
{!{ <div class="gutter flex" style="justify-content: center"> {{inject '~/img' images.fetalgenitals className="card" caption="<a href=\"https://schoolbag.info/biology/concepts/188.html\">Source</a>" alt="Fetal development of internal sexual anatomy"}}</div> }!}
Once formed, the testes then begin producing a testosterone surge which typically starts in the 8th week of gestation and continues until the 24th week. This surge, [combined with another hormone from the placenta](https://www.sciencedaily.com/releases/2019/02/190214153053.htm), is responsible for the development of the penis and scrotum. Genitalia formation starts around week 9 and becomes identifiable by the 11th week. If the surge does not occur, or the body does not respond to it (such as in the case of Androgen Insensitivity Syndrome) then the genitalia form into the vulva, vagina and uterus instead.
If there is an interference in this process then you can end up with the wrong bits, and this is the result of many intersex conditions. Often times this is a partial development, where the external genitalia only partially form, but functional gonads still exist. Sometimes the child comes out with fully functional male or female genitalia, but mismatched gonads. Sometimes the TDF protein fails to release and the fetus grows completely functional female reproductive organs, despite the presence of a Y chromosome.
This is known as Swyer Syndrome, and an unknown number of women may have this condition. In 2015 [an XY woman with Swyer Syndrome who was born without ovaries](https://www.independent.co.uk/news/science/mostly-male-woman-gives-birth-to-twins-in-medical-miracle-10033528.html) successfully carried and gave birth to a child via IVF. Usually Swyer Syndrome results in completely non-functional ovaries, but [in 2008 a woman was found with Swyer Syndrome](https://www.ncbi.nlm.nih.gov/pmc/articles/PMC2190741/) who had gone through puberty, menstruated normally, and had two unassisted pregnancies. Her condition went undiscovered until her daughter was was found to also have it.
The fact is, the vast majority of the population has never been tested for genetic karyotype, so we dont know how common these cases actually are. Where does this come into affect for gender identity? Well, the exact same process that causes the external genitals to differentiate also occurs for the brain.
{!{ <div class="gutter">
<strong style="display: block;text-align: center;">And it gets even weirder!</strong>
{{inject '~/tweet' ids=(array
'1224039568971710464'
'1224040716365524993'
'1224041800513380352'
'1224041800513380352'
'1224042620164296705'
'1224043995413639168'
'1224044949160611840'
) tweets=meta.tweets className="oneblock hide-reply" }}</div> }!}
#### Brain Split
The prenatal brain doesnt really start to develop until between week 12 and 24. The cerebral cortex, the thin outer layer of the brain that contains most of what we think of as consciousness, grows substantially during those periods of time. Prior to that, the structure present is more like a scaffolding, the basic parts of the nervous system necessary for bodily function. The primary sulci (the wrinkles in the cerebral cortex that allow for more surface area) [start to form at week 14](https://www.ncbi.nlm.nih.gov/pmc/articles/PMC2989000/#Sec5title), well after the genitals have developed.
It [has been confirmed multiple times](https://www.the-scientist.com/features/are-the-brains-of-transgender-people-different-from-those-of-cisgender-people-30027) via MRI studies that there are small but significant differences between cis male and cis female brains, differences which align with the gender identities of trans people in the study. Note, **this does not mean that anyone with those differences will have that gender**, because gender identity isnt that simple, but it provides evidence that there is a clear difference in masculine and feminine brains.
A change in the testosterone levels in the fetus after the 11th week can directly impact the masculinization of the cerebral cortex, as well as changes in other parts of the brain structure. This has been examined [over and over again](https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4350266/) in studies of female assigned children with CAH (congenital adrenal hyperplasia) and CAIS (complete androgen insensitivity syndrome).
<blockquote class="cite"><p>We found a significant relationship between fetal testosterone and sexually differentiated play behavior in both girls and boys.</p>&mdash; <a href="https://www.ncbi.nlm.nih.gov/pmc/articles/PMC2778233/">Fetal Testosterone Predicts Sexually Differentiated Childhood Behavior in Girls and in Boys</a></blockquote>
An excess of testosterone in the mothers body during the second trimester can (and does) cause masculinization of the brain in an externally female fetus, and an interference in testosterone production or uptake can (and does) cause feminisation of an externally male fetus. This interference does not have to be external in origin, either. Any number of genetic traits can cause the brain to respond differently to testosterone.
A fairly large study of transgender individuals released in 2018 [found several key genes](https://academic.oup.com/jcem/article/104/2/390/5104458) which were statistically more likely to be longer among trans women (longer, as in having more repeated fragments). Individually these genes may not have an impact strong enough to cause a malfunction of masculinization, but collectively they absolutely could reduce the ability for the fetal brain to masculinize. These genes are all passed from parent to child, giving credence to a tendency for trans parents to have trans children.
#### Gender is Biological
Sadly, western society has actively prevented a deeper understanding of gender. Ancient civilizations understood it well, but colonialism wiped them off the map. 100 years ago, [scientists in Germany were actively studying](https://en.wikipedia.org/wiki/Institut_f%C3%BCr_Sexualwissenschaft) transgender medicine and made extraordinary advancements, until the nazis burned it all in 1933. Conservative and fascist pressures in the modern day have hindered advancements in transgender healthcare whenever possible.
Yet, progress continues, and every few years we learn a little bit more.
What we know for certain is that it is not a psychological condition, it is not something caused by trauma or by any external influence, nothing can make a person transgender. It happens in the womb, and is not something that a person can choose to be, any more than they could choose their race or their eye color. It has nothing to do with sexual orientation, it has nothing to do with kinks or fetishes, it has nothing to do with social influences from their parents or from their peers. [Transgender children are as firm in their identities as cisgender children are.](https://www.forbes.com/sites/dawnstaceyennis/2020/12/29/study-transgender-children-recognize-their-authentic-gender-at-early-age-just-like-other-kids/#20bbb14526bf).
{!{ {{inject '_pager'}} }!}

35
pages/gdb/changelog.md Normal file
View File

@ -0,0 +1,35 @@
## Change Log
The following changes that have been made to this document since release:
**1/27/2020**
- *Introduction*: Added paragraphs about how a person can realize their dysphoria at any stage of life.
- *Introduction*: Added paragraph about the growth within the transgender population.
- *Impostor Syndrome*: Added tweet about repetition of bigotry in "fear" of child conversion
- Fixed various typos
**1/30/2020**
- *Physical / Biochemical*
- Fixed the place where "uterus" should have been "fetus", as well as some other typos.
- Changed sentence on genderfluidity to be less binary in nature
- Added section on cis dysphoria and intersex operations
- Added section on body images issues aligning with true gender
- Social: Added a section about the tendency for trans folk to subconsciously self-select other trans folk.
- Added the History and What is GD sections to the menu.
**2/06/2020**
- Major overhaul of the Causes of Gender Dysphoria page to include lots more information about chromosomal anomalies.
**2/08/2020**
- Added "What is Gender" to the introduction.
- Moved History of GD and What Is GD into a new page.
{!{ {{inject '_pager'}} }!}

86
pages/gdb/chromosomes.md Normal file
View File

@ -0,0 +1,86 @@
---
date: "2020-01-26T20:41:55.827Z"
title: "Disorders of Sex Development: Gender is not Chromosomal"
description: "DNA is more what you'd call guidelines, than actual rules."
tweets:
- https://twitter.com/RebeccaRHelm/status/1207834357639139328
- https://twitter.com/RebeccaRHelm/status/1207835110617309191
- https://twitter.com/RebeccaRHelm/status/1207835384358604802
- https://twitter.com/RebeccaRHelm/status/1207835597206937600
- https://twitter.com/RebeccaRHelm/status/1207835815071473664
- https://twitter.com/RebeccaRHelm/status/1207835999130259456
- https://twitter.com/RebeccaRHelm/status/1207837155667718145
- https://twitter.com/RebeccaRHelm/status/1207838570276372480
- https://twitter.com/RebeccaRHelm/status/1207838924263084033
- https://twitter.com/RebeccaRHelm/status/1207839452619522048
- https://twitter.com/RebeccaRHelm/status/1207839986801922048
- https://twitter.com/alicemiriel/status/1208181235593490433
- https://twitter.com/TransEthics/status/1223942625708761088
---
# But the Chromosomes!!!
{!{ <div class="gutter">
{{inject '~/tweet' ids=(array
'1223942625708761088'
) tweets=meta.tweets className="" }}
{{inject '~/tweet' ids=(array
'1207834357639139328'
'1207835110617309191'
'1207835384358604802'
'1207835597206937600'
'1207835815071473664'
'1207835999130259456'
'1207837155667718145'
'1207838570276372480'
'1207839986801922048'
'1207838924263084033'
'1207839452619522048'
) tweets=meta.tweets className="oneblock" }}
{{inject '~/tweet' ids=(array
'1208181235593490433'
) tweets=meta.tweets className="" }}
</div>}!}
There are dozens of ways that chromosomes can be much more complex than XX and XY. Medically these are referred to as DSDs ([Disorders of Sex Development](https://en.wikipedia.org/wiki/Disorders_of_sex_development)). Not all result in an intersex condition, and many only manifest at the onset of puberty.
- [De la Chapelle Syndrome](https://en.wikipedia.org/wiki/XX_male_syndrome) (46,XX Male) occurs when the SRY gene from the sperm parent crosses over into a non-Y-bearing sperm during spermatogenesis. When the egg and sperm merge, it results in an XX embryo with an SRY gene, creating a phenotypical male child with two X chromosomes.
- [Swyer Syndrome](https://en.wikipedia.org/wiki/Swyer_syndrome) (46,XY Female) produces a phenotypically female child with an XY chromosome. This results from a dozen different genetic conditions, including:
- Absence or defect of an SRY gene
- Absence or defect of [DHH](https://en.wikipedia.org/wiki/Desert_hedgehog_(protein)) synthesis
- Absence of the [SF-1](https://en.wikipedia.org/wiki/Steroidogenic_factor_1) protein due to adrenal failure
- Absence of or defect the [CBX2](https://en.wikipedia.org/wiki/CBX2_(gene)) gene, preventing TDF cascade
- [XX Gonadal Dysgenesis](https://en.wikipedia.org/wiki/XX_gonadal_dysgenesis) is very similar to Swyer Syndrome, except occurs in XX children and results in nonfunctional ovaries.
- [Turner Syndrome](https://en.wikipedia.org/wiki/Turner_syndrome) (45,X) produces a phenotypically female child with numerous abnormalities. It occurs when neither an X or Y chromosome crosses over from the sperm.
- [Klinefelter Syndrome](https://en.wikipedia.org/wiki/Klinefelter_syndrome) (47,XXY) results in a phenotypically male child with more feminine traits. In extremely rare cases [it appears in female assigned children](https://www.ncbi.nlm.nih.gov/pubmed/15755052) as well, resulting in feminized testicles instead of ovaries.
- [49,XXXXY Klinefelter Syndrome](https://en.wikipedia.org/wiki/49,XXXXY) is often fatal, but when it isn't, it will always results in a sterile child.
- [Trisomy X](https://en.wikipedia.org/wiki/Triple_X_syndrome) (47,XXX), [Tetrasomy X](https://en.wikipedia.org/wiki/Tetrasomy_X) (48,XXXX), and [Pentasomy X](https://en.wikipedia.org/wiki/49,_XXXXX) (49,XXXXX) all result in a female child, but with progressively more intense health issues.
- [XXYY Syndrome](https://en.wikipedia.org/wiki/XXYY_syndrome) results in male children (due to two SRY genes) which often experience hypogonadism, needing testosterone supplements, but otherwise seeming like a typical male
- [Mosaicism](https://en.wikipedia.org/wiki/Mosaic_(genetics)) results when some cells in the body have one set of chromosomes and other cells have another due to a mutation of the genome during gestation. This may be XX/XY (resulting in a dual set of genitalia), X/XY (a milder form of Swyer or Turner syndromes) or XX/XXY (a milder form of Klinefelter syndrome).
- [Chimerism](https://en.wikipedia.org/wiki/Chimera_(genetics)) occurs when two fertilized embryos merge together into one zygote, causing half of the child to contain one set of DNA and the other half to contain another. This can result in an otherwise completely typical human being of either male or female phenotype, even capable of producing offspring, but which comes back on a kareotype test as not matching their phenotype based on where the sample was taken on their body. In extremely rare cases this can result in two full sets of reproductive organs.
- [Congenital Adrenal Hyperplasia](https://en.wikipedia.org/wiki/Congenital_adrenal_hyperplasia)(CAH) is masculinization of the female genitals in an XX child due to overactive adrenal glands.
- [Androgen Insensitivity Syndrome](https://en.wikipedia.org/wiki/Androgen_insensitivity_syndrome)(AIS) is a total or partial resistance to all androgens, preventing masculinization of all organs, save for the testicles, in an XY child. AIS subjects typically develop a female gender identity, but some partial cases may be male.
- [5-alpha-reductase deficiency](https://en.wikipedia.org/wiki/5-alpha-reductase_deficiency)(5ARD) is a failure in the body's ability to metabolize testosterone into dihydrotestosterone (DHT), preventing masculinization of the genitalia until the onset of puberty, when the child suddenly grows a penis.
- [Aromatase Deficiency](https://en.wikipedia.org/wiki/Aromatase_deficiency) causes masculinization of an otherwise female child due to excess levels of testosterone (and can bleed-over into the mother during gestation).
- [Aromatase Excess](https://en.wikipedia.org/wiki/Aromatase_excess_syndrome) causes feminisation in an otherwise male child, as all testosterone is converted into estrogen.
{!{ {{inject '~/img' images.barbosa className="card borderless center" alt="The code is more what you'd call guidelines, than actual rules."}} }!}
{!{ {{inject '_pager'}} }!}

24
pages/gdb/conclusion.md Normal file
View File

@ -0,0 +1,24 @@
---
date: "2020-01-26T20:41:55.827Z"
title: "In Conclusion"
description: "Enough with the gatekeeping already."
---
# Conclusion
Every single year we get new studies that show an increase in the size of the transgender population. As awareness continues to grow, more and more people are realizing what has been wrong with their lives and are coming out of the closet. People who transitioned decades ago are coming out of stealth. GLAAD estimates as much as 3% of the population could be transgender, and I have seen numbers as high as 5% or even 10% from more liberal estimations. The more we come to understand about gender, the more language we gain to describe gender, the more people realize that the rigid Male and Female sexual structure that we have been forced into is false.
Yet all this change frightens people. It frightens conservatives who see their patriarchal social structures dissolving under the new understanding of gender. It frightens old-school transgender people who transitioned under the Harry Benjamin rules and now see so many people easily obtaining what they had to act and lie and manipulate to achieve. They fear that if anyone can be trans, then the public will stop taking trans people seriously. It frightens the misogynistic trans-exclusionary groups that fight so hard to invalidate transgender rights, because they think if anyone can be a man or a woman, then their status as a man or a woman is harmed.
There is no such thing as a "Transtrender".
There is no such thing as "Rapid Onset Gender Dysphoria".
There is no such thing as parents "transing" their kids.
These mentalities have to stop.
{!{ {{inject '_pager'}} }!}

61
pages/gdb/diagnoses.md Normal file
View File

@ -0,0 +1,61 @@
---
date: "2020-01-26T20:41:55.827Z"
title: "Diagnosing Gender Dysphoria"
description: "It's clinical."
---
# How is Gender Dysphoria Diagnosed?
This section is going to focus on the diagnostic criteria under the American Psychiatric Association's Diagnostic and Statistical Manual of Mental Disorders, version five (DSM-5). The reason I'm focusing on this standard is because, well, nobody else has one. The UK's National Health Service basically mirrors the APA's DSM. Other countries have their own local standards, but they're all either very similar, or a lot more outdated.
The WPATH SoC describes ways that Gender Dysphoria manifests, but does not define clear diagnostic criteria, instead leaving it up to individual mental health professionals to make their own diagnoses. In general it advocates that if the patient is of sound mind and body and says that they have Gender Dysphoria, then they should be believed. The key piece here is "sound mind and body", it is left to the mental health professional to do the due diligence to ensure that there are no other conditions which may be causing the patient to believe this.
Or to put it bluntly, WPATH says that if you think you're trans, you're trans. This has been the attitude that the majority of the community has adopted as well. As long as you believe your gender does not match what you were assigned at birth, you are transgender. However, insurance companies aren't so happy with self-diagnoses, so here are the criteria which are defined in DSM-5 for diagnosing someone with Gender Dysphoria.
{!{ <div class="gutter d-md-block d-sm-none"><div class="card"><div class="card-body"><h4 class="card-title">For Your Information</h4> }!}
Diagnoses of Gender Dysphoria in pre-pubescent children requires the child must have a documented six month history of meeting 6 of these criteria, as well as demonstrated distress or impairment in function.
1. A strong desire to be of the other gender or an insistence that one is the other gender
2. A strong preference for wearing clothes typical of the opposite gender
3. A strong preference for cross-gender roles in make-believe play or fantasy play
4. A strong preference for the toys, games or activities stereotypically used or engaged in by the other gender
5. A strong preference for playmates of the other gender
6. A strong rejection of toys, games and activities typical of ones assigned gender
7. A strong dislike of ones sexual anatomy
8. A strong desire for the physical sex characteristics that match ones experienced gender
{!{ </div></div></div> }!}
**Note** These are the criteria for adolescents and adults. Children have a different set of criteria, which [you can find here](https://www.psychiatry.org/patients-families/gender-dysphoria/what-is-gender-dysphoria). I have also changed the wording slightly, here, as the official criteria are binary centric.
For an adult to be diagnosed with Gender Dysphoria by a licensed mental health professional they must meet two of these six criteria, and have experienced those criteria for longer than six months.
- **A marked incongruence between ones experienced/expressed gender and primary and/or secondary sex characteristics**
The way the person sees the world and interacts with the world does not align with the way it is typically expected for someone of the gender they were assigned at birth. There are a very broad number of traits which fit into this description. It can be in the way they interact with others, how they talk, what hobbies they prefer, how they dress, their body language and mannerisms, what genders they relate to more.
- **A strong desire to be rid of ones primary and/or secondary sex characteristics**
- **A strong desire for the primary and/or secondary sex characteristics of another gender**
These two are pretty well paired, this is physical dysphoria as I defined it above. The person finds discomfort with aspects of their body which are a result of their sex at birth, or may even be their sex at birth.
- **A strong desire to be of another gender**
- **A strong desire to be treated as another gender**
These are the social and societal dysphoria. They are how a person wants to interact with the world, and wants the world to interact with them.
- **A strong conviction that one has the typical feelings and reactions of another gender**
This is pretty self explanatory.
As I said, only two of these conditions need be met for a formal diagnoses. You may notice that only two of these comprise the physical body. It is perfectly valid for a trans person to be experiencing Gender Dysphoria without actually hating any part of their body, or wanting to change any part of their body. Physical Dysphoria is only one fraction of the many ways that lead to being trans.
Now, here is the kicker. If you identify as transgender, meaning that your gender does not align with the binary sex you were assigned at birth, you already meet two of these criteria! You have a strong enough desire to be of another gender that you are identifying that you *are* another gender, and you have a strong conviction of what your gender feels like, and it isn't what you were given at birth.
So, it is literally impossible for a person to identify as trans and not experience gender dysphoria. By the WPATH requirements anyone can identify as trans. Ergo, the statement "you do not have to have dysphoria to be transgender" is a logical paradox.
Then why do we still say it? Because most people don't know what gender dysphoria actually is, and it is easier to repeat the mantra, than to explain the nuances and subtleties of how Gender Dysphoria manifests. But hey, look, now you've got a nice article to link to that can help people understand that.
{!{ {{inject '_pager'}} }!}

70
pages/gdb/euphoria.md Normal file
View File

@ -0,0 +1,70 @@
---
date: "2020-01-26T20:41:55.827Z"
title: "How Gender Dysphoria Manifests: Euphoria"
description: "In order for there to be shadow there must be light."
tweets:
- '1215716433210105856'
- https://twitter.com/ErinInTheMorn/status/1228141518386585607
- https://twitter.com/TwippingVanilla/status/1228165207316287489
- https://twitter.com/ErinInTheMorn/status/1228165767264256003
---
# Gender Euphoria
{!{
<div class="gutter"><blockquote>
<strong>Eu·pho·ri·a</strong> - <em>Noun</em><br>
A feeling or state of intense excitement and happiness. Elation, joy, glee.
</blockquote></div>
}!}
Before I can talk about discomfort, I have to talk about relief. Gender Euphoria is itself a sign of Gender Dysphoria. You might be asking yourself, "how can happiness be sadness?" The answer to that is simple.
Imagine a person who was born in a cave, who spent their entire life living underground, their only source of illumination being candles and oil lamps. Imagine they've never been above ground, they don't even know the surface exists. Then one day a cavein happens in a side tunnel, and reveals an opening to the surface. Sunlight pours into the opening, and at first it is blinding and the person runs away in fear. Later they return to the opening, and as the person's eyes adjust they look out through the hole and see a bright and brilliant world full of colors they didn't even know existed.
That world is scary, it's huge and full of unknowns, so they crawl back into the cave for safety, but that hole is still there, and they see the light every time they pass it. Gradually they peek out more and more frequently, and further and further from the opening. They start to want that light, they find reasons to visit it more often.
Eventually they realize that they don't want to go back into the hole any more. They have to go back, because that is where their family and friends are, but this place is so much better, they want to stay here. Going back into the hole feels wrong, it starts to hurt to be in the dark so much.
This is what Gender Euphoria is like, it is brief flashes of a light that may be too bright to handle at first, too confusing to understand, but as time goes on you become more accustomed to them and you realize that this is where you belong, and the darkness becomes the dysphoria.
{!{ <div class="gutter">{{inject '~/tweet' ids=(array
'1215716433210105856'
) tweets=meta.tweets className="hide-reply" }}</div> }!}
Many trans people have no idea how much pain they are in until they find small bits of relief. Cosplay, stage acting, drag, role playing games, video games; small little forays into a different gender than they have lived as. They find that it feels just a little bit more comfortable. They'll make up excuses for why ("If I'm gonna be looking at this character's ass, it might as well be a girl's ass."), they'll try to convince themselves it's all just for fun, or an artistic expression. They might tell themselves that the bits of joy they feel at hearing a different pronoun are just novelty. But soon they find themselves looking for reasons to get that more often. More and more frequently they're role playing characters of a different sex, building more costumes, buying more clothes, performing more often. You find yourself wanting to do that all the time, because it just feels better than your real life, and being "you" starts to hurt. Eventually, the old you becomes the costume.
This is the most fundamental reason why we as a community say "you do not need dysphoria to be trans", because black ink on a black canvas isn't visible without close examination and a lot of light.
Anything that can be a source of dysphoria has an equal and opposite euphoria.
{!{ <div class="gutter">{{inject '~/tweet' ids=(array
'1228141518386585607'
'1228165207316287489'
'1228165767264256003'
) tweets=meta.tweets className="hide-reply" }}</div> }!}
Examples:
- Being gendered correctly
- Being addressed by your chosen name
- Wearing correctly gendered clothing
- Seeing and feeling changes in your body
- Seeing yourself in the mirror (removal of depersonalization)
- Socializing in a way that conforms with gendered expectations
- Getting a haircut in a masculine / feminine / androgynous manner
- Shaving your legs
- NOT shaving your legs
- Being included in something you wouldn't otherwise because of your assigned gender (eg, bridal party or bachelor shower)
- Feeling sexy / having sex in a way that aligns with your gender and sexuality.
Even just being out in the world as yourself and being seen as yourself can be massively euphoric.
**What euphoria is NOT** is a sexual high, turn on, or fetish. Sometimes euphoria can trigger a sexual response, and there are many factors at play that cause that (feeling good about your body is a turn on, for example), but it is not a source of sexual excitement. Trans people are not "getting off" on presenting or acting like their true selves.
That said, many people who have not yet realized they are trans may resort to fetishes and kinks to express their gender and/or relieve their dysphoria. They may maintain some of these kinks through transition. There is no shame in this, how they find sexual fulfillment is their own business. However, these things are *alongside* their gender. A trans person's sense of gender persists indefinitely, it does not go away when they go back to their daily lives.
{!{ {{inject '_pager'}} }!}

View File

@ -0,0 +1,19 @@
---
date: "2020-01-26T20:41:55.827Z"
title: "How Gender Dysphoria Manifests: Historical Dysphoria"
description: "I don't regret the things I have done, I regret the things I didn't do when I had the chance."
---
# Historical Dysphoria
When you grow up as the wrong assigned gender, you are going to miss out on a lot of things that should have been available to you if only people had known. Sleepovers, camping trips, girl/boy scouts, shopping trips, cheerleading or sports. Events that are co-ed may have very different feelings attached to them based on how you engage with them, like going to prom, religious ceremonies (such as having a bat mitzvah instead of a bar mitzvah), and even just the act of courtship. These dysphoria may also be biological in origin, such as a sorrow over having not given birth to or breastfed your children.
These missed opportunities can manifest as feelings of loss and hurt. Furthermore, the memories of things you *did* have access to but wouldn't have otherwise, or events that were performed in the wrong gender, can also be a sour point, as these may have awkward attachments. Imagine having to be a groom at your wedding when you know you should have been a bride; growing up dreaming about your perfect wedding, and then playing the wrong role in it.
Sometimes historical dysphoria can manifest existentially, hitting you with all the grief of the youth lost. All the dating, the teenage antics, the parties, even just having been able to be sexual with the correct parts while your body was young and you had no responsibilities. It is time that can never be gained back.
Many trans people attempt to recapture some of these lost events, hosting or attending queer proms, organizing sleepovers, performing vow renewals with their spouses, and engaging in common puberty rites of passage like having a mother figure help them shop for their first bra, or having a father figure teach them to shave. However, ultimately, historical dysphoria is something that can never be relieved. You can make new experiences to replace the ones you lost, but you can never turn back the clock.
This is one of many reasons why affirming trans youth is so important. Boys want to do common boy things and girls want to do common girl things, and when they miss out they will not forget.
{!{ {{inject '_pager'}} }!}

View File

@ -1,35 +1,41 @@
--- ---
date: "2020-01-26T20:41:55.827Z" date: "2020-01-26T20:41:55.827Z"
title: "The Gender Dysphoria Bible" title: "A Brief History of Gender Dysphoria"
subtitle: "A Brief History of Gender Dysphoria"
description: "The origins of Gender Dysphoria and the current meaning today." description: "The origins of Gender Dysphoria and the current meaning today."
--- ---
# A Brief History of Gender Dysphoria
In 1948 noted sexologist Dr. Alfred Kinsey (yes, [*that* Kinsey](https://en.wikipedia.org/wiki/Alfred_Kinsey)) was contacted by a woman whose male child adamantly insisted that they were in fact a girl, and that something had gone very wrong. The mother, rather than trying to suppress her daughter, wished to help her become who she knew herself to be. Kinsey reached out to a German endocrinologist named [Dr. Harry Benjamin](https://en.wikipedia.org/wiki/Harry_Benjamin) to see if he could help the child. Dr. Benjamin then developed a protocol of estrogen therapy for the teen, and worked with the family to find surgical help. In 1948 noted sexologist Dr. Alfred Kinsey (yes, [*that* Kinsey](https://en.wikipedia.org/wiki/Alfred_Kinsey)) was contacted by a woman whose male child adamantly insisted that they were in fact a girl, and that something had gone very wrong. The mother, rather than trying to suppress her daughter, wished to help her become who she knew herself to be. Kinsey reached out to a German endocrinologist named [Dr. Harry Benjamin](https://en.wikipedia.org/wiki/Harry_Benjamin) to see if he could help the child. Dr. Benjamin then developed a protocol of estrogen therapy for the teen, and worked with the family to find surgical help.
Benjamin then went on to refine his protocol and treated thousands of patients with similar feelings over the course of his career. He refused to take payment for his work, instead taking satisfaction from the relief he granted these patients, and using their treatment to further his understanding of the condition. He coined a term for this feeling of incongruence in 1973: Gender Dysphoria. Unfortunately, this term would not be used in the United States until 2013, the American Psychiatric Association opting for the term Gender Identity Disorder instead. Benjamin then went on to refine his protocol and treated thousands of patients with similar feelings over the course of his career. He refused to take payment for his work, instead taking satisfaction from the relief he granted these patients, and using their treatment to further his understanding of the condition. He coined a term for this feeling of incongruence in 1973: Gender Dysphoria. Unfortunately, this term would not be used in the United States until 2013, the American Psychiatric Association opting for the term Gender Identity Disorder instead.
{!{ {{inject '~/img' images.hbscale className="card sideline" caption="Harry Benjamin Diagnostic Scale"}} }!} {!{ <div class="gutter">{{inject '~/img' images.hbscale className="card sideline" caption="Harry Benjamin Diagnostic Scale"}}</div> }!}
If you are a trans person reading this, you may have heard the name Harry Benjamin before, but probably not in a favorable context. In 1979 his name was used (with permission) in the forming of the Harry Benjamin International Gender Dysphoria Association (HBIGDA), which released a Standards of Care (SoC) for transgender people. This SoC came to be known as the Harry Benjamin Rules, and were infamously limiting in regards to how Gender Dysphoria could be diagnosed. Patients were placed within a six tier scale based upon their level of misery and sexual dysfunction. If you did not land at Tier 5 or higher, classified as a "True Transexual", you were usually rejected for treatment. If you are a trans person reading this, you may have heard the name Harry Benjamin before, but probably not in a favorable context. In 1979 his name was used (with permission) in the forming of the Harry Benjamin International Gender Dysphoria Association (HBIGDA), which released a Standards of Care (SoC) for transgender people. This SoC came to be known as the Harry Benjamin Rules, and were infamously limiting in regards to how Gender Dysphoria could be diagnosed. Patients were placed within a six tier scale based upon their level of misery and sexual dysfunction. If you did not land at Tier 5 or higher, classified as a "True Transexual", you were usually rejected for treatment.
The problem was, Tier 5 and 6 required that you had to be exclusively attracted to your own birth sex. Transition *had* to be making you straight, not gay, and bisexuals were not allowed. You also had to be experiencing severe distress with your body and genitals, and already be living as your true gender without treatment. Many trans people got around these limitations through community coaching and performative presentations, but for many people (myself included) it was believed that if you did not fit all the criteria, then you were not trans enough to transition. The problem was, Tier 5 and 6 required that you had to be exclusively attracted to your own birth sex. Transition *had* to be making you straight, not gay, and bisexuals were not allowed. You also had to be experiencing severe distress with your body and genitals, and already be living as your true gender without treatment. Many trans people got around these limitations through community coaching and performative presentations, but for many people (myself included) it was believed that if you did not fit all the criteria, then you were not trans enough to transition.
In 2011 the HBIGDA reorganized itself to respond to mounting pressures in trans understanding and acceptance, taking on the new name World Professional Association for Transgender Health (WPATH). Under guidance by actual transgender people (a first for the organization), WPATH then proceeded to release an entirely new Standards of Care (version 7, the first in ten years) which abandoned the Benjamin Scale, focusing on specific individual symptoms and disconnecting gender from sexuality entirely. Two years later, in 2013, the American Psychiatric Association changed their diagnostic criteria to match the WPATH SoC in their Diagnostic and Statistical Manual of Mental Disorders (DSM) version 5, replacing Gender Identity Disorder with Gender Dysphoria. With this change, medical transition became available to all trans people in the United States. In 2011 the HBIGDA reorganized itself to respond to mounting pressures in trans understanding and acceptance, taking on the new name World Professional Association for Transgender Health (WPATH). Under guidance by actual transgender people (a first for the organization), WPATH then proceeded to release an entirely new Standards of Care (SoC, version 7, the first in ten years) which abandoned the Benjamin Scale, focusing on specific individual symptoms and disconnecting gender from sexuality entirely. Two years later, in 2013, the American Psychiatric Association changed their diagnostic criteria to match the WPATH SoC in their Diagnostic and Statistical Manual of Mental Disorders (DSM) version 5, replacing Gender Identity Disorder with Gender Dysphoria. With this change, medical transition became available to all trans people in the United States.
This is why trans presence across the world has suddenly exploded in the last decade. With easier access comes larger numbers, with larger numbers comes more visibility, with more visibility comes more awareness, and with more awareness comes more people accessing treatment. [A study conducted in 2014](https://williamsinstitute.law.ucla.edu/wp-content/uploads/TransAgeReport.pdf) showed 0.6% of adults and 0.7% of youth in the United States identified as transgender, [a study conducted in 2016](https://www.cdc.gov/mmwr/volumes/68/wr/mm6803a3.htm) showed 1.8% of high school age students identified as transgender, and [a survey conducted by GLAAD in 2017](https://www.glaad.org/files/aa/2017_GLAAD_Accelerating_Acceptance.pdf) showed a whopping 12% of respondents 18 to 34 did not identify as cisgender. This is why trans presence across the world has suddenly exploded in the last decade. With easier access comes larger numbers, with larger numbers comes more visibility, with more visibility comes more awareness, and with more awareness comes more people accessing treatment. [A study conducted in 2014](https://williamsinstitute.law.ucla.edu/wp-content/uploads/TransAgeReport.pdf) showed 0.6% of adults and 0.7% of youth in the United States identified as transgender, [a study conducted in 2016](https://www.cdc.gov/mmwr/volumes/68/wr/mm6803a3.htm) showed 1.8% of high school age students identified as transgender, and [a survey conducted by GLAAD in 2017](https://www.glaad.org/files/aa/2017_GLAAD_Accelerating_Acceptance.pdf) showed a whopping 12% of respondents 18 to 34 did not identify as cisgender.
Transgender people are coming out of the woodwork, we are everywhere. Transgender people are coming out of the woodwork, we are everywhere.
#### So What Is Gender Dysphoria? ## So What Is Gender Dysphoria?
> **Dys·pho·ri·a** - *Noun* {!{
> A state of unease or generalized dissatisfaction with life. The opposite of euphoria. <div class="gutter">
<blockquote>
<strong>Dys·pho·ri·a</strong> - <em>Noun</em><br>
A state of unease or generalized dissatisfaction with life. The opposite of euphoria.
</blockquote>
{{inject '~/img' images.glue className="card sideline"}}
</div>
}!}
{!{ {{inject '~/img' images.glue className="card sideline" caption="What Dysphoria Feels Like"}} }!} There is a common misconception among both cisgender and transgender people that Gender Dysphoria refers exclusively to a physical discomfort with ones own body. Consequently, proponents of WPATH SoC 7 and DSM-5 have taken to a habit of saying that you do not have to have dysphoria to be transgender. This statement is often repeated like a mantra, as it informs people who do not feel significant body discomfort that they may also be transgender.
There is a common misconception among both cisgender and transgender people that Gender Dysphoria refers exclusively to a physical discomfort with ones own body. Consequently, proponents of SoC 7 and DSM-5 have taken to a habit of saying that you do not have to have dysphoria to be transgender. This statement is often repeated like a mantra, as it informs people who do not feel significant body discomfort that they may also be transgender.
However, this belief that body discomfort is central to Gender Dysphoria is in fact a misconception, and is not even a majority component of a Gender Dysphoria diagnosis. Gender Dysphoria crosses a large number of all aspects of life, including how you interact with others, how others interact with you, how you dress, how you behave, how you fit into society, how you perceive the world around you, and yes, how you relate to your own body. However, this belief that body discomfort is central to Gender Dysphoria is in fact a misconception, and is not even a majority component of a Gender Dysphoria diagnosis. Gender Dysphoria crosses a large number of all aspects of life, including how you interact with others, how others interact with you, how you dress, how you behave, how you fit into society, how you perceive the world around you, and yes, how you relate to your own body.
@ -61,4 +67,4 @@ There is no one single trans experience, there is no standard set of feelings an
Ok, that disclaimer out of the way, lets get to the meat and potatoes. Ok, that disclaimer out of the way, lets get to the meat and potatoes.
{{inject '_pager' step=2}} {!{ {{inject '_pager'}} }!}

View File

@ -0,0 +1,106 @@
---
date: "2020-01-26T20:41:55.827Z"
title: "Impostor Syndrome, but make it Trans"
description: "I don't regret the things I have done, I regret the things I didn't do when I had the chance."
tweets:
- '1219963582063968258'
- '1221970265862811650'
- '1153300365355307008'
- '1153300366902960128'
- '1153300368974991361'
- '1153300370631741440'
- '1153300372468801536'
- '1153300374133981186'
---
# Impostor Syndrome
{!{ <div class="gutter">{{inject '~/tweet' ids=(array
'1219963582063968258'
) tweets=meta.tweets className="hide-reply" }}</div> }!}
> [Impostor syndrome](https://en.wikipedia.org/wiki/Impostor_syndrome) (also known as impostor phenomenon, impostorism, fraud syndrome or the impostor experience) is a psychological pattern in which an individual doubts their accomplishments and has a persistent internalized fear of being exposed as a "fraud".
Society in general is very good about making trans people doubt themselves. We receive tons and tons of subliminal messages through out our lives saying that being trans isn't normal and that anyone who is has to be exceptionally special. Cis media's obsession with the "born in the wrong body" narrative has led to a lot of false information being internalized by trans youth. Many, *many* trans kids grow up thinking they aren't actually trans because they don't *know* that they are a different gender, they just wish they were.
On top of this, messages saying that trans people hate their bodies or hate their genitalia have polluted the awareness landscape, so that many people who either do not experience physical dysphoria (or simply think theirs isn't very strong) go around believing they aren't "trans enough".
***[YES, YOU ARE TRANS ENOUGH](https://www.amazon.com/Yes-You-Are-Trans-Enough/dp/1785923153/)***
{!{ <div class="gutter">{{inject '~/tweet' ids=(array
'1221970265862811650'
) tweets=meta.tweets className="" }}</div> }!}
On top of this, the constant messaging from transphobic media that trans people are not actually their true genders and are simply trying to trick people into believing otherwise gets internalized like a virus. This creates a lot of self doubt about the authenticity of one's gender, especially in the face of so many gender stereotypes. Seeing ones self fail to meet those stereotypes can make it very easy to convince yourself that you do not live up to your own gender (note, cis men and women get this too, far too often).
Furthermore, due to a history of transphobic abuse, many trans people suffer from damaged self-esteems, and often already have difficulty with self doubts. Gender Dysphoria also causes depression, which further contributes to and reinforces those doubts. This all leads into a massive cluster of self invalidation that can lead someone to struggle over and over again to accept their own gender identity.
But here's the thing... only trans people are worried about if they are actually transgender! A cisgender person does not have this obsession with their identity, they think about it, they process it, they move on. If you keep returning to these thoughts over and over again, this is your brain telling you that you took a wrong turn.
The world is *full* of influences put in place to fill us with doubt and keep us from breaking outside of the established social order. These
### Autogynephilia
{!{ <div class="gutter">{{inject '~/tweet' ids=(array
'1153300365355307008'
'1153300366902960128'
'1153300368974991361'
'1153300370631741440'
'1153300372468801536'
'1153300374133981186'
) tweets=meta.tweets className="oneblock" }}</div> }!}
This pattern was strongly reinforced during the late 1980s when the Autogynephelia (AGP) theory of Ray Blanchard gained a lot of traction as trans awareness was just starting to escalate. AGP is a pseudo-scientific explanation intended to "explain" the source of trans women's identities using [paraphilias](https://en.wikipedia.org/wiki/Paraphilia). Blanchard separated trans women according to if they were attracted to men or to women, while simultaneously invalidating their womanhood. His work completely ignored transgender men, and he dismisses non-binary identities outright.
AGP attests that straight trans women are actually just gay men who seek a feminine appearance to draw desire from straight men, and that trans lesbians are actually straight men who have become so obsessed with their desire for women that they wish to become a woman in order to gain sexual gratification from themselves.
Blanchard's theory largely hinged on the way that presenting feminine often resulted in sexual arousal within newly transitioning women. You see, most of his study subjects were patients who were trying to seek hormone therapy for the first time, and as such were still very new to presenting female.
Yes, it boggles the mind, but this was actually considered a valid theory of psychology for years, it appeared in college textbooks. Blanchard's research studies did not meet scientific rigor, and his data was found to be extremely flawed (he manipulated his patients, and simply just threw out any data that didn't fit his hypothesis). A lot of his theories are based in misogynistic views of womanhood, and the man never actually involved any cisgender women in his study to function as a control group. You can read more about how flawed the theory is in Julia Serano's excellent essay, [The Case Against Autogynephilia](https://www.juliaserano.com/av/Serano-CaseAgainstAutogynephilia.pdf).
AGP had been thoroughly dismissed by modern psychology by the late 2000s, but the damage has been done. In the public's eye, trans women were all perverted fetishists. Media portrayals of trans women mirrored this attitude, further spreading negative imagery into the public consciousness.
Trans women then internalize these messages, and come to the conclusion that they are not actually transgender, just fetishists. It happened to me, it's happened to nearly every millennial trans woman I know who figured themselves out as a teen.
You are not a fetishist, the feeling you get from thinking of yourself as a woman is gender euphoria.
### Patriarchal Oppression
A common source for invalidation for AFABs is the conflation of gender with the systemic oppression of women, particularly among non-medically transitioning non-binary people. The message of "oh you just don't want to be a woman because of how women are treated" is far too often heard, and it can deeply infest your subconscious to the point of self doubt. Yes, being seen as a woman can really suck, but that has absolutely nothing to do with one's gender.
Radical Feminism's messaging of abandoning female gender roles can also conflate ones own feelings. "Am I actually non-binary, or am I just a feminist?" "Am I actually a man, or am I just a very butch lesbian?" These kinds of doubts sneak in and fester like weeds.
Then you have the problem of people believing that to be non-binary is to be androgynous, and to be androgynous is to be less feminine. Feminine enbies are valid! It is OK if you do not want to remove your breasts. It is OK if you enjoy your curves. It is OK if you do not mind being called "she" and "her". That does not make you any less transgender.
If you feel like you are not a binary woman, than you are not a binary woman. Cis women do not experience that detachment.
### Toxic Masculinity
Male assigned kids grow up positively drenched in messaging of what it is to "be a man". There are so few examples of positive masculinity in popular media, and AMAB Masculine Enbies are also commonly erased in trans representation that being a gender queer male can feel very lonely. AMAB Enbies are often either grouped in with gay cis men or treated like trans women.
You can just be gender-queer! Your identity is valid!
### Transmedicalism
This one hits *everybody*. Transmedicalism (aka Truetrans) is a transgender ideology derived from the Harry Benjamin scale (ranks 5 and 6). It seeks to reinforce the pre-WPATH rules, requiring intense physical dysphoria, demanding medical transition, and often invalidating all non-binary identities. At its core, transmedicalism is a supremacist concept, elevating binary trans people above the needs of any other gender identity, and a push back against the expansion of the transgender identity. They wish for more gatekeeping than we have today, rail against enbies using the transgender label, and would prefer to see fewer people receive treatment for their gender dysphoria.
To put it succinctly, many transmedicalists hate that the newer generation "has it so easy," despite the fact that many of their ranks are part of that generation. This ideology started among disgruntled trans elders, but has since spread to other binary individuals, particularly among young trans men.
If a trans person's first exposure to transness is a transmedicalist, this can severely set back their own self-acceptance and push them even further into the closet. Transmed's are well known to actually tell people "No, you are not trans."
**Do not believe these lies.** They are bully tactics explicitly designed to gaslight and dismiss people's pain for self gratification.
### Trans Exclusionary Reactionary Feminism / Gender Critical Movement / Gender Essentialism
[Gender Essentialism](https://en.wikipedia.org/wiki/Gender_essentialism) is the belief that there are an innate attributes to a person's existence that are derived based on what sex organs the person is born with. TERF and GC ideology was born out of the lesbian separatist movement of second wave feminism and fully denies the existence of transgender biology or non-binary identities. The movement has been largely overtaken by right-wing reactionaries, racists and homophobes, and is now being bolstered by evangelical christian organizations.
These people will stop at nothing to invalidate your existence. Do not give them the time of day.
### Gender Abolitionism / Postgenderism
[Postgenderism](https://en.wikipedia.org/wiki/Postgenderism) is a [transhumanist](https://en.wikipedia.org/wiki/Transhumanism) philosophy originating in radical feminism which states that gender causes more harm than good, and seeks to eradicate it from our society. GAs believe that all gender is a construct and that anyone who feels strongly connected to a binary gender is either nefariously propagating gender stereotypes or ignorantly following systemic indoctrination.
GAs do not believe in the existence of gender dysphoria, and will attempt to invalidate those who experience it. They're functionally the extreme leftist version of the Gender Critical movement.
{!{ {{inject '_pager'}} }!}

31
pages/gdb/index.md Normal file
View File

@ -0,0 +1,31 @@
---
date: "2020-01-26T20:41:55.827Z"
title: "The Gender Dysphoria Bible"
description: "A dive into the multitude of ways that gender dysphoria manifests and what it means to be transgender."
---
# The Gender Dysphoria Bible
{!{
<div class="gutter"><blockquote>
<strong>Trans·gen·der</strong> - <em>adjective</em><br>
Denoting or relating to a person whose sense of personal identity and gender does not correspond with their sex assigned at birth.
</blockquote></div>
}!}
For as long as human civilization has existed, [there have been people](https://en.wikipedia.org/wiki/Transgender_history) whose experience of their internal gender does not align with the physical features of their body. The Gala, a middle gender priest class of the Sumerian empire, exited over four thousand five hundred years ago. The indigenous cultures of North America recognized [a third gender](https://en.wikipedia.org/wiki/Third_gender) far before European colonialism, and still do to this day. Roman emperor Elagabalus (218 AD) insisted on being referred to as Lady rather than Lord, and even put forward a ransom for anyone who could conduct genital reconstruction surgery.
In spite of this, however, the modern understanding of the transgender experience is only approximately 130 years. Even the word "transgender" only dates back to 1965 when John Oliven proposed it as a more accurate alternative to David Cauldwell's term "transsexual" (coined in 1949), which itself replaced Magnus Hirschfield's term "transvestite" (1910).
To be transgender is to have a gender identity which does not match the gender you were presumed to have based on the genitalia you were born with. This can mean a person born with a penis is actually a girl, that a person born with a vulva is actually a boy, or that a person with either genital configuration may not wholly fit either side of that spectrum and is non-binary.
A trans person can come to recognize this at *any point* in their life. Some children identify it at as soon as they are able to grasp the concept of the differences between the sexes, others don't start to feel anything until the onset of puberty, and still others do not realize that anything is wrong at all until they are fully adults. Many people are simply never exposed to the idea that their gender could mismatch their birth sex, or what that feels like, and thus simply accepted their fate.
Even more common is a perception that even tho they have feelings about being unhappy with the gender they were assigned at birth, they believe that this is not the same as what transgender people experience. Some may feel that a wish to be transgender and have transition available is some kind of disrespect towards "real" trans people who knew they were actually boys or girls "born in the wrong body." These narratives of the transgender experience that have been spread by popular media create a very false impression of just what it means to be transgender and what growing up transgender feels like.
This experience of discontinuity between the internal and external self is what we describe as Gender Dysphoria. Every trans person, regardless of their position within or outside of the gender binary, experiences some form of Gender Dysphoria. This is something of a political topic within trans communities, as different groups have their own ideas of what Gender Dysphoria is, how it manifests, and what qualifies a person as being trans. By and large, however, this debate is feckless and fruitless, as the definition at the top of this page encompasses the beginning and the ending of how these terms intermingle.
The purpose of this site is to document the many ways that Gender Dysphoria manifests, as well as other aspects of gender transition, in order to provide a guide for those who are questioning, those who are starting, those already on their path, and those who simply wish to be better allies.
{!{ {{inject '_pager'}} }!}

View File

@ -0,0 +1,79 @@
---
date: "2020-01-26T20:41:55.827Z"
title: "Managed Dysphoria: Gender in Disguise"
description: "I don't regret the things I have done, I regret the things I didn't do when I had the chance."
tweets:
- '1215746083487461379'
- '1215749725456125952'
---
# Managed Dysphoria
Growing up in the closet, even when you don't know you're in the closet, becomes an existence built on top of coping mechanisms intended to alleviate dysphoria. The following are ways in which a closeted trans person may find to alleviate the dysphoria they experience in their day to day lives.
- When a video game gives you the option of choosing your gender, you tend to choose differently than your assigned gender. This may be accompanied with excuses to defend that choice. "It defaulted to male and I didn't care." "I don't want to stare a guy's butt for hours."
- A preference for literature and film with characters of your true gender, or with characters who break gender norms (Mulan, Little Women)
- Pornographic outlets which satisfy strong desires or feel more relatable, such as a draw towards gay/lesbian porn, bridal kink, or transformation sequences.
- Crossdressing or performing drag
- Finding excuses to cut hair short, or to grow it out.
- Shaving of body hair, or a refusal to shave hair you're expected to.
- Wearing loose and baggy clothing that hides the shape of your body.
- Avoiding social gatherings whenever possible, seeking isolation.
- Becoming intimately educated about some gender associated topic, such as men's or women's clothing design
- Obsessively working out (AFABs)
- Helping cis partners to shop in order to live vicariously through their presentation.
{!{ <div class="gutter">{{inject '~/tweet' ids=(array
'1215746083487461379'
'1215749725456125952'
) tweets=meta.tweets className="collapse" }}</div> }!}
Because so much abuse is handed down on to gender non-conforming children, many trans people grow up learning to hide their natural personalities out of sheer necessity. Many trans people speak about having a phase of life where they attempted to "buy-in" on their assigned gender, performing masculinity or femininity to extremes in order to try to "fix" themselves. This leads to repression tendencies which may even superficially appear toxic, but are simply the results of trying to hide every scrap of their true selves.
- Growing and meticulously grooming facial hair (the so called "denial beard")
- Taking up makeup artistry in order to perfect a high femme look.
- Presenting extremely masculine or hyper feminine.
- Avoiding any conversation about fashion for any gender. Dissociating whenever fashion conversations or activities occur.
- Obsessively working out (AMABs)
- Assuming a strongly stereotyped gender role in a relationship (eg, the dutifully modest housewife)
- Marrying and having kids in anticipation that it will "fix" what's wrong with you.
- Buying in to ultra-conservative attitudes towards gender and sexuality
- Homophobia and Transphobia expressed in self defense to ward off suspicion.
- Aggressively passive engagement in anything connected to ones true gender.
Finally, another very common coping mechanism is to find means of escapement or mental engagement in order to forget your own feelings.
- Intensely investing large amounts of time into hobbies
- Long hours spent at work
- Chain binging movies, tv shows or books.
- Spending all idle time in video games or on social media
- Obsessively cleaning ones living space
- Sleeping. Lots and lots of sleeping.
{!{ {{inject '_pager'}} }!}

View File

@ -0,0 +1,148 @@
---
date: "2020-01-26T20:41:55.827Z"
title: "How Gender Dysphoria Manifests: Physical Dysphoria"
description: "Body discomfort is only one of the many ways Gender Dysphoria manifests."
tweets:
- '1220143004821938176'
- '1184580976581775366'
- '1184837108919230464'
- '947522372315369472'
- '947523244948680705'
---
# Physical Gender Dysphoria
Everyone has heard of the "born in the wrong body" narrative. Physical Dysphoria is discomfort over the shape of one's body due to the sexual characteristics it presents. So what body features are we talking about here?
{!{
<style>
.fact-grid h4 { font-weight: 600;grid-row: 1; }
.fact-grid li {break-inside: avoid;}
@media (min-width: 500px) {
.fact-grid {
display: grid;
grid-template-columns: 1fr 2fr;
grid-template-rows: min-content 1fr;
grid-column-gap: 1em;
font-size: 0.7em;
}
.fact-grid .two-col { column-count: 2; }
}
</style>
<div class="fact-grid ">
<h4>Primary Sex Characteristics</h4>
<div>
}!}
The core reproductive features which develop during pregnancy
- Gonads
- Testicles
- Ovaries
- External Genitalia
- Penis
- Clitoris
- Scrotum
- Labia
- Vulva
- Internal Reproductive Organs
- Prostate / Skene's Gland
- Uterus
{!{ </div> <h4>Secondary Sexual Characteristics</h4>
<div class="two-col"> }!}
All sexually dimorphic features which develop during and after puberty as a result of hormone exposure. In general, these features are all nearly identical for both male and female pre-pubescent children.
- Fat Distribution
- Waist, Hips, Butt Shape
- Thighs, Arms, Back
- Cheeks and Jaw Line
- Muscle Mass
- Neck, Shoulders and Upper Body
- Arms and Legs
- Abdominal
- Skeletal Build
- Range of Height
- Size of Feet and Hands
- Width of Shoulders
- Rib Cage Breadth
- Thickness and Density of Limbs
- Forehead, Brow, Cheek and Jaw bones
- Pelvic Width
- Skin Texture and Tone
- Voice Pitch and Resonance
- Breast Development
- Facial Hair
- Body Hair (excluding genitals and arm pits)
{!{ </div></div> }!}
{!{ <div class="gutter"><div class="card"><div class="card-body"><h4 class="card-title">For Your Information</h4> }!}
The genitals of a transgender person on hormone therapy do not behave remotely like their cisgender counterparts.
- The Estrogenic Penis softens, erections become less pronounced, the skin thins and begins to perspire like a vaginal wall. The scrotum softens and changes color, with the perineal raphe becoming more distinct. Due to the cessation of random erections, the erectile tissue will atrophy if not regularly put to use, causing the entire penis to shrink over time. Vibration becomes more effective for arousal.
- The Androgenic Vagina becomes dryer & prone to tearing (lubrication can be an issue). The skin of the clitoris thickens, and the clitoral glans grows in length and girth due to the onset of random erections. Labia also become thicker, and often hairier. The onset of HRT often results in extreme sensitivity of the clitoris.
{!{ </div></div></div> }!}
Primary characteristics can only be altered through surgical intervention. Some secondary sexual characteristics are also one-way trips and require medical intervention to undo, namely the growth of breast tissue and the deepening of the vocal chords. Estrogen does not make the voice more feminine, Testosterone does not make breasts shrink (aside from the loss of fat). Changes to skeletal structure (such as enlarging from testosterone and the widening of hips from estrogen) can only occur prior to the age of 25, while the body is still growing.
Some secondary traits can be surgically enhanced (Breast Augmentation, body contouring, facial masculinization / feminization), and some cannot be changed at all.
---
Physical dysphoria manifests in several different ways. Sometimes this is felt in a sort of phantom limb phenomenon, where the person can feel sensations from a penis or vagina that is not there, an ache in a uterus that does not exist, or a sense of absence on the chest from breasts that have not grown in.
It can be felt as a sort of *reverse* phantom effect, where the person is persistently aware of something that should *not* be there. The brain is receiving sensory input that it does not expect, such as the weight of breasts, or the presence of testicles or a uterus, and this input takes priority because it isn't expected.
It may be felt as horror or revulsion when looking at or touching the external genitals, triggering emotional outbursts or a strong desire to remove the offending organ. AFAB (assigned female at birth) trans people may experience feelings of wrongness during menstruation, or a sense of alien disconnect from their hormone cycle.
{!{ <div class="gutter">{{inject '~/tweet' ids=(array
'1220143004821938176'
) tweets=meta.tweets className="hide-reply" }}</div> }!}
It can manifest as a compulsion to be rid of certain body traits, such as obsessively shaving body or facial hair. This can also manifest in the opposite compulsion, leading to meticulous grooming of those traits in order to try to control them, like maintaining a perfect beard, persistently keeping ones nails manicured and polished, or spending hours in the gym attempting to hone ones shape.
Undesired physical features may prompt a person to experience envy of people who have been forced to remove those features due to illnesses, such as testicular or breast cancer. AMABs with severe genital dysphoria tend to have a wish for some kind of freak accident that would cause the loss of their phallus.
Sometimes it may just simply be a feeling of being incorrect, which you may not even attribute to gender or sex. For most of my life I believed that the reason I hate my body was because I was fat. It wasn't until I started transition that I realized I don't hate my fat at all, I hated having *male* fat. The feminine curves that HRT gave me make me feel so much more in tune with my body.
{!{ <div class="gutter">{{inject '~/tweet' ids=(array
'1184580976581775366'
'1184837108919230464'
) tweets=meta.tweets className="hide-reply" }}</div> }!}
The dysphoria one feels about their body can and will change over time, for better and worse. Many trans women today enter into transition feeling no disconnect with their genitals, for example, but later find that changes as the other more in your face sources melt away, stimulation differs, and their genitalia itself changes shape and function. Some may assume that they will absolutely need facial feminisation surgery, but then 2 years in realize they're actually ok with how they look. I used to be terribly sensitive about my widows peak, but now that my hair has grown in I find I'm completely ok with my hair line.
It's ok for you to realize you need more or less than when you started.
It's ok if you don't hate anything about your body, and just wish you looked more feminine or masculine.
It's ok if you don't need medical transition *at all*. Body feelings are not the be-all-end-all of transition.
**Total body physical dysphoria is not a requirement to be transgender. AFABs do not have to hate their chest, AMABs do not have to hate their penis. Every trans person's experience is different. All are valid.**
### Internalized Body Image Issues
The world is full of subconscious messages about how men and women's bodies should be shaped. We are bombarded with advertising and media creating a normalized view of what is and is not beautiful. Don't be too fat, don't be too skiny, don't be too tall, don't be too short, don't have too broad of a chin, don't have too large of a nose, wear makeup but don't wear too much makeup, don't leave the house without a bra, but don't let the bra show. On and on and on, the constant barrage of expectations of gendered appearance.
Everyone absorbs these messages, and trans people internalize the factors which matter to the gender they align with. Trans girls grow up mapping feminine standards onto themselves, trans boys map masculine standards on to themselves, and enbies often internalize shame around androgyny. This is *on top* of the shame they are loaded with for not living up to their assigned gender's standards.
What is the end result of this? Kathryn said it best:
{!{ {{inject '~/tweet' ids=(array
'947522372315369472'
'947523244948680705'
) tweets=meta.tweets className="grid-row" }} }!}
{!{ {{inject '_pager'}} }!}

View File

@ -0,0 +1,61 @@
---
date: "2020-01-26T20:41:55.827Z"
title: "How Gender Dysphoria Manifests: Presentational Dysphoria"
description: "Hoodies and sweatpants never go out of style."
tweets:
- '1215716435068100611'
- '1215716435974066176'
- '1215716436980703233'
- '1215716438020849664'
- '1191555135756853249'
---
# Presentational Dysphoria
Clothes. Hair. Makeup. Jewelry. Glasses. Piercings and other body modifications. Even personal hygiene can be a factor of presentation, such as the shaving of body hair, or how you take care of your skin. All of these things are gendered in society, clothing and hair especially.
While the sexual revolution of the 1960s and the business fashion craze of the 80s did wonders for blurring the gap between masculine and feminine presentation (largely by normalizing masc fashion as androgynous), there are still enormous pressures to conform to traditional gender norms. Gender Non-Conforming dress is so instantly marked as queer that any time a woman wears a tailored suit she is marked as a lesbian, and a dad who [puts on an Elsa costume because his son wants to have a Frozen party](https://twitter.com/cbsnews/status/1088441623846023168?lang=en) is labeled as subversive and abusing his child.
Long hair on men has been seen as [an act of rocker rebellion](https://www.youtube.com/watch?v=PbAoXw_DqvM) for decades, and men with long hair get discriminated against as being layabouts and bums. Short hair on women is often read as queer or butch (unless they're old, then it's expected), and women are often pressured to keep their hair long. Pierced ears on men became somewhat more normalized in the 90s, but are still seen as an act of rebellion, and some employers wont allow men to wear earrings. Makeup on men is so stigmatized by toxic masculinity that even men who *like* makeup feel pressured to avoid it.
Like it or not, presentation is gendered, and it is extremely common for trans people to want to present themselves in the fashion of their true gender, and a desire to be free of the shackles of gendered presentation is common among all trans people, regardless of where they sit on the gender spectrum. For AMAB individuals they may manifest as a wish to incorporate more feminine elements, for AFABs it may manifest as a want for more masculine appearance. This may come as a full push towards the opposite of their assigned gender, or a desire to seek a middle-ground in pursuit of androgyny. It may even simply be a wish to *not* present as your assigned gender.
**Not all transfemmes are feminine, not all transmascs are masculine, not all enbies seek androgyny. Butch AMAB trans people are valid, femme AFAB trans people are valid. Presentation is not gender, gender is not presentation.**
Presentational dysphoria typically appears early on in the form of a fascination with the styling of another gender, and a wish to be able to present as people of that gender do. That desire may be fulfilled somewhat by seeking out styling that is unisex, but typically that wish is self-gatekept by statements of "I'm not confident enough to attempt that." AMABs often run into issue here where this desire often gets trapped behind heteronormative expectations, causing an interest in feminine presentation to be misinterpreted as sexual desire.
Post-transition presentational dysphoria is usually simply a case of high discomfort when attempt to present as one's assigned gender. It may not even be about how one looks, but just the way the clothing makes you feel. For the first year and a half of my own transition I could not bear to wear unisex t-shirts because they just made me feel more masculine. Even now I have to cut the collars out of them, because the close neck makes me feel dysphoric.
### Presentation's Affect on Physical Dysphoria.
{!{ <div class="gutter">{{inject '~/tweet' ids=(array
'1215716435068100611'
'1215716435974066176'
'1215716436980703233'
'1215716438020849664'
) tweets=meta.tweets className="oneblock" }}</div> }!}
Clothing can also play a major role in the level of physical dysphoria a person experiences. Mens clothing always cut very boxy, straight up and down on the vertical and very square in the horizontal. Women's clothing is cut for more curves, accentuating waistlines and hip shape. Men's pants feature a lower crotch to make room for external genitals, and no fitting for curves, where womens bottoms are the opposite. Women's clothing is often form fitting, where Male clothing is rarely form fitting at all. Men's clothing is often made of sturdier and thicker materials, meant to be worn as a single layer. Women's clothing is often made of thinner and stretchier materials, expected to be layered together.
Because these structures are meant to fit the masculine or feminine forms, they tend to amplify the sensation of wrongness. A classic affect is the way that the difference between mens and womens jeans can have a radical affect on a trans person's comfort level. Unfortunately this works both ways, as even affirming clothing can reveal how your shape is a mismatch.
I, myself am very feminine in my preferred presentation, and I had a longing to wear dresses from when I was just five years old. I abhorred wearing suits, hating the way they fit on my body, since they always tugged in ways that felt very incorrect for what my body needed. I refused to wear any denim for most of my life because men's jeans always felt so incorrect (women's jeans and leggings, however, feel amazing). Then as I entered into transition and began to present more female, my dysphoria struck again in the ways my body did not conform to what womens clothing was expecting (too much in the crotch, too wide and bulky in the shoulders, too large in the waist, not large enough in the chest). It wasn't until the second year that I had experienced enough change in my shape to where womens clothing was properly affirming of my shape.
What does this look like? Well, it looks a lot like other common body image issues. A tendency to avoid anything form fitting, leaning towards softer fabrics and baggier clothes. A classic gender dysphoria trope is the kid who wears nothing but sweatpants and hoodies. Clothes will be oversized in order to keep them from hugging the body. AFABs may prefer to wear compressing sports bras in order to minimize their chests, and avoid anything with a tight waistline.
{!{ <div class="gutter">{{inject '~/tweet' ids=(array
'1191555135756853249'
) tweets=meta.tweets className="" }}</div> }!}
Internally it most often manifests as intense jealousy of the people you wish you could be. Jealousy over an influencer's body shape, a strong desire for the outfit of a person on the street, and most especially envy of other trans people. This feeling often persists well into transition, because this sensation of wanting to be other people of your gender is actually completely natural, even for cis people.
### Presentation's Affect on Social Dysphoria.
Presentation can be important for avoiding misgendering, especially early in transition. A lot of trans people feel a need to perform their gender in order to be accepted for who they are, leaning in to feminine or masculine presentation more than they actually would like in order to make up for their body and ensure that people gender them correctly. Those pursuing medical transition may find this need becomes less important as their bodies change and they become able to be gendered correctly without all of the performance.
Performative Presentation was practically required prior to the reformation of WPATH in 2011; anyone who showed up to a doctors appointment without extreme feminine or masculine presentation risked be labeled a fake and losing their treatment under the Harry Benjamin Scale. Trans women actually would lost their estrogen simply for wearing jeans and a blouse instead of a dress, or for not putting on enough makeup. This is one of the reasons why transmedicalist ideology is so dangerous, it would see us returning to this system, labeling anyone who doesn't meet stereotypical views of femininity and masculinity as not actually transgender.
Presentation is especially important among pre-pubescent children, as they lack any significant secondary sexual characteristics. Clothing and hair are the only ways we have to show the gender of a child, so much so that if a baby simply wears a pink shirt, strangers assume it is a girl. Even unisex clothing for kids is strongly gendered by way of colors and graphics. For trans children it can be extremely distressing to be either forced to cut their hair, or required to grow it out. Denying a young trans girl access to dresses, or forcing them onto a trans boy, can be debilitating to their morale.
{!{ {{inject '_pager'}} }!}

View File

@ -0,0 +1,30 @@
---
date: "2020-01-26T20:41:55.827Z"
title: "How Gender Dysphoria Manifests: Sexual Dysphoria"
description: "Sometimes a Cigar doesn't want to be smoked."
tweets:
- '1137399651458519040'
---
# Sexual Dysphoria
Closely related to Societal Dysphoria is dysphoria centered around sexuality, sexual relationships, and the act of having sex. [Heteronormative](https://en.wikipedia.org/wiki/Heteronormativity) gender roles come loaded with the expectation that [AMABs will top and AFABs will bottom](https://en.wikipedia.org/wiki/Top,_bottom_and_versatile). These dynamics get reinforced by our popular media, by toxic masculinity, and especially by our pornography, even in *transgender* pornography (the bulk of trans/cis pornography involves the trans woman topping, when in reality a majority of trans women are submissive). Deviations from these roles often result in shame, both from partners and from peers.
Of course, this is not an absolute, by any means, and many heterosexual cis couples do find ways out of these molds, finding a new dynamic in their relationship, or engaging in kinks to satisfy desires. Some couples find they aren't sexually compatible at all and seek other partners. However, there are many many external pressures discouraging this kind of self-awareness and discovery, and breaking away from those demands can be extremely difficult, even traumatic. This is particularly true when there is a background of conservatism or religious virtuism.
Cisgender gay relationships shirk this by virtue of necessity, opening the doors for individuals to explore what role leaves them more fulfilled. Some gay couples have an established dominant/submissive dynamic, and they enter into the relationship with that already understood. Others resolve it by switching up which partner is dominant. Yet, gay relationships can still get caught up in these kinds of expectations in regards to [butch/femme](https://en.wikipedia.org/wiki/Butch_and_femme), [bear](https://en.wikipedia.org/wiki/Bear_(gay_culture)), and [twink](https://en.wikipedia.org/wiki/Twink_(gay_slang)) dynamics.
What does all this mean? Trans people who enter into perceptually heterosexual relationships pre-transition sometimes find themselves losing interest in sexual intercourse, as penetrative acts do not produce the fulfillment that they would expect. In extreme cases it can feel completely wrong and trigger panic. The sensations may feel pleasurable, but the experience is out of place, and the act itself feels forced.
{!{ <div class="gutter">{{inject '~/tweet' ids=(array
'1137399651458519040'
) tweets=meta.tweets className="" }}</div> }!}
This can lead to one feeling less enthusiastic or even disinterested in sex, as half of what makes up sex drive is the mental context of the situation. Many trans people never even experience sex until adulthood, functionally operating as asexual due to how severely their dysphoria has shutdown all sex drive. They may still perform for the sake of their partners, but not get as much enjoyment as they could, and even end up disconnecting from reality around them in order to accomplish the task.
This dysphoria may be so significant that they find themselves taking a sexual identity that they don't actually connect with. It is not unheard of for a trans person to realize after coming out that they never actually felt a connection to the sexual orientation that they had identified with previously, but were rather using it as a way to feel less dysphoric in their sex lives.
Some trans women, for example, identified as gay men pre-transition out of a desire to have a partner that treats them like women during sex, but find themselves to actually be lesbians once that demand is lifted. Others may attempt to live as gay men, but find that the role doesn't fulfill them because they know their partners see them as men.
{!{ {{inject '_pager'}} }!}

View File

@ -0,0 +1,75 @@
---
date: "2020-01-26T20:41:55.827Z"
title: "How Gender Dysphoria Manifests: Social Dysphoria"
description: "Pronouns and Deadnames and Gendering, oh my."
tweets:
- '1215718003310039040'
- '1215720411788382210'
- '1215724301065891841'
- '1215727546387648517'
- '1215727547780096000'
- '1215731319973523456'
- '1219968711681040384'
- '1137185510793678848'
---
# Social Dysphoria
{!{ <div class="gutter">{{inject '~/tweet' ids=(array
'1215718003310039040'
'1215720411788382210'
'1215724301065891841'
'1215727546387648517'
'1215727547780096000'
'1215731319973523456'
) tweets=meta.tweets className="oneblock" }} </div> }!}
All social gender dysphoria orbit around one central concept: What Gender do people believe me to be? Social Dysphoria is about how the outside world perceives you, how others address you, and how you are expected to address them. This applies differently prior to the trans person becoming self-aware of their own gender, versus how Social Dysphoria is experienced after a trans awakening (cracking one's shell).
While still in the dark, the only awareness is that something seems off about the way you interact with your interactions with other people. People of your assigned gender seem to interact with each other in ways that do not feel natural to you. Their behaviors and mannerisms feel strange and surprising, where interactions with individuals of your true gender feel easier. You relate to people closer to your own truth.
For example, an AMAB trans person may find themselves very uncomfortable in groups of men. They may feel out of place and struggle to fit in among their male peers. Masculine social interactions don't come naturally to them, and trying to emulate their male friends feels awkward. They may feel themselves drawn more to friendships with women, but become frustrated at the social and heterosexual dynamics that come into play between men and women, preventing them from forming platonic relationships.
This feeling of wrongness intensifies as the person becomes more and more aware of their own incongruence, and upon realizing who they really are it takes on a new shape. For binary trans people this often may be about the intense need to be seen as your true gender, be it male or female. Some non-binary people experience this more as euphoria at being seen as neither male or female and thus only being referred to in ungendered ways, or from being read as different genders by different people in the same setting. Some experience intense euphoria when people are incapable of reading their gender and become confused.
Social dysphoria is where pronouns and misgendering comes in to play; being addressed with a gendered pronoun such as she, he, him, or her which is not the pronoun that aligns with our gender is extremely discomforting. Granted, this is true for *all* people, including cisgender people, but where a cis person will be insulted by being misgendered, a trans person will feel hurt. It's like nails on a chalkboard, or steelwool across skin. Hearing the wrong pronoun is a reminder that the person you are talking to does not recognize you for the gender that you are.
Gender neutral pronouns can also be unsettling for binary trans people if used in a way that make it clear the person is avoiding the pronoun that matches them. This often is an indication that a person has been read as being transgender, and the person addressing them doesn't know what pronouns they use. Asking their pronouns can resolve this situation immediately, but the paradox is that even in that scenario, having their pronouns asked may itself induce dysphoria around having been recognized as being trans. It is sort of a catch-22.
Singular they can also be used maliciously when a transphobic individual refuses to use the correct pronoun, but knows they will get in trouble for using the wrong pronouns. Tone and intent matter a lot.
The same also applies to names. Being called by one's given name (deadname) instead of their chosen name can feel invalidating when done ignorantly, and downright dismissive when done intentionally.
Social Dysphoria may manifest pre-transition in feelings of isolation or misplacement when interacting with others. For example, an AMAB (Assigned Male At Birth) trans person may find themselves very uncomfortable when socializing with a group of men, like they just don't fit in. They may find themselves deeply hurt when women shy away from them in public, and get frustrated that they aren't able to form platonic relationships with women due to heterosexual expectations.
It may also manifest as joy or embarrassment at being labeled as your true gender while still living as your assigned gender. Examples:
- An AMAB person being labeled a girl, intending insult, but it causing them to blush rather than get angry.
- An AFAB person being called Sir, and feeling better for it.
{!{ <div class="gutter">{{inject '~/tweet' ids=(array
'1219968711681040384'
) tweets=meta.tweets className="" }} </div> }!}
The discomfort caused by social dysphoria can pressure a trans person to act and present in an exaggerated manner in order to try to convince the rest of the world that they really are who they say they are. Trans feminine people may concentrate on makeup and feminine clothes, and become quieter in order to seem more demure, speaking in a higher voice. Trans masculine people will lean on masculine clothing styles, stand taller, suppress displays of emotion, start speaking louder, and make their voices intentionally deeper.
### Physical vs Social Dysphoria
Some physical traits which may cause discomfort all the time for some trans people may only manifest as a social dysphoria for others. For example, some people may only be self conscious about their physical appearance when it causes them to be misgendered or clocked (read as being trans), and feel completely comfortable when interacting in environments where they are always seen and treated as their true gender.
I, myself, have no direct physical dysphoria around my voice, I actually really enjoy singing in my natal baritone, and when I am home with just my family I let me voice relax. When out in public, however, being able to speak in a feminine voice plays a critical role in my being seen as a woman by strangers, so I put a lot of effort into training it into a feminine sound. My feminine voice turns on the instant I answer the phone or leave the house, it isn't even a conscious thing.
### "One of us!"
A very curious and surprisingly phenomenon is that closeted trans people have a tendency to find each other without ever knowing they've done it. There's a funny pattern that I have heard duplicated over and over where one person in a friend group realizes they are transgender, starts to transition, and that inspires other members of the group to also realize they are trans and come out as well.
{!{ <div class="gutter">{{inject '~/tweet' ids=(array
'1137185510793678848'
) tweets=meta.tweets className="" }} </div> }!}
Trans people subconsciously tend to gravitate towards each others friendships, both out of a need for peers who think and act the same as us without judgments, and due to a kinship of social ostracization. This is not exclusive to trans people, of course, the same happens for all types of queers, but the way it has a rippled effect is quite powerful. It's very similar to the way an entire friend group will get married and have kids all in response to one member of the group initiating.
Trans people often continue to self-select their groups post-transition as well, as we simply understand each other better than cis people can. There is an energy that occurs when a group of trans people get together in a location, the room becomes charged with camaraderie and commiseration. We all have so much in common in our histories, so many shared experiences, that short of personality conflicts we instantly bond together.
{!{ {{inject '_pager'}} }!}

View File

@ -0,0 +1,69 @@
---
date: "2020-01-26T20:41:55.827Z"
title: "How Gender Dysphoria Manifests: Societal Dysphoria"
description: "Because a Role is a Role, and a Toll is a Toll, and it's a heavy toll to live the wrong role."
tweets:
- '1201138482569195526'
- '1216109204093722630'
- '1216109206509694979'
- '1216109207671508992'
- '1216109214994747393'
- '1216110299285200896'
- '1216110666626555904'
- '1216111083997605888'
- '1216112014411599877'
---
# Societal Dysphoria
Gender roles exist, and as much as we may try to buck them and point out the sexism that exists, there will always be expectations placed on people for their gender. The strongest of these are in marital and parental roles; "Husband", "Wife", "Mother", "Father", these terms come with loads of baggage attached to them, and the wrong role, or even any role at all, can feel like a lead lined straight jacket. You are given a whole book full of behaviors and actions, likes and dislikes, that you are just expected to fulfill, and if you fail to meet those requirements then you are seen as a bad spouse or a bad parent.
An AFAB birthing parent may experience severe dysphoria around being labeled as a mother. The vast majority of resources for birth are *extremely* female gendered, so just the very process of conceiving, carrying and giving birth is exceptionally loaded with gender expectations. If you are pregnant then you are labeled a mom, regardless of how you actually feel about your role, and with that comes a whole load of assumptions. Assumptions about caregiving, breastfeeding, and child rearing.
Cisgender [passing](https://en.wikipedia.org/wiki/Passing_(gender)) trans feminine individuals also run into this. If you are holding an infant or tending to a child then you are labeled a mom (unless the child is mixed race, then you're demoted to nanny, but that's a whole other topic). This can be validating, because it is a sign that you've been seen as a woman, but it can also be extremely *invalidating* when cis women start to talk about what they think are shared experiences with reproductive processes.
Some unexpected ways that Societal Dysphoria can appear are in the need to conform to the social standards of your true gender. For example, many trans women have stories about feeling the need to cover up their chest pre-transition out of an intrinsic sense of modesty. A discomfort at swimming topless is a common trait, even when there is no understanding of ones true self; something just knows.
### Shame
Failure to live up to these roles can manifest *intensely* as shame and humiliation. Growing up closeted and struggling to fit into common gender tropes often results in signs of disappointment from parents and peers who expected otherwise. A father may be disappointed that their AMAB child isn't willing to engage in sports or other masculine activities. Female peers may demonstrate disapproval of an AMAB teenager choosing to hang out with a male social circle. Teen boys may ostracize an AMAB trans person who doesn't join in with their humor.
These kinds of situations can lead to bullying and abuse, pushing the trans person to feel isolated, alone, and out of place. This sense of division then creates feelings of shame for failing to be the person everyone expects them to be. This then manifests as depression on top of other dysphoria, compounding their pain.
{!{ <div class="gutter">{{inject '~/tweet' ids=(array
'1201138482569195526'
) tweets=meta.tweets className="" }}</div> }!}
The shame becomes especially intense at the moment of revealing themselves to be trans. Transphobic friends and family having negative, sometimes even violent reactions to a trans person coming out of the closet converts that shame into extreme guilt and disgrace. An adult trans person in a marriage may feel a tremendous amount of remorse at upending their spouse's life by revealing themselves. They may expect reproach from their neighbors and peers, and fear how that will affect their spouse and/or children.
This too is a form of gender dysphoria, as these influences would not have been felt if the person had been cisgender.
The other way shame comes in to play is in the systemic transphobia present in our society. Trans adults of today grew up watching transphobic media in their childhood. The transsexual obsession of the late 80s and early 90s was horrifically traumatic for trans kids of the time, watching all the adults and peers around them laugh, jeer and be disgusted by people who they not only identified with, but strongly empathized and looked up to. This shame sits with us for our entire lives; it is a fundamental reason for why so many trans people do not come out until their late 30s or later, because only when they reach mid-life are they able to overcome that shame.
Shame also tends to build up until it boils over into radical action. A very common aspect among trans people's histories are cycles where they will build up their presentation, fighting their feelings less and less, until suddenly they feel overcome with the shame and purge everything, vowing to never pursue those feelings again. This pattern repeats over and over again.
### Dating and Romantic Relationships
{!{ <div class="gutter">{{inject '~/tweet' ids=(array
'1216109204093722630'
'1216109206509694979'
'1216109207671508992'
'1216109214994747393'
'1216110299285200896'
'1216110666626555904'
'1216111083997605888'
'1216112014411599877'
) tweets=meta.tweets className="oneblock" }}</div> }!}
Societal Dysphoria *strongly* comes into play with courtship rituals. Being forced into being the boyfriend or girlfriend when you are not a boy or a girl is extremely disorienting and often feels very unfair. AMABs may find themselves wishing *they* were the one being pampered, and AFABs may become uncomfortable with the amount of attention they receive from their prospective partners (beyond the discomfort that women experience, as this includes genuine attention, not just unwanted attention). The expectations placed on them by their partners to fill these courtship roles may feel like a heavy burden to bear. By contrast, dating as your true gender becomes euphoric. Buy a trans girl flowers and see how much she swoons.
A closeted trans person may feel so much pressure to conform to heterosexuality that they suppress their own instincts with regards to relationships and take on a performative role. Many a trans woman has attempted to play the role of a heterosexual husband to a wife, only to realize with transition that they are actually submissive themselves and would prefer to have a male partner. They may not even be attracted to women.
Beyond discomfort, many trans people realize that the dynamics of relationships that they have experienced simply did not fit the shape of how they appeared. Many trans people come to realize after transition that they had never actually dated like a cis person of their assigned gender, instead always having romantic relationships that fit their true orientation. Male to male and female to female relationships have completely different patterns from heterosexual relationships; different courtship rituals, different perceptions, different communication styles. Men relate differently to men than they do to women, and women to women differently than they do to men, even when they don't know they are men or women.
For example, I myself realized after coming out to my wife that all of my previous dating attempts had absolutely been sapphic in nature. My first order had always been to become good friends with them. Dates would never be labeled as dates because we would just sit and talk somewhere, hanging out together. Consequently, several of my relationships ended simply because I was too scared to make the first move out of destroying the friendship. I would spend half my waking day thinking about them and wanting to be around them, not out of sexual lust, but out of personal infatuation. My first girlfriend straight up told me on our first date that I was unlike any man she'd ever dated because I enjoyed talking instead of just trying to get physical. She broke up with me two months later because I wasn't as assertive as she wanted from a partner.
This all gets even more complex for non-binary people, some of whom can at best describe their dating style as Queer.
{!{ {{inject '_pager'}} }!}

117
pages/gdb/treatment.md Normal file
View File

@ -0,0 +1,117 @@
---
date: "2020-01-26T20:41:55.827Z"
title: "Treating Gender Dysphoria"
description: "Transition is the cure."
---
# How is Gender Dysphoria Treated?
Treatment options vary significantly depending on the individual person's needs. Every single transition is unique, and there is no one way to transition. This section is a list of possible pathways.
## Social Transition
In a phrase: Coming out of the closet. This is simply announcing to the world that you are transgender and that you wish to use a new name and/or new pronouns. Or not, you may just wish for people to know that you are trans and do not actually identify with your assigned binary gender. For some non-binary people this may not even be a full step away from their assignment, since gender is a spectrum and there is such as thing as a "non-binary man" and a "non-binary woman".
A social transition is the act of stepping out of the closet, and it can relieve a lot of stress from suppression of ones self.
## Legal Transition
This is the process of changing your legal documents to reflect your true gender. This may be through a legal name and gender change issued by a court, through a change of gender marker on an official ID, or through re-issuing of birth certificates and marriage licenses.
## Presentational Transition
These are changes to how you style yourself, be it your clothes, your hair, or the use of makeup. Our society heavily genders all of these things, and switching presentation is both affirming to one's self and also sends cues to those around them about how they wish to be addressed.
## Medical Transition
For adults this is hormone replacement therapy and surgery. For adolescents this often means puberty blockers until the teen is old enough to be certain of which gonadal hormone they want to have. For pre-pubescents, this is nothing. Let me repeat that again, since transphobes keep getting it wrong.
***PREPUBESCENT CHILDREN DO NOT MEDICALLY TRANSITION***.
While the American Academy of Pediatrics [strongly encourages the validation and acceptance of transgender youth](https://pediatrics.aappublications.org/content/pediatrics/early/2018/09/13/peds.2018-2162.full.pdf), and the enabling of all other forms of transition, they explicitly do not support doctors beginning either hormone therapy or puberty blockers until a child has reached [Tanner stage 2](https://en.wikipedia.org/wiki/Tanner_scale).
Furthermore, no surgeon in the United States will perform a gender altering surgery on a minor (excluding intersex "corrections", which is a whole other problem outside the scope of this article). Very few children have strong enough features to be read as either male or female without clues provided through presentation. Allowing a child to change their hair and clothes is all that is needed for the child to be seen as male or female.
## Hormonal Transition
**Trans Masculine Hormone Therapy** (female to male sexual characteristics) consists of the introduction of testosterone, usually via intramuscular injection or topical gel. The increase in total gonadal hormones typically causes a cessation of ovulation, which is the source of the majority of estrogen produced in the ovaries.
**Trans Feminine Hormone Therapy** (male to female sexual characteristics) consists of the introduction of estrogen, typically estradiol, via oral pills, patches, or regular injections (intramuscular or subcutaneous). The use of slow dispensing implants is also becoming more and more common. It is also common practice to prescribe an anti-androgen to block testosterone production or absorption. In the United States this is usually Spironolacotone, a blood pressure medication which has a testosterone blocking side-effect. Outside of the US the most common drug is Cyproterone Acetate, an androgen receptor blocker, which is not available in the US. Doctors may also prescribe Bicalutamide, which also blocks androgen receptors. However, some doctors may simply opt to use larger estradiol doses in order to cause the body to halt testosterone production.
**In adolescents**, puberty blockers may involve the above androgen blockers, or if it is covered by insurance, the use of an antigonadtropin (drug which blocks the hormones that cause the production of estrogen and androgen) such as leuprolide acetate (a shot delivered every few months) or histrelin acetate (an annual implant).
## Surgical Transition
Transgender surgeries are typically divided into three separate categories:
**Bottom Surgery** (modifications to genitals).
- Trans Feminine:
- Orchiectomy (removal of the testicles)
- Scrotectomy (removal of scrotal tissue, following orchiectomy)
- Vaginoplasty (creation of a vaginal cavity)
- Vulvaplasty (creation of a vulva, with or without depth).
{!{ <div class="gutter"><div class="card"><div class="card-body"><h4 class="card-title">For Your Information</h4> }!}
A newly developing area of bottom surgery is in AMAB non-binary operations which attempt to perform vaginoplasty *without* the removal of the penis. This particular surgery is extremely experimental and has been performed less than a dozen times in the United States, but the outlook for the future is good.
{!{ </div></div></div> }!}
- Trans Masculine:
- Hysterectomy (removal of uterus and cervix)
- Oophorectomy (removal of one or both ovaries)
- Vaginectomy (removal of vaginal cavity)
- Metoidioplasty (a process which increases the size of the clitorus into a penis)
- Phalloplasty (construction of a penis from skin grafting)
- Urethroplasty (extension of the urethral canal through the phallus)
- Scrotoplasty (use of labia majora and false testicles to construct a scrotum).
**Top Surgery** (modifications to the chest)
- Trans Feminine:
- Breast Augmentation via fat transfer or implants.
- Trans Masculine:
- Bilateral Mastectomy (breast tissue removal) with chest reconstruction.
**Facial Feminizing / Masculinizing Surgery** (modifications to the skull, cartilage and skin on the face).
The younger a person is, the less they will need these surgeries, especially if they medically transition prior to the age of 20.
- Trans Feminine:
- Forehead recontouring
- Eye socket recontouring
- Brow lift
- Hairline correction
- Blepharoplasty (lifting of eye bags)
- Rhinoplasty (reshaping of the nose)
- Cheek implants
- Lip lift
- Lip filling
- Jaw recontouring
- Tracheal shave (adam's apple reduction)
- Rhytidectomy (face lift)
- Trans Masculine:
- Forehead augmentation
- Jaw augmentation
- Chin augmentation
- Tracheal augmentation (adam's apple enlargement)
Other Trans Feminine Surgeries:
- Brazilian Butt Lift. Fat from the belly is transplanted into the butt in order to increase hip to waist ratio.
- Voice Feminisation Surgery. An incision is performed in the vocal chords in order to permanently raise the pitch.
- Cinderella Surgery. Bones in the foot are shortened in order to reduce foot size. EXTREMELY RISKY
- Shoulder Reduction. The collar bone is shortened to reduce the width of the shoulders. EXTREMELY RISKY
{!{ {{inject '_pager'}} }!}

View File

@ -1,15 +1,16 @@
--- ---
date: "2020-01-26T20:41:55.827Z" date: "2020-01-26T20:41:55.827Z"
title: "The Gender Dysphoria Bible" title: "What is Gender?"
subtitle: "What is Gender?" description: "How do we define the concept of Gender, and how does it differ from Sex?"
description: "A dive into the multitude of ways that gender dysphoria manifests and what it means to be transgender."
tweets: tweets:
- https://twitter.com/CognitiveSoc/status/1228717614630940672 - https://twitter.com/CognitiveSoc/status/1228717614630940672
--- ---
{!{ {{inject '~/tweet' ids=(array # What is Gender?
{!{ <div class="gutter">{{inject '~/tweet' ids=(array
'1228717614630940672' '1228717614630940672'
) tweets=meta.tweets className="sideline" }} }!} ) tweets=meta.tweets className="hide-reply" }}</div> }!}
If you trace the etymology of the word to its Latin roots, gender simply means "type". Historically the word was used in literature to refer to masculine, feminine and neutral nouns. In 1955 psychologist John Money proposed using the term to differentiate mental sex from physical sex, but he was not the first to do so. If you trace the etymology of the word to its Latin roots, gender simply means "type". Historically the word was used in literature to refer to masculine, feminine and neutral nouns. In 1955 psychologist John Money proposed using the term to differentiate mental sex from physical sex, but he was not the first to do so.
@ -21,21 +22,23 @@ Human Sex (the adjective, not the verb) is broken down into three categories:
Any of these three aspects can fall into a position on a range of values. Your elementary school health class probably taught you that Genotype is binary, either Female (XX) or Male (XY), when the reality is that there are a dozen other permutations that can occur within human beings. Any of these three aspects can fall into a position on a range of values. Your elementary school health class probably taught you that Genotype is binary, either Female (XX) or Male (XY), when the reality is that there are a dozen other permutations that can occur within human beings.
{!{ {{inject '~/img' images.bimodal className="card sideline"}} }!} {!{ {{inject '~/img' images.bimodal className="card borderless center span34"}} }!}
Likewise, many people believe that Phenotype is also binary, but biology has recognized for hundreds of years that when you plot out all sexual characteristics across a population, you actually end up with a bimodal distribution where the majority of the population falls within a percentile of two groups. This means that some people will, simply by nature of how life works, fall outside of the typical two piles. Many people fall in the middle, with characteristics of both sexes. Likewise, many people believe that Phenotype is also binary, but biology has recognized for hundreds of years that when you plot out all sexual characteristics across a population, you actually end up with a bimodal distribution where the majority of the population falls within a percentile of two groups. This means that some people will, simply by nature of how life works, fall outside of the typical two piles. Many people fall in the middle, with characteristics of both sexes.
Gender, however, is a lot more... wibbly wobbly timey wimey type stuff. There are a lot of different ways that people have attempted to illustrate the gender spectrum, but none have quite thoroughly captured it, because the spectrum is itself a very abstract concept.
{!{ {!{
{{inject '~/img' images.spectrum className="sideline" link="https://bahamutzero.tumblr.com/post/56838411871/gender-a-visual-guide-when-most-people-think-of"}} <div class="gutter flex">
{{inject '~/img' images.graph className="sideline" }} {{inject '~/img' images.spectrum className="" link="https://bahamutzero.tumblr.com/post/56838411871/gender-a-visual-guide-when-most-people-think-of" style="margin-bottom: 5px"}}
{{inject '~/img' images.gender_unicorn className="sideline" link="http://www.transstudent.org/gender"}} {{inject '~/img' images.graph className="" style="margin-bottom: 5px"}}
{{inject '~/img' images.gender_unicorn className="" link="http://www.transstudent.org/gender" style="margin-bottom: 5px"}}
</div>
}!} }!}
Gender, however, is a lot more... wibbly wobbly timey wimey type stuff. There are a lot of different ways that people have attempted to illustrate the gender spectrum, but none have quite thoroughly captured it, because the spectrum is itself a very abstract concept.
The short of it is, some people are very male, some people are very female, some people feel no gender at all, some people feel both, some are smack in the middle, some land along the edges. Some people oscillate all over the spectrum in unpredictable ways, changing like the wind. Only an individual can identify their own gender, no one else can dictate it for them. The short of it is, some people are very male, some people are very female, some people feel no gender at all, some people feel both, some are smack in the middle, some land along the edges. Some people oscillate all over the spectrum in unpredictable ways, changing like the wind. Only an individual can identify their own gender, no one else can dictate it for them.
Gender is part social constructs, part learned behaviors, and part biological processes which form very early in a person's life. Gender is part social construct, part learned behaviors, and part biological processes which form very early in a person's life.
Present evidence seems to suggest that a person's gender is established during gestation while the cerebral cortex of the brain is forming (more about that in the Causes of Gender Dysphoria section). This mental model then informs, at a subconscious level, what aspects of the gender spectrum a person will lean towards. It affects behavior, perceptions of the world, the way we experience attraction (separate from sexual orientation and hormonal influences) and how we bond with other people. Present evidence seems to suggest that a person's gender is established during gestation while the cerebral cortex of the brain is forming (more about that in the Causes of Gender Dysphoria section). This mental model then informs, at a subconscious level, what aspects of the gender spectrum a person will lean towards. It affects behavior, perceptions of the world, the way we experience attraction (separate from sexual orientation and hormonal influences) and how we bond with other people.
@ -51,4 +54,5 @@ What **Gender is *not*** is sexual orientation. We describe orientation using te
In generalist terms this essay will be describing gender in a sense of binary identities (male/female) vs non-binary identities (agender, bigender, genderqueer, etc), but this is purely for the sake of writing simplicity. Please know that the depth of gender experience and expression is far, far more complicated than this simple breakdown. In generalist terms this essay will be describing gender in a sense of binary identities (male/female) vs non-binary identities (agender, bigender, genderqueer, etc), but this is purely for the sake of writing simplicity. Please know that the depth of gender experience and expression is far, far more complicated than this simple breakdown.
{{inject '_pager' step=1}} {!{ {{inject '_pager'}} }!}

BIN
pages/images/_filler.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 B

BIN
pages/images/_titlecard.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 196 KiB

View File

@ -2,7 +2,7 @@
{{#content "meta"}} {{#content "meta"}}
<meta property="og:title" content="{{page.title}}"> <meta property="og:title" content="{{page.title}}">
<meta property="og:description" content={{page.description}}> <meta property="og:description" content="{{page.description}}">
<meta property="og:image" content="https://{{page.domain}}{{rev '/images/titlecard.jpg'}}"> <meta property="og:image" content="https://{{page.domain}}{{rev '/images/titlecard.jpg'}}">
<meta property="og:url" content="https://{{page.domain}}"> <meta property="og:url" content="https://{{page.domain}}">
<meta name="twitter:title" content="{{page.title}}"> <meta name="twitter:title" content="{{page.title}}">
@ -19,10 +19,7 @@
{{markdown '_index-copy'}} {{markdown '_index-copy'}}
<div class="pager"> {{inject 'gdb/_pager'}}
<span class="filler"></span>
<a href="/gdb/what-is-gender" class="btn btn-primary">Continue Reading {{icon 'chevron-right'}}</a>
</div>
</div></section> </div></section>

View File

@ -1,54 +0,0 @@
---
title: 'Tagged Posts'
---
{{#extend "layout"}}
{{#content "meta"}}
<meta property="og:title" content="{{page.title}}">
<meta property="og:description" content="Just a plus size trans girl in a straight size cis world.">
<meta property="og:image" content="{{rev '/images/avi.jpeg'}}">
<meta property="og:url" content="https://{{page.domain}}/tags.html">
<meta name="twitter:card" content="summary_large_image">{{/content}}
{{#content "bodyAttributes"}}class="page-index"{{/content}}
{{#content "body"}}
<div class="tag-list">
<h3>Posts By Tag</h3>
<div class="nav nav-pills" role="tablist">
{{#each posts.tags}}
<a
class="nav-link {{#unless @index}}active{{/unless}}"
data-toggle="pill"
role="tab"
id="{{@key}}-tab"
href="#{{@key}}"
aria-controls="{{@key}}"
aria-selected="{{#if @index}}true{{else}}false{{/if}}"
>{{this}}</a>
{{/each}}
</div>
</div>
<div class="tab-content">
{{#each posts.tags}}
<div class="tab-pane fade {{#unless @index}}show active{{/unless}}" role="tabpanel" id="{{@key}}" aria-labelledby="{{@key}}-tab">
<div class="post-grid">
{{#each (get ../posts.byTag this)}}
{{> cell}}
{{/each}}
</div>
</div>
{{/each}}
</div>
{{/content}}
{{#content "postscripts"}}
<script src="{{rev '/js/tags.js'}}"></script>
{{/content}}
{{/extend}}

View File

@ -1,29 +0,0 @@
{{#extend "layout"}}
{{#content "bodyAttributes"}}class="page-index"{{/content}}
{{#content "body"}}
<div class="card-grid" style="grid-auto-rows: unset;">
{{#each posts.all}}
<a class="titlecard-preview {{#each classes}}{{this}} {{/each}}" data-id="{{id}}">
<span>{{originalpath}}</span>
<img src="/images/filler.png" data-src="{{rev this.titlecard}}" alt="" defer>
</a>
{{/each}}
</div>
{{/content}}
{{#append 'postscripts'}}
<script src="https://cdnjs.cloudflare.com/ajax/libs/lozad.js/1.9.0/lozad.min.js"></script>
<script>
window.lozad('img[data-src]', {
rootMargin: '50% 0px', // syntax similar to that of CSS Margin
threshold: 0.5, // ratio of element convergence
}).observe(); // lazy loads elements with default selector as '.lozad'
</script>
{{/append}}
{{/extend}}

1
pages/tweets/logo.svg Executable file
View File

@ -0,0 +1 @@
<svg id="Logo_FIXED" data-name="Logo — FIXED" xmlns="http://www.w3.org/2000/svg" viewBox="75 98 250 204"><defs><style>.cls-1{fill:none;}.cls-2{fill:#1da1f2;}</style></defs><title>Twitter_Logo_Blue</title><rect class="cls-1" width="400" height="400"/><path class="cls-2" d="M153.62,301.59c94.34,0,145.94-78.16,145.94-145.94,0-2.22,0-4.43-.15-6.63A104.36,104.36,0,0,0,325,122.47a102.38,102.38,0,0,1-29.46,8.07,51.47,51.47,0,0,0,22.55-28.37,102.79,102.79,0,0,1-32.57,12.45,51.34,51.34,0,0,0-87.41,46.78A145.62,145.62,0,0,1,92.4,107.81a51.33,51.33,0,0,0,15.88,68.47A50.91,50.91,0,0,1,85,169.86c0,.21,0,.43,0,.65a51.31,51.31,0,0,0,41.15,50.28,51.21,51.21,0,0,1-23.16.88,51.35,51.35,0,0,0,47.92,35.62,102.92,102.92,0,0,1-63.7,22A104.41,104.41,0,0,1,75,278.55a145.21,145.21,0,0,0,78.62,23"/></svg>

After

Width:  |  Height:  |  Size: 793 B

22
pages/tweets/verified.svg Normal file
View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
<style type="text/css">
.st0{fill:#1DA1F2;}
</style>
<g id="_x3C_Group_x3E_">
<path class="st0" d="M512,268c0,17.9-4.3,34.5-12.9,49.7c-8.6,15.2-20.1,27.1-34.6,35.4c0.4,2.7,0.6,6.9,0.6,12.6
c0,27.1-9.1,50.1-27.1,69.1c-18.1,19.1-39.9,28.6-65.4,28.6c-11.4,0-22.3-2.1-32.6-6.3c-8,16.4-19.5,29.6-34.6,39.7
C290.4,507,273.9,512,256,512c-18.3,0-34.9-4.9-49.7-14.9c-14.9-9.9-26.3-23.2-34.3-40c-10.3,4.2-21.1,6.3-32.6,6.3
c-25.5,0-47.4-9.5-65.7-28.6c-18.3-19-27.4-42.1-27.4-69.1c0-3,0.4-7.2,1.1-12.6c-14.5-8.4-26-20.2-34.6-35.4
C4.3,302.5,0,285.9,0,268c0-19,4.8-36.5,14.3-52.3c9.5-15.8,22.3-27.5,38.3-35.1c-4.2-11.4-6.3-22.9-6.3-34.3
c0-27,9.1-50.1,27.4-69.1c18.3-19,40.2-28.6,65.7-28.6c11.4,0,22.3,2.1,32.6,6.3c8-16.4,19.5-29.6,34.6-39.7
C221.6,5.1,238.1,0,256,0c17.9,0,34.4,5.1,49.4,15.1c15,10.1,26.6,23.3,34.6,39.7c10.3-4.2,21.1-6.3,32.6-6.3
c25.5,0,47.3,9.5,65.4,28.6c18.1,19.1,27.1,42.1,27.1,69.1c0,12.6-1.9,24-5.7,34.3c16,7.6,28.8,19.3,38.3,35.1
C507.2,231.5,512,249,512,268z M245.1,345.1l105.7-158.3c2.7-4.2,3.5-8.8,2.6-13.7c-1-4.9-3.5-8.8-7.7-11.4
c-4.2-2.7-8.8-3.6-13.7-2.9c-5,0.8-9,3.2-12,7.4l-93.1,140L184,263.4c-3.8-3.8-8.2-5.6-13.1-5.4c-5,0.2-9.3,2-13.1,5.4
c-3.4,3.4-5.1,7.7-5.1,12.9c0,5.1,1.7,9.4,5.1,12.9l58.9,58.9l2.9,2.3c3.4,2.3,6.9,3.4,10.3,3.4
C236.6,353.7,241.7,350.9,245.1,345.1z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

168
scss/_card.scss Normal file
View File

@ -0,0 +1,168 @@
.card {
text-decoration: none;
background: white;
&.borderless {
border: none;
}
.card-img-top + .card-img-top {
border-top: 1px solid $card-border-color;
border-radius: 0
}
.card-body {
padding: 1em;
line-height: 1.3;
color: #333;
font-size: 12px;
font-family: $font-secondary;
ul { padding-left: 1.2em; }
}
.card-body.caption {
font-size: 10px;
text-align: center;
}
.list-group-item {
font-size: 12px;
padding: 0.5rem 1.25rem;
text-decoration: none;
&.active + .active {
border-bottom: 1px solid lighten($list-group-active-bg, 15%);
background-color: lighten($list-group-active-bg, 10%);
}
}
@include media-breakpoint-up(md) {
&.left {
float: left;
margin-right: 10px;
}
&.right {
float: right;
margin-left: 10px;
}
&.center {
margin-left: auto;
margin-right: auto;
margin-bottom: 1em;
}
&.natural {
.card-img-top {
width: unset;
max-height: 50vh;
margin: 0 auto;
}
}
&.span2, &.span3, &.span4, &.span5, &.span6, &.span34 {
&.left { clear: left; }
&.right { clear: right; }
&:first-child {
margin-top: 0.5em;
}
}
&.hero { width: 35%; }
&.span1 { width: 100%; }
&.span2 { width: 50%; }
&.span3 { width: 33%; }
&.span4 { width: 25%; }
&.span5 { width: 20%; }
&.span6 { width: 15%; }
&.span34 { width: 75%; }
}
@include media-breakpoint-down(sm) {
margin-top: 0 !important;
margin-bottom: 5px;
&.hero {
margin: 0 -15px 10px -15px;
border-left: none;
border-right: none;
border-radius: 0;
img { border-radius: 0; }
}
}
&.ig-card {
background: white;
padding:12px;
font-size:14px;
line-height:17px;
color: rgb(38, 38, 38);
font-family: Roboto, Helvetica, Arial,sans-serif;
text-decoration:none;
.ig-header {
display: flex;
flex-direction: row;
align-items: center;
.ig-avatar {
background-color: #F4F4F4;
background-position: center center;
background-repeat: no-repeat;
background-size: cover;
border-radius: 50%;
flex-grow: 0;
height: 40px;
width: 40px;
margin: 0 10px 0 0;
}
.ig-name {
display: flex;
flex-direction: column;
flex-grow: 1;
justify-content: center;
align-items: flex-start;
font-weight: 400;
line-height: 1.2;
strong {
font-weight: 600;
}
}
}
.ig-image {
margin: 10px 0;
border-radius: 5px;
}
.ig-caption {
line-height: 18px;
font-size: 14px;
font-weight: 400;
word-wrap:break-word;
margin: 0;
}
.ig-footer {
color:#c9c8cd;
font-size: 10px;
line-height: 1;
overflow:hidden;
padding:6px 0 0 0;
margin: 0;
text-overflow:ellipsis;
text-transform: uppercase;
}
}
}

55
scss/_footer.scss Normal file
View File

@ -0,0 +1,55 @@
footer, .footer {
font-size: 10px;
text-align: center;
margin-top: 10px;
margin-bottom: 20px;
padding: 0 20px;
p {
margin: 0 auto;
}
&, a { color: #ccc; }
a { text-decoration: underline; }
.cc-by-nc-sa {
line-height: 1;
display: inline-block;
vertical-align: bottom;
.svg-icon {
margin: 0 5px;
}
}
}
.patreon-support {
font-size: 12px;
strong {
margin-bottom: 5px;
display: block;
}
a {
color: #aaa;
}
ul {
padding: 0;
li {
display: inline;
}
li::after {
content: ", ";
}
li:last-child::after {
content: "";
}
}
}

26
scss/_global.scss Normal file
View File

@ -0,0 +1,26 @@
body {
font-family: $font-primary;
}
span.svg-icon {
$size: 1.5em;
display: inline-block;
position: relative;
height: $size;
width: $size;
line-height: 1;
svg {
width: 100%;
height: 100%;
fill: currentColor;
}
}
img.svg-icon {
height: 1.5em;
display: inline-block;
position: relative;
line-height: 1;
}

30
scss/_grid-row.scss Normal file
View File

@ -0,0 +1,30 @@
.grid-row {
clear: both;
display: grid;
grid-template-rows: 1fr;
grid-gap: 10px;
grid-template-columns: repeat( auto-fit, minmax( 250px, 1fr ) );
margin-bottom: 1rem;
@include media-breakpoint-up(md) {
.double { grid-column-end: span 2; }
}
&.by-two {
grid-template-columns: repeat( auto-fit, minmax( 420px, 1fr ) );
}
&.by-three {
grid-template-columns: repeat( auto-fit, minmax( 325px, 1fr ) );
}
&.by-three-forced {
@include media-breakpoint-up(md) {
grid-template-columns: repeat( auto-fit, minmax( 30%, 1fr ) );
}
}
}

185
scss/_header.scss Normal file
View File

@ -0,0 +1,185 @@
@mixin header--active {
min-height: 0;
color: #555;
background: #fff;
box-shadow: 1px 2px 10px rgba(0, 0, 0, 0.3);
a {
&:hover, &:focus {
text-decoration: none;
}
}
}
body.inner-page header {
@include header--active;
}
header {
color: white;
padding: 0 3rem;
position: fixed;
top: -1px;
left: -1px;
right: -1px;
z-index: 100;
@media (max-width: 500px) {
padding: 0.5rem 1rem 0;
position: static;
}
transition-property: min-height, background, box-shadow;
transition-duration: 0.4s;
background: none;
// width: 100%;
min-height: 100px;
display: flex;
align-items: center;
justify-content: center;
a {
color: inherit;
// transition: none;
&:hover, &:focus {
color: inherit;
text-decoration: none;
}
}
.top-brand {
text-align: center;
color: inherit;
font-family: $font-brand;
font-size: 2em;
white-space: nowrap;
@media (max-width: 500px) {
font-size: 1.8em;
}
}
@media (min-width: 500px) {
&.active {
@include header--active;
}
}
nav {
flex: 1;
max-width: 1200px;
display: flex;
justify-content: space-between;
align-items: center;
@media (max-width: 500px) {
flex-direction: column;
// align-items: stretch; // uncomment after menu items are added back
}
@media (max-width: 500px) {
font-size: 0.8rem;
}
}
.top-nav-inner {
display: flex;
justify-content: space-between;
align-items: center;
list-style: none;
margin: 0 0 0 1em;
padding: 0;
.top-nav-item {
transition-property: color, padding, margin;
transition-duration: 0.3s;
transition-timing-function: ease;
display: block;
padding: 0.5rem 1rem;
text-align: center;
border-top: 5px solid transparent;
border-bottom: 5px solid transparent;
white-space: nowrap;
&:hover {
border-bottom: 5px solid $primary;
}
}
.break {
flex-basis: 100%;
display: none;
}
@media (max-width: 1000px) {
.top-nav-item {
padding: 0.5rem 0.5rem;
}
}
@media (max-width: 800px) {
.top-nav-item {
border-top: none;
}
}
@media (max-width: 400px) {
flex-wrap: wrap;
justify-content: center;
.break { display: block; }
.top-nav-item {
padding: 0.25rem 0.5rem;
}
}
}
}
.disclaimer {
$cwColor: darken($gray-100, 2%);
border-bottom: 1px solid $gutter-border;
@media (min-width: 500px) {
margin-top: $header-full-height;
}
> div {
margin: 0 auto;
max-width: 1200px;
padding: 10px 1em;
@media (max-width: 500px) {
padding: 10px 1em;
}
}
background-color: $cwColor;
font-size: 0.8rem;
font-weight: 300;
.strong {
display: block;
font-weight: 600;
margin: 5px -10px;
padding: 0px 10px 5px;
font-size: 1.2rem;
font-family: $font-secondary;
p { margin: 0; }
}
p:last-child {
margin-bottom: 0;
}
}

101
scss/_index.scss Normal file
View File

@ -0,0 +1,101 @@
.front-page {
header {
@media (max-width: 500px) {
position: absolute;
}
}
.top-fold {
min-height: 100vh;
background-color: $header-bg-mid;
background-image: linear-gradient(135deg, $header-bg-1, $header-bg-2);
padding-top: $header-full-height;
@media (max-width: 400px) {
padding-top: 100px;
}
.container {
margin: 0 auto;
padding-bottom: 1em;
padding-top: 2em;
max-width: 1000px;
}
blockquote {
padding: 1em;
border-radius: 1em;
margin-top: -2.5em;
margin-bottom: 0;
margin-left: 1em;
margin-right: 0.5em;
float: right;
background: #ad7ad6;
border: 3px solid rgba(#ad7ad6, 0.9);
box-shadow: inset 0px 1px 5px rgba(#000, 0.2), 0px 2px 3px rgba(#000, 0.7);
text-shadow: 0px 1px 3px rgba(black, 0.9);
color: $gray-100;
max-width: 500px;
width: 50vw;
font-family: $font-secondary;
transition-property: margin;
transition-duration: 0.3s;
transition-timing-function: ease;
p {
margin: 0;
}
span {
font-weight: 300;
}
}
.copy {
color: #333;
padding: 1em 1.4em;
background: #eee;
border-radius: 0.3rem;
box-shadow: inset 0px 1px 5px rgba(#000, 0.2), 0px 1px 5px rgba(#000, 0.9);
text-shadow: 0px 1px 3px rgba(#fff, 0.6);
max-width: 850px;
margin-left: 0.5em;
}
@media (max-width: 760px) {
blockquote {
max-width: unset;
width: unset;
margin-top: -1em;
margin-bottom: 1em;
}
}
@media (max-width: 865px) {
.copy {
margin-right: 0.5em;
}
blockquote {
margin-right: 1em;
}
}
}
.pager {
margin: -1.5em 1em 1em;
.btn {
min-width: unset;
}
}
}

99
scss/_markup.scss Normal file
View File

@ -0,0 +1,99 @@
.markup {
p a {
transition-property: color, padding, margin;
transition-duration: 0.3s;
transition-timing-function: ease;
color: $primary;
text-decoration: underline;
&:hover {
color: #e84992;
}
}
img {
max-width: 100%;
}
hr {
overflow: hidden;
}
blockquote {
font-family: $font-secondary;
font-weight: 300;
font-size: 0.94em;
line-height: 1.4;
background: $trans-blue-lightest;
border: 1px solid $trans-blue;
box-shadow: 0 1px 3px rgba($trans-blue,0.5);
border-radius: 5px;
padding: 15px;
color: black;
position: relative;
overflow: hidden;
strong {
font-weight: 600;
}
&::before {
font-family: cursive;
font-weight: 700;
display: block;
padding-left: 10px;
content: "\201C";
font-size: 50px;
position: absolute;
left: -10px;
top: -16px;
color: $trans-blue;
text-shadow: 0 1px 3px rgba($trans-blue,0.5);
opacity: 0.8;
}
p:last-child {
margin-bottom: 0;
}
}
h1, h2, h3, h4, h5 {
clear: left;
display: flex;
a { text-decoration: inherit; }
.header-link {
flex: 1;
font-size: 0.75em;
text-decoration: none;
align-self: center;
text-align: right;
opacity: 0.15;
&:hover {
opacity: 1;
}
img {
height: 1em;
}
}
}
li p {
margin-bottom: 0;
margin-top: 0.5em;
}
li p + ul {
margin-bottom: 0.5em;
}
ul { padding-left: 2em; }
}

35
scss/_pager.scss Normal file
View File

@ -0,0 +1,35 @@
.pager {
display: grid;
grid-template-columns: 1fr 1fr;
grid-gap: 5px;
justify-content: center;
align-items: center;
margin: 1em 0;
&.top {
margin: 0 0 1em;
}
> div {
display: flex;
}
.btn {
font-size: 0.9em;
box-shadow: 0px 1px 5px rgba(#000, 0.5);
color: white;
white-space: nowrap;
// width: 100%;
min-width: 75%;
display: flex;
}
.back, .back .btn {
justify-content: flex-start;
}
.forward, .forward .btn {
justify-content: flex-end;
}
}

105
scss/_post.scss Normal file
View File

@ -0,0 +1,105 @@
body.page {
@media (max-width: 500px) {
font-size: 0.8em;
}
header {
background: $gray-800;
&.active { background: white; }
}
#body {
background-color: $gutter-bg;
@media (max-width: 500px) {
border-left: 1px solid $gutter-border;
border-right: 1px solid $gutter-border;
}
border-bottom: 1px solid $gutter-border;
max-width: 1200px;
margin: 0 auto;
}
article {
@media (min-width: 800px) {
margin-right: 400px;
@media (max-width: 1000px) {
margin-right: 300px;
}
}
background: $content-bg;
border-right: 1px solid $gutter-border;
padding: 1em 1em;
> h1:first-child {
margin-top: 0.5em;
}
@media (max-width: 500px) {
padding: 1em 1em;
> h1:first-child {
margin-top: 0.25em;
}
}
}
h1, h2, h3, h4, h5 { a {
color: inherit;
overflow: hidden;
} }
.gutter {
@media (min-width: 800px) {
position: relative;
height: 0;
left: calc(100% + 1em);
width: 400px;
padding: 0 1em;
@media (max-width: 1000px) {
width: 300px;
}
}
@media (min-width: 500px) and (max-width: 800px) {
float: right;
width: 300px;
margin-left: 1em;
zoom: 0.9;
}
// outline: 1px solid red;
&.flex, .flex {
display: flex;
flex-direction: column;
align-items: center;
}
> a > img:not(.card-img-top), > img {
max-width: 100%;
margin-bottom: 5px;
}
}
.full-wide {
width: calc(100vw - 4em);
background-color: darken($content-bg, 1%);
border: 1px solid $gutter-border;
border-radius: 0.3em;
padding: 1.2em 1.2em 1em;
box-shadow: 0 1px 3px rgba($gray-600, 0.5);
margin-bottom: 1em;
}
// @import "./pager";
}

360
scss/_tweet.scss Normal file
View File

@ -0,0 +1,360 @@
.tweet {
$borderColor: #e1e8ed;
$borderHover: #ccd6dd;
$textLight: #697882;
$textDark: #1c2022;
$textHover: #3b94d9;
$borderRadius: .35em;
$avatarSize: 36px;
// zoom: 0.8;
font-size: 12px;
border: 1px solid $borderColor;
border-radius: .35em;
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
margin-bottom: 1em;
background-color: white;
overflow-x: hidden;
overflow-y: auto;
@include media-breakpoint-up(md) {
&.capped { max-height: 700px; }
}
.emoji {
height: 1.25em;
width: 1.25em;
vertical-align: -0.2em;
padding: 0px 0.05em 0px 0.1em;
}
.tweet-item {
border-radius: $borderRadius;
padding: 1em 1em 13px;
.tweet-logo { display: none; }
}
.tweet-item + .tweet-item {
border-top: 1px solid $borderColor;
border-top-left-radius: 0;
border-top-right-radius: 0;
}
.tweet-item:first-child .tweet-logo { display: block; }
.tweet-header {
text-decoration: none;
display: grid;
grid-template-columns: $avatarSize 1fr 30px;
grid-template-rows: 1fr 1.2em 5px 1.1em 1fr;
grid-template-areas:
"avatar . logo"
"avatar name logo"
"avatar . logo"
"avatar screen-name logo"
"avatar . logo"
;
grid-column-gap: 10px;
grid-row-gap: 0px;
color: $textDark;
margin-bottom: 1em;
line-height: 1;
&:hover {
color: $textHover;
}
b {
grid-area: avatar;
display: flex;
justify-content: center;
align-items: center;
img {
width: $avatarSize;
height: $avatarSize;
border-radius: 50%;
}
}
strong {
-webkit-font-smoothing: antialiased;
grid-area: name;
font-size: 1.2em;
line-height: 1.1;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
align-self: flex-start;
.tweet-verified {
height: 16px;
width: 16px;
display: inline-block;
vertical-align: bottom;
margin-left: 4px;
background-image: url('/tweets/verified.svg');
background-position: center center;
background-size: contain;
background-repeat: no-repeat;
}
.tweet-protected {
height: 20px;
width: 20px;
display: inline-block;
vertical-align: bottom;
}
}
span {
grid-area: screen-name;
font-size: 1.1em;
color: $textLight;
}
.tweet-logo {
grid-area: logo;
height: 20px;
width: 30px;
}
}
.tweet-text {
line-height: 1.5em;
p { margin-bottom: 0.5em; }
a { color: $textHover; }
}
.tweet-quoted {
text-decoration: none;
border: 1px solid $borderColor;
border-radius: .35em;
padding: 10px;
display: block;
color: $textDark;
font-size: 14px;
margin-top: 10px;
&:hover {
border-color: $borderHover;
}
span {
color: $textLight;
}
span, strong {
line-height: 1;
}
}
.tweet-entities {
margin-top: 10px;
border-radius: 14px;
overflow: hidden;
max-width: 600px;
max-height: 600px;
.tweet-entities-inner {
padding-bottom: 56.25%;
position: relative;
> div {
position: absolute;
top: 0; right: 0;
bottom: 0; left: 0;
}
}
.tweet-entities-grid {
display: grid;
grid-gap: 5px;
grid-template: 1fr 1fr / 1fr 1fr;
height: 100%;
&.count1 .tweet-entity {
grid-row-end: span 2;
grid-column-end: span 2;
}
&.count2 .tweet-entity {
grid-row-end: span 2;
}
&.count3 .tweet-entity:first-child {
grid-row-end: span 2;
}
.tweet-entity {
display: flex;
align-items: stretch;
justify-content: stretch;
}
.tweet-entity > * {
flex: 1;
}
}
}
.tweet-photo {
background-size: cover;
background-position: center center;
}
.tweet-video {
width: 100%;
height: 100%;
border: 1px solid $borderColor;
border-radius: 14px;
}
.tweet-footer {
display: block;
color: $textLight;
font-size: 1em;
margin-top: 10px;
a {
text-decoration: none;
color: inherit;
&:hover {
color: $textHover;
text-decoration: underline;
}
}
}
&.collapse, &.oneblock {
.tweet-item {
.tweet-footer { display: none; }
}
.tweet-item + .tweet-item {
.tweet-header {display: none;}
}
.tweet-item:last-child {
.tweet-footer { display: block; }
}
}
&.oneblock {
padding: 20px;
&.borderless { border: none; padding: 0; }
.tweet-item {
border-top: none;
padding: 0;
}
.tweet-item + .tweet-item {
padding-top: 0.5em;
}
}
@include media-breakpoint-up(md) {
&.oneblock:not(.right) {
max-height: unset;
}
}
&.hide-reply .tweet-text a.mention:first-child { display: none; }
&.collapse:not(.grid-row) {
.tweet-item {
padding-bottom: 0.5em;
}
.tweet-item + .tweet-item {
padding-top: 0.5em;
}
.tweet-item:last-child {
padding-bottom: 20px;
}
}
&.grid-row:not(.collapse) {
border: none;
max-height: unset;
.tweet-item {
background-color: white;
border: 1px solid $borderColor;
display: flex;
flex-direction: column;
border-top-left-radius: $borderRadius;
border-top-right-radius: $borderRadius;
.tweet-logo { display: block; }
.tweet-text {
flex-grow: 1;
flex-shrink: 1;
}
}
}
&.grid-row.collapse {
border: none;
border: 1px solid $borderColor;
border-radius: 0;
max-height: unset;
grid-gap: 0;
.tweet-item {
background-color: white;
border: 1px solid $borderColor;
border-radius: 0;
display: flex;
flex-direction: column;
margin: -1px;
.tweet-logo { display: block; }
.tweet-text {
flex-grow: 1;
flex-shrink: 1;
}
}
.tweet-item {
.tweet-footer { display: none; }
}
.tweet-item + .tweet-item {
.tweet-header {display: none;}
}
.tweet-item:last-child {
.tweet-footer { display: block; }
}
@include media-breakpoint-up(md) {
&.by-two {
.tweet-item:first-child {
.tweet-logo { display: none }
}
.tweet-item:nth-child(2) {
.tweet-header {
display: grid;
b, strong, span {
visibility: hidden;
}
}
}
}
}
}
}

104
scss/style.scss Normal file
View File

@ -0,0 +1,104 @@
$body-bg: #f8f9fa;
$content-bg: white;
$gutter-bg: #f0f0f0;
$gutter-border: #e2e2e2;
$font-primary: 'Lato', Arial, sans-serif;
$font-secondary: 'Gothic A1', 'Helvetica Neue', Helvetica, serif;
$font-brand: 'Sriracha', Geneva, monospace;
$font-family-sans-serif: $font-primary;
$font-family-base: $font-primary;
$grid-breakpoints: (
xs: 0,
sm: 500px,
md: 800px,
lg: 1000px,
xl: 1200px
) !default;
$line-height-base: 1.6;
$headings-font-family: 'Roboto', 'Helvetica Neue', Helvetica, serif;
$headings-font-weight: 300;
$font-size-base: 1rem;
$h1-font-size: $font-size-base * 2.2;
$h2-font-size: $font-size-base * 1.8;
$h3-font-size: $font-size-base * 1.5;
$h4-font-size: $font-size-base * 1.2;
$h5-font-size: $font-size-base * 1.15;
$h6-font-size: $font-size-base;
h1, h2, .h1, .h2 { font-weight: 300; }
h3, .h3 { font-weight: 400; }
h4, h5, .h4, .h5 { font-weight: 600; }
$trans-white: #fff;
$trans-pink: #F7A8B8;
$trans-blue: #55CDFC;
$trans-pink-light: #fde6eb;
$trans-blue-light: #b9eafe;
$trans-blue-lightest: #f0f8ff;
$trans-pink-dark: #ee4b6c;
$trans-blue-dark: #0377a4;
$primary: #fc0a7e;
$header-bg-1: #E81179;
$header-bg-2: #281362;
$header-bg-mid: mix($header-bg-1, $header-bg-2);
$header-full-height: 100px;
@import "bootstrap/scss/functions";
@import "bootstrap/scss/variables";
@import "bootstrap/scss/mixins";
@import "bootstrap/scss/root";
@import "bootstrap/scss/reboot";
@import "bootstrap/scss/type";
// @import "bootstrap/scss/images";
// @import "bootstrap/scss/code";
// @import "bootstrap/scss/grid";
// @import "bootstrap/scss/tables";
// @import "bootstrap/scss/forms";
@import "bootstrap/scss/buttons";
// @import "bootstrap/scss/transitions";
@import "bootstrap/scss/dropdown";
// @import "bootstrap/scss/button-group";
// @import "bootstrap/scss/input-group";
// @import "bootstrap/scss/custom-forms";
// @import "bootstrap/scss/nav";
// @import "bootstrap/scss/navbar";
@import "bootstrap/scss/card";
// @import "bootstrap/scss/breadcrumb";
// @import "bootstrap/scss/pagination";
@import "bootstrap/scss/badge";
// @import "bootstrap/scss/jumbotron";
@import "bootstrap/scss/alert";
// @import "bootstrap/scss/progress";
// @import "bootstrap/scss/media";
@import "bootstrap/scss/list-group";
// @import "bootstrap/scss/close";
// @import "bootstrap/scss/toasts";
// @import "bootstrap/scss/modal";
// @import "bootstrap/scss/tooltip";
// @import "bootstrap/scss/popover";
// @import "bootstrap/scss/carousel";
// @import "bootstrap/scss/spinners";
@import "bootstrap/scss/utilities";
@import "bootstrap/scss/print";
@import "./global";
@import "./header";
@import "./footer";
@import "./tweet";
@import "./index";
@import "./post";
@import "./card";
@import "./grid-row";
@import "./markup";
@import "./pager";

23
server.js Normal file
View File

@ -0,0 +1,23 @@
const express = require('express');
const morgan = require('morgan');
const directory = require('serve-index');
const log = require('fancy-log');
var app = express();
app.disable('etag');
app.use(morgan('dev'));
app.use((req, res, next) => {
res.set('Cache-Control', 'no-store, no-cache, must-revalidate, private');
req.headers['if-none-match'] = 'no-match-for-this';
next();
});
app.use(express.static('dist', { etag: false, maxAge: 5 }));
app.use(directory('dist', { 'icons': true }));
app.get('/i', (req, res) => res.send(''));
app.listen(process.env.PORT || 8000, () => log('Listening on http://127.0.0.1:8000'));

1
svg/bars.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path fill="currentColor" d="M16 132h416c8.837 0 16-7.163 16-16V76c0-8.837-7.163-16-16-16H16C7.163 60 0 67.163 0 76v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z"/></svg>

After

Width:  |  Height:  |  Size: 442 B

1
svg/brands/amazon.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path fill="currentColor" d="M257.2 162.7c-48.7 1.8-169.5 15.5-169.5 117.5 0 109.5 138.3 114 183.5 43.2 6.5 10.2 35.4 37.5 45.3 46.8l56.8-56S341 288.9 341 261.4V114.3C341 89 316.5 32 228.7 32 140.7 32 94 87 94 136.3l73.5 6.8c16.3-49.5 54.2-49.5 54.2-49.5 40.7-.1 35.5 29.8 35.5 69.1zm0 86.8c0 80-84.2 68-84.2 17.2 0-47.2 50.5-56.7 84.2-57.8v40.6zm136 163.5c-7.7 10-70 67-174.5 67S34.2 408.5 9.7 379c-6.8-7.7 1-11.3 5.5-8.3C88.5 415.2 203 488.5 387.7 401c7.5-3.7 13.3 2 5.5 12zm39.8 2.2c-6.5 15.8-16 26.8-21.2 31-5.5 4.5-9.5 2.7-6.5-3.8s19.3-46.5 12.7-55c-6.5-8.3-37-4.3-48-3.2-10.8 1-13 2-14-.3-2.3-5.7 21.7-15.5 37.5-17.5 15.7-1.8 41-.8 46 5.7 3.7 5.1 0 27.1-6.5 43.1z"/></svg>

After

Width:  |  Height:  |  Size: 741 B

1
svg/brands/aws.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><path fill="currentColor" d="M180.41 203.01c-.72 22.65 10.6 32.68 10.88 39.05a8.164 8.164 0 0 1-4.1 6.27l-12.8 8.96a10.66 10.66 0 0 1-5.63 1.92c-.43-.02-8.19 1.83-20.48-25.61a78.608 78.608 0 0 1-62.61 29.45c-16.28.89-60.4-9.24-58.13-56.21-1.59-38.28 34.06-62.06 70.93-60.05 7.1.02 21.6.37 46.99 6.27v-15.62c2.69-26.46-14.7-46.99-44.81-43.91-2.4.01-19.4-.5-45.84 10.11-7.36 3.38-8.3 2.82-10.75 2.82-7.41 0-4.36-21.48-2.94-24.2 5.21-6.4 35.86-18.35 65.94-18.18a76.857 76.857 0 0 1 55.69 17.28 70.285 70.285 0 0 1 17.67 52.36l-.01 69.29zM93.99 235.4c32.43-.47 46.16-19.97 49.29-30.47 2.46-10.05 2.05-16.41 2.05-27.4-9.67-2.32-23.59-4.85-39.56-4.87-15.15-1.14-42.82 5.63-41.74 32.26-1.24 16.79 11.12 31.4 29.96 30.48zm170.92 23.05c-7.86.72-11.52-4.86-12.68-10.37l-49.8-164.65c-.97-2.78-1.61-5.65-1.92-8.58a4.61 4.61 0 0 1 3.86-5.25c.24-.04-2.13 0 22.25 0 8.78-.88 11.64 6.03 12.55 10.37l35.72 140.83 33.16-140.83c.53-3.22 2.94-11.07 12.8-10.24h17.16c2.17-.18 11.11-.5 12.68 10.37l33.42 142.63L420.98 80.1c.48-2.18 2.72-11.37 12.68-10.37h19.72c.85-.13 6.15-.81 5.25 8.58-.43 1.85 3.41-10.66-52.75 169.9-1.15 5.51-4.82 11.09-12.68 10.37h-18.69c-10.94 1.15-12.51-9.66-12.68-10.75L328.67 110.7l-32.78 136.99c-.16 1.09-1.73 11.9-12.68 10.75h-18.3zm273.48 5.63c-5.88.01-33.92-.3-57.36-12.29a12.802 12.802 0 0 1-7.81-11.91v-10.75c0-8.45 6.2-6.9 8.83-5.89 10.04 4.06 16.48 7.14 28.81 9.6 36.65 7.53 52.77-2.3 56.72-4.48 13.15-7.81 14.19-25.68 5.25-34.95-10.48-8.79-15.48-9.12-53.13-21-4.64-1.29-43.7-13.61-43.79-52.36-.61-28.24 25.05-56.18 69.52-55.95 12.67-.01 46.43 4.13 55.57 15.62 1.35 2.09 2.02 4.55 1.92 7.04v10.11c0 4.44-1.62 6.66-4.87 6.66-7.71-.86-21.39-11.17-49.16-10.75-6.89-.36-39.89.91-38.41 24.97-.43 18.96 26.61 26.07 29.7 26.89 36.46 10.97 48.65 12.79 63.12 29.58 17.14 22.25 7.9 48.3 4.35 55.44-19.08 37.49-68.42 34.44-69.26 34.42zm40.2 104.86c-70.03 51.72-171.69 79.25-258.49 79.25A469.127 469.127 0 0 1 2.83 327.46c-6.53-5.89-.77-13.96 7.17-9.47a637.37 637.37 0 0 0 316.88 84.12 630.22 630.22 0 0 0 241.59-49.55c11.78-5 21.77 7.8 10.12 16.38zm29.19-33.29c-8.96-11.52-59.28-5.38-81.81-2.69-6.79.77-7.94-5.12-1.79-9.47 40.07-28.17 105.88-20.1 113.44-10.63 7.55 9.47-2.05 75.41-39.56 106.91-5.76 4.87-11.27 2.3-8.71-4.1 8.44-21.25 27.39-68.49 18.43-80.02z"/></svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

1
svg/brands/discord.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path fill="currentColor" d="M297.216 243.2c0 15.616-11.52 28.416-26.112 28.416-14.336 0-26.112-12.8-26.112-28.416s11.52-28.416 26.112-28.416c14.592 0 26.112 12.8 26.112 28.416zm-119.552-28.416c-14.592 0-26.112 12.8-26.112 28.416s11.776 28.416 26.112 28.416c14.592 0 26.112-12.8 26.112-28.416.256-15.616-11.52-28.416-26.112-28.416zM448 52.736V512c-64.494-56.994-43.868-38.128-118.784-107.776l13.568 47.36H52.48C23.552 451.584 0 428.032 0 398.848V52.736C0 23.552 23.552 0 52.48 0h343.04C424.448 0 448 23.552 448 52.736zm-72.96 242.688c0-82.432-36.864-149.248-36.864-149.248-36.864-27.648-71.936-26.88-71.936-26.88l-3.584 4.096c43.52 13.312 63.744 32.512 63.744 32.512-60.811-33.329-132.244-33.335-191.232-7.424-9.472 4.352-15.104 7.424-15.104 7.424s21.248-20.224 67.328-33.536l-2.56-3.072s-35.072-.768-71.936 26.88c0 0-36.864 66.816-36.864 149.248 0 0 21.504 37.12 78.08 38.912 0 0 9.472-11.52 17.152-21.248-32.512-9.728-44.8-30.208-44.8-30.208 3.766 2.636 9.976 6.053 10.496 6.4 43.21 24.198 104.588 32.126 159.744 8.96 8.96-3.328 18.944-8.192 29.44-15.104 0 0-12.8 20.992-46.336 30.464 7.68 9.728 16.896 20.736 16.896 20.736 56.576-1.792 78.336-38.912 78.336-38.912z"/></svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

1
svg/brands/github.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512"><path fill="currentColor" d="M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3zm44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z"/></svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

Some files were not shown because too many files have changed in this diff Show More