add hrt.cat

This commit is contained in:
soap 2024-02-23 07:44:13 -06:00
parent 81d3e5107a
commit c9e614f013
69 changed files with 2601 additions and 0 deletions

1
hrtcat/anonymity.html Normal file

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 255 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 781 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 366 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 892 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

View file

@ -0,0 +1,497 @@
(function (jtd, undefined) {
// Event handling
jtd.addEvent = function(el, type, handler) {
if (el.attachEvent) el.attachEvent('on'+type, handler); else el.addEventListener(type, handler);
}
jtd.removeEvent = function(el, type, handler) {
if (el.detachEvent) el.detachEvent('on'+type, handler); else el.removeEventListener(type, handler);
}
jtd.onReady = function(ready) {
// in case the document is already rendered
if (document.readyState!='loading') ready();
// modern browsers
else if (document.addEventListener) document.addEventListener('DOMContentLoaded', ready);
// IE <= 8
else document.attachEvent('onreadystatechange', function(){
if (document.readyState=='complete') ready();
});
}
// Show/hide mobile menu
function initNav() {
jtd.addEvent(document, 'click', function(e){
var target = e.target;
while (target && !(target.classList && target.classList.contains('nav-list-expander'))) {
target = target.parentNode;
}
if (target) {
e.preventDefault();
target.parentNode.classList.toggle('active');
}
});
const siteNav = document.getElementById('site-nav');
const mainHeader = document.getElementById('main-header');
const menuButton = document.getElementById('menu-button');
jtd.addEvent(menuButton, 'click', function(e){
e.preventDefault();
if (menuButton.classList.toggle('nav-open')) {
siteNav.classList.add('nav-open');
mainHeader.classList.add('nav-open');
} else {
siteNav.classList.remove('nav-open');
mainHeader.classList.remove('nav-open');
}
});
}
// Site search
function initSearch() {
var request = new XMLHttpRequest();
request.open('GET', '/hrtcat/assets/js/search-data.json', true);
request.onload = function(){
if (request.status >= 200 && request.status < 400) {
var docs = JSON.parse(request.responseText);
lunr.tokenizer.separator = /[\s\-/]+/
var index = lunr(function(){
this.ref('id');
this.field('title', { boost: 200 });
this.field('content', { boost: 2 });
this.field('relUrl');
this.metadataWhitelist = ['position']
for (var i in docs) {
this.add({
id: i,
title: docs[i].title,
content: docs[i].content,
relUrl: docs[i].relUrl
});
}
});
searchLoaded(index, docs);
} else {
console.log('Error loading ajax request. Request status:' + request.status);
}
};
request.onerror = function(){
console.log('There was a connection error');
};
request.send();
}
function searchLoaded(index, docs) {
var index = index;
var docs = docs;
var searchInput = document.getElementById('search-input');
var searchResults = document.getElementById('search-results');
var mainHeader = document.getElementById('main-header');
var currentInput;
var currentSearchIndex = 0;
function showSearch() {
document.documentElement.classList.add('search-active');
}
function hideSearch() {
document.documentElement.classList.remove('search-active');
}
function update() {
currentSearchIndex++;
var input = searchInput.value;
if (input === '') {
hideSearch();
} else {
showSearch();
// scroll search input into view, workaround for iOS Safari
window.scroll(0, -1);
setTimeout(function(){ window.scroll(0, 0); }, 0);
}
if (input === currentInput) {
return;
}
currentInput = input;
searchResults.innerHTML = '';
if (input === '') {
return;
}
var results = index.query(function (query) {
var tokens = lunr.tokenizer(input)
query.term(tokens, {
boost: 10
});
query.term(tokens, {
wildcard: lunr.Query.wildcard.TRAILING
});
});
if ((results.length == 0) && (input.length > 2)) {
var tokens = lunr.tokenizer(input).filter(function(token, i) {
return token.str.length < 20;
})
if (tokens.length > 0) {
results = index.query(function (query) {
query.term(tokens, {
editDistance: Math.round(Math.sqrt(input.length / 2 - 1))
});
});
}
}
if (results.length == 0) {
var noResultsDiv = document.createElement('div');
noResultsDiv.classList.add('search-no-result');
noResultsDiv.innerText = 'No results found';
searchResults.appendChild(noResultsDiv);
} else {
var resultsList = document.createElement('ul');
resultsList.classList.add('search-results-list');
searchResults.appendChild(resultsList);
addResults(resultsList, results, 0, 10, 100, currentSearchIndex);
}
function addResults(resultsList, results, start, batchSize, batchMillis, searchIndex) {
if (searchIndex != currentSearchIndex) {
return;
}
for (var i = start; i < (start + batchSize); i++) {
if (i == results.length) {
return;
}
addResult(resultsList, results[i]);
}
setTimeout(function() {
addResults(resultsList, results, start + batchSize, batchSize, batchMillis, searchIndex);
}, batchMillis);
}
function addResult(resultsList, result) {
var doc = docs[result.ref];
var resultsListItem = document.createElement('li');
resultsListItem.classList.add('search-results-list-item');
resultsList.appendChild(resultsListItem);
var resultLink = document.createElement('a');
resultLink.classList.add('search-result');
resultLink.setAttribute('href', doc.url);
resultsListItem.appendChild(resultLink);
var resultTitle = document.createElement('div');
resultTitle.classList.add('search-result-title');
resultLink.appendChild(resultTitle);
// note: the SVG svg-doc is only loaded as a Jekyll include if site.search_enabled is true; see _includes/icons/icons.html
var resultDoc = document.createElement('div');
resultDoc.classList.add('search-result-doc');
resultDoc.innerHTML = '<svg viewBox="0 0 24 24" class="search-result-icon"><use xlink:href="#svg-doc"></use></svg>';
resultTitle.appendChild(resultDoc);
var resultDocTitle = document.createElement('div');
resultDocTitle.classList.add('search-result-doc-title');
resultDocTitle.innerHTML = doc.doc;
resultDoc.appendChild(resultDocTitle);
var resultDocOrSection = resultDocTitle;
if (doc.doc != doc.title) {
resultDoc.classList.add('search-result-doc-parent');
var resultSection = document.createElement('div');
resultSection.classList.add('search-result-section');
resultSection.innerHTML = doc.title;
resultTitle.appendChild(resultSection);
resultDocOrSection = resultSection;
}
var metadata = result.matchData.metadata;
var titlePositions = [];
var contentPositions = [];
for (var j in metadata) {
var meta = metadata[j];
if (meta.title) {
var positions = meta.title.position;
for (var k in positions) {
titlePositions.push(positions[k]);
}
}
if (meta.content) {
var positions = meta.content.position;
for (var k in positions) {
var position = positions[k];
var previewStart = position[0];
var previewEnd = position[0] + position[1];
var ellipsesBefore = true;
var ellipsesAfter = true;
for (var k = 0; k < 5; k++) {
var nextSpace = doc.content.lastIndexOf(' ', previewStart - 2);
var nextDot = doc.content.lastIndexOf('. ', previewStart - 2);
if ((nextDot >= 0) && (nextDot > nextSpace)) {
previewStart = nextDot + 1;
ellipsesBefore = false;
break;
}
if (nextSpace < 0) {
previewStart = 0;
ellipsesBefore = false;
break;
}
previewStart = nextSpace + 1;
}
for (var k = 0; k < 10; k++) {
var nextSpace = doc.content.indexOf(' ', previewEnd + 1);
var nextDot = doc.content.indexOf('. ', previewEnd + 1);
if ((nextDot >= 0) && (nextDot < nextSpace)) {
previewEnd = nextDot;
ellipsesAfter = false;
break;
}
if (nextSpace < 0) {
previewEnd = doc.content.length;
ellipsesAfter = false;
break;
}
previewEnd = nextSpace;
}
contentPositions.push({
highlight: position,
previewStart: previewStart, previewEnd: previewEnd,
ellipsesBefore: ellipsesBefore, ellipsesAfter: ellipsesAfter
});
}
}
}
if (titlePositions.length > 0) {
titlePositions.sort(function(p1, p2){ return p1[0] - p2[0] });
resultDocOrSection.innerHTML = '';
addHighlightedText(resultDocOrSection, doc.title, 0, doc.title.length, titlePositions);
}
if (contentPositions.length > 0) {
contentPositions.sort(function(p1, p2){ return p1.highlight[0] - p2.highlight[0] });
var contentPosition = contentPositions[0];
var previewPosition = {
highlight: [contentPosition.highlight],
previewStart: contentPosition.previewStart, previewEnd: contentPosition.previewEnd,
ellipsesBefore: contentPosition.ellipsesBefore, ellipsesAfter: contentPosition.ellipsesAfter
};
var previewPositions = [previewPosition];
for (var j = 1; j < contentPositions.length; j++) {
contentPosition = contentPositions[j];
if (previewPosition.previewEnd < contentPosition.previewStart) {
previewPosition = {
highlight: [contentPosition.highlight],
previewStart: contentPosition.previewStart, previewEnd: contentPosition.previewEnd,
ellipsesBefore: contentPosition.ellipsesBefore, ellipsesAfter: contentPosition.ellipsesAfter
}
previewPositions.push(previewPosition);
} else {
previewPosition.highlight.push(contentPosition.highlight);
previewPosition.previewEnd = contentPosition.previewEnd;
previewPosition.ellipsesAfter = contentPosition.ellipsesAfter;
}
}
var resultPreviews = document.createElement('div');
resultPreviews.classList.add('search-result-previews');
resultLink.appendChild(resultPreviews);
var content = doc.content;
for (var j = 0; j < Math.min(previewPositions.length, 3); j++) {
var position = previewPositions[j];
var resultPreview = document.createElement('div');
resultPreview.classList.add('search-result-preview');
resultPreviews.appendChild(resultPreview);
if (position.ellipsesBefore) {
resultPreview.appendChild(document.createTextNode('... '));
}
addHighlightedText(resultPreview, content, position.previewStart, position.previewEnd, position.highlight);
if (position.ellipsesAfter) {
resultPreview.appendChild(document.createTextNode(' ...'));
}
}
}
var resultRelUrl = document.createElement('span');
resultRelUrl.classList.add('search-result-rel-url');
resultRelUrl.innerText = doc.relUrl;
resultTitle.appendChild(resultRelUrl);
}
function addHighlightedText(parent, text, start, end, positions) {
var index = start;
for (var i in positions) {
var position = positions[i];
var span = document.createElement('span');
span.innerHTML = text.substring(index, position[0]);
parent.appendChild(span);
index = position[0] + position[1];
var highlight = document.createElement('span');
highlight.classList.add('search-result-highlight');
highlight.innerHTML = text.substring(position[0], index);
parent.appendChild(highlight);
}
var span = document.createElement('span');
span.innerHTML = text.substring(index, end);
parent.appendChild(span);
}
}
jtd.addEvent(searchInput, 'focus', function(){
setTimeout(update, 0);
});
jtd.addEvent(searchInput, 'keyup', function(e){
switch (e.keyCode) {
case 27: // When esc key is pressed, hide the results and clear the field
searchInput.value = '';
break;
case 38: // arrow up
case 40: // arrow down
case 13: // enter
e.preventDefault();
return;
}
update();
});
jtd.addEvent(searchInput, 'keydown', function(e){
switch (e.keyCode) {
case 38: // arrow up
e.preventDefault();
var active = document.querySelector('.search-result.active');
if (active) {
active.classList.remove('active');
if (active.parentElement.previousSibling) {
var previous = active.parentElement.previousSibling.querySelector('.search-result');
previous.classList.add('active');
}
}
return;
case 40: // arrow down
e.preventDefault();
var active = document.querySelector('.search-result.active');
if (active) {
if (active.parentElement.nextSibling) {
var next = active.parentElement.nextSibling.querySelector('.search-result');
active.classList.remove('active');
next.classList.add('active');
}
} else {
var next = document.querySelector('.search-result');
if (next) {
next.classList.add('active');
}
}
return;
case 13: // enter
e.preventDefault();
var active = document.querySelector('.search-result.active');
if (active) {
active.click();
} else {
var first = document.querySelector('.search-result');
if (first) {
first.click();
}
}
return;
}
});
jtd.addEvent(document, 'click', function(e){
if (e.target != searchInput) {
hideSearch();
}
});
}
// Switch theme
jtd.getTheme = function() {
var cssFileHref = document.querySelector('[rel="stylesheet"]').getAttribute('href');
return cssFileHref.substring(cssFileHref.lastIndexOf('-') + 1, cssFileHref.length - 4);
}
jtd.setTheme = function(theme) {
var cssFile = document.querySelector('[rel="stylesheet"]');
cssFile.setAttribute('href', '/hrtcat/assets/css/just-the-docs-' + theme + '.css');
}
// Scroll site-nav to ensure the link to the current page is visible
function scrollNav() {
const href = document.location.pathname;
const siteNav = document.getElementById('site-nav');
const targetLink = siteNav.querySelector('a[href="' + href + '"], a[href="' + href + '/"]');
if(targetLink){
const rect = targetLink.getBoundingClientRect();
siteNav.scrollBy(0, rect.top - 3*rect.height);
}
}
// Document ready
jtd.onReady(function(){
initNav();
initSearch();
scrollNav();
});
// Copy button on code
jtd.onReady(function(){
var codeBlocks = document.querySelectorAll('div.highlighter-rouge, div.listingblock > div.content, figure.highlight');
// note: the SVG svg-copied and svg-copy is only loaded as a Jekyll include if site.enable_copy_code_button is true; see _includes/icons/icons.html
var svgCopied = '<svg viewBox="0 0 24 24" class="copy-icon"><use xlink:href="#svg-copied"></use></svg>';
var svgCopy = '<svg viewBox="0 0 24 24" class="copy-icon"><use xlink:href="#svg-copy"></use></svg>';
codeBlocks.forEach(codeBlock => {
var copyButton = document.createElement('button');
var timeout = null;
copyButton.type = 'button';
copyButton.ariaLabel = 'Copy code to clipboard';
copyButton.innerHTML = svgCopy;
codeBlock.append(copyButton);
copyButton.addEventListener('click', function () {
if(timeout === null) {
var code = (codeBlock.querySelector('pre:not(.lineno, .highlight)') || codeBlock.querySelector('code')).innerText;
window.navigator.clipboard.writeText(code);
copyButton.innerHTML = svgCopied;
var timeoutSetting = 4000;
timeout = setTimeout(function () {
copyButton.innerHTML = svgCopy;
timeout = null;
}, timeoutSetting);
}
});
});
});
})(window.jtd = window.jtd || {});

61
hrtcat/assets/js/vendor/lunr.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,144 @@
//
// NOTE
//
// Recipes listed by weight in grams.
// They are converted to volume in the calculator.
//
//
// we want to take the needed vol of hormone + BB + BA
// then make up the remainder of the volume with oil
const RECIPES = {
'E_PAR_20': {
'hormone': 0.02,
'BB': 0.224,
'BA': 0.02,
'oil': 0.73
},
'E_PAR_40': {
'hormone': 0.04,
'BB': 0.447,
'BA': 0.02,
'oil': 0.522
},
'T_SLAYBACK_200': {
'hormone': 0.2,
'BB': 0.224,
'BA': 0.02,
'oil': 0.542
}
}
//
// Densities
//
const DENSITIES = {
'E': 1.1,
'TC': 1.1,
'TEn': 1.06,
'TU': 1.03,
'BB': 1.118,
'BA': 1.044,
'none': ''
}
//
//
//
const hormone_select = document.getElementById("hormone-select");
const recipe_select = document.getElementById("recipe-select");
const brew_vol = document.getElementById("brew-vol");
const updateHormoneDensity = () => {
const hormoneDensityCell = document.getElementById("hormone_density");
let selectValue = document.getElementById("hormone-select").value;
hormoneDensityCell.innerText = DENSITIES[selectValue];
// if everything is filled out, calculate brew amounts.
if (isFormComplete()) {
updateRecipe();
}
}
const updateRecipe = () => {
// if everything isn't filled out, break.
if (!isFormComplete()) {
return;
}
const recipeSelectValue = document.getElementById("recipe-select").value;
const hormoneDensity = DENSITIES[hormone_select.value];
//
// Get cells that will receive data
//
const hormoneMassCell = document.getElementById("hormone_mass");
const bbMassCell = document.getElementById("bb_mass");
const baMassCell = document.getElementById("ba_mass");
const hormoneVolCell = document.getElementById("hormone_vol");
const bbVolCell = document.getElementById("bb_vol");
const baVolCell = document.getElementById("ba_vol");
const oilVolCell = document.getElementById("oil_vol");
const hormoneTotalCell = document.getElementById("hormone_total");
const bbTotalCell = document.getElementById("bb_total");
const baTotalCell = document.getElementById("ba_total");
const oilTotalCell = document.getElementById("oil_total");
//
//
const hormoneMass = RECIPES[recipeSelectValue]['hormone'];
const bbMass = RECIPES[recipeSelectValue]['BB'];
const baMass = RECIPES[recipeSelectValue]['BA'];
hormoneMassCell.innerText = hormoneMass * 1000 + "mg";
bbMassCell.innerText = bbMass * 1000 + "mg";
baMassCell.innerText = baMass * 1000 + "mg";
// establish vol of BB and BA and hormone.
// make up for the remainder of the vol with oil.
// this makes up for subtle displacements due to
// density differences in hormone esters.
const hormoneIn1ml = convertMassToVol(hormoneMass, hormoneDensity)
const bbIn1ml = convertMassToVol(bbMass, DENSITIES['BB'])
const baIn1ml = convertMassToVol(baMass, DENSITIES['BA'])
const oilIn1ml = Math.round((1 - hormoneIn1ml - bbIn1ml - baIn1ml) * 100) / 100;
hormoneVolCell.innerText = hormoneIn1ml;
bbVolCell.innerText = bbIn1ml;
baVolCell.innerText = baIn1ml;
oilVolCell.innerText = oilIn1ml;
const hormoneMassInTotal = hormoneMass * brew_vol.value;
const hormoneVolInTotal = convertMassToVol(hormoneMassInTotal, hormoneDensity)
const bbVolInTotal = bbIn1ml * brew_vol.value;
const baVolInTotal = baIn1ml * brew_vol.value;
hormoneTotalCell.innerText = Math.round(hormoneMassInTotal * 100) / 100 + 'g / ' + hormoneVolInTotal + 'mL';
bbTotalCell.innerText = Math.round(bbVolInTotal * 100) / 100 + 'mL';
baTotalCell.innerText = Math.round(baVolInTotal * 100) / 100 + 'mL';
oilTotalCell.innerText = Math.round((brew_vol.value - hormoneVolInTotal - bbVolInTotal - baVolInTotal) * 100) / 100 + 'mL';
}
hormone_select.addEventListener('change', updateHormoneDensity);
recipe_select.addEventListener('change', updateRecipe);
brew_vol.addEventListener('change', updateRecipe);
const convertMassToVol = (mass, density) => {
return Math.round(mass/density * 100) / 100;
}
const isFormComplete = () => {
const hormone_select = document.getElementById("hormone-select").value;
const recipe_select = document.getElementById("recipe-select").value;
const brewVol = document.getElementById("brew-vol").value;
return (hormone_select !== 'none' &&
recipe_select !== 'none' && brewVol !== "")
}

1
hrtcat/calculator.html Normal file

File diff suppressed because one or more lines are too long

1
hrtcat/changelog.html Normal file

File diff suppressed because one or more lines are too long

41
hrtcat/contact.html Normal file

File diff suppressed because one or more lines are too long

1
hrtcat/contribute.html Normal file

File diff suppressed because one or more lines are too long

2
hrtcat/donate.html Normal file

File diff suppressed because one or more lines are too long

1
hrtcat/experiments.html Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

1
hrtcat/guide.html Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

1
hrtcat/guide/5-mix.html Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

1
hrtcat/index.html Normal file

File diff suppressed because one or more lines are too long

1
hrtcat/journal.html Normal file

File diff suppressed because one or more lines are too long

1
hrtcat/lena.html Normal file

File diff suppressed because one or more lines are too long

1
hrtcat/lidocaine.html Normal file

File diff suppressed because one or more lines are too long

1
hrtcat/media.html Normal file

File diff suppressed because one or more lines are too long

1
hrtcat/network.html Normal file

File diff suppressed because one or more lines are too long

1
hrtcat/other.html Normal file

File diff suppressed because one or more lines are too long

1
hrtcat/producers.html Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

1
hrtcat/resources.html Normal file

File diff suppressed because one or more lines are too long

1
hrtcat/start-hrt.html Normal file

File diff suppressed because one or more lines are too long

1
hrtcat/summary.html Normal file

File diff suppressed because one or more lines are too long

1
hrtcat/todo.html Normal file

File diff suppressed because one or more lines are too long

1
hrtcat/topics.html Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -25,6 +25,7 @@
<a href="diyhrt.market">diyhrt.market</a><br>
<a href="reddit/r/TransDIY/wiki.html">/r/transdiy wiki</a> (<a href="reddit/r/TransDIY/wiki/pharmacies.html">pharmacies</a>)<br>
<a href="transfemscience.org">transfemscience.org</a><br>
<a href="hrtcat">hrt.cat</a><br>
<a href="guides">guides</a><br>
<a href="other_sites">related sites</a><br>
<a href="unmaintained">archived / unmaintained sites</a><br>