mirror of
https://github.com/naturalcrit/homebrewery.git
synced 2026-01-17 08:02:44 +00:00
Merge branch 'master' into pr/1549
This commit is contained in:
13
changelog.md
13
changelog.md
@@ -6,6 +6,17 @@ h5 {
|
|||||||
|
|
||||||
# changelog
|
# changelog
|
||||||
|
|
||||||
|
### Tuesday, 17/08/2021 - v2.13.4
|
||||||
|
- Fixed user page crashing when user has untitled brew
|
||||||
|
|
||||||
|
##### G-Ambatte:
|
||||||
|
- Tweaks to user page tool tips
|
||||||
|
- Fix view counts being reset on Google Drive files
|
||||||
|
|
||||||
|
##### Gazook89 :
|
||||||
|
- New **PHB → Artist Credit** snippet
|
||||||
|
- **PRINT** snippets moved to the **Style Editor** tab
|
||||||
|
|
||||||
### Monday, 09/08/2021 - v2.13.3
|
### Monday, 09/08/2021 - v2.13.3
|
||||||
|
|
||||||
##### G-Ambatte :
|
##### G-Ambatte :
|
||||||
@@ -48,6 +59,8 @@ myStyle {color: black}
|
|||||||
- Pasting your brew into a "New" page and saving will transfer any CSS in the code fence to the Style tab.
|
- Pasting your brew into a "New" page and saving will transfer any CSS in the code fence to the Style tab.
|
||||||
- Unsaved work in the New page Style tab is now cached to your browser storage if you navigate away.
|
- Unsaved work in the New page Style tab is now cached to your browser storage if you navigate away.
|
||||||
|
|
||||||
|
\page
|
||||||
|
|
||||||
|
|
||||||
### Thursday, 10/6/2021 - v2.12.0
|
### Thursday, 10/6/2021 - v2.12.0
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ const BrewRenderer = createClass({
|
|||||||
if(this.props.renderer == 'legacy') {
|
if(this.props.renderer == 'legacy') {
|
||||||
pages = this.props.text.split('\\page');
|
pages = this.props.text.split('\\page');
|
||||||
} else {
|
} else {
|
||||||
pages = this.props.text.split(/^\\page/gm);
|
pages = this.props.text.split(/^\\page$/gm);
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -62,7 +62,7 @@ const BrewRenderer = createClass({
|
|||||||
if(this.props.renderer == 'legacy') {
|
if(this.props.renderer == 'legacy') {
|
||||||
pages = this.props.text.split('\\page');
|
pages = this.props.text.split('\\page');
|
||||||
} else {
|
} else {
|
||||||
pages = this.props.text.split(/^\\page/gm);
|
pages = this.props.text.split(/^\\page$/gm);
|
||||||
}
|
}
|
||||||
this.setState({
|
this.setState({
|
||||||
pages : pages,
|
pages : pages,
|
||||||
@@ -130,8 +130,14 @@ const BrewRenderer = createClass({
|
|||||||
renderPage : function(pageText, index){
|
renderPage : function(pageText, index){
|
||||||
if(this.props.renderer == 'legacy')
|
if(this.props.renderer == 'legacy')
|
||||||
return <div className='phb page' id={`p${index + 1}`} dangerouslySetInnerHTML={{ __html: MarkdownLegacy.render(pageText) }} key={index} />;
|
return <div className='phb page' id={`p${index + 1}`} dangerouslySetInnerHTML={{ __html: MarkdownLegacy.render(pageText) }} key={index} />;
|
||||||
else
|
else {
|
||||||
return <div className='phb3 page' id={`p${index + 1}`} dangerouslySetInnerHTML={{ __html: Markdown.render(pageText) }} key={index} />;
|
pageText += `\n\\column\n `; //Artificial column break at page end to emulate column-fill:auto (until `wide` is used, when column-fill:balance will reappear)
|
||||||
|
return (
|
||||||
|
<div className='page' id={`p${index + 1}`} key={index} >
|
||||||
|
<div className='columnWrapper' dangerouslySetInnerHTML={{ __html: Markdown.render(pageText) }} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
renderPages : function(){
|
renderPages : function(){
|
||||||
|
|||||||
@@ -68,7 +68,9 @@ const Editor = createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
handleInject : function(injectText){
|
handleInject : function(injectText){
|
||||||
const text = (this.isText() ? this.props.brew.text : this.props.brew.style);
|
let text;
|
||||||
|
if(this.isText()) text = this.props.brew.text;
|
||||||
|
if(this.isStyle()) text = this.props.brew.style ?? DEFAULT_STYLE_TEXT;
|
||||||
|
|
||||||
const lines = text.split('\n');
|
const lines = text.split('\n');
|
||||||
const cursorPos = this.refs.codeEditor.getCursorPosition();
|
const cursorPos = this.refs.codeEditor.getCursorPosition();
|
||||||
@@ -119,7 +121,7 @@ const Editor = createClass({
|
|||||||
|
|
||||||
// New Codemirror styling for V3 renderer
|
// New Codemirror styling for V3 renderer
|
||||||
if(this.props.renderer == 'V3') {
|
if(this.props.renderer == 'V3') {
|
||||||
if(line.startsWith('\\page')){
|
if(line.match(/^\\page$/)){
|
||||||
codeMirror.addLineClass(lineNumber, 'background', 'pageLine');
|
codeMirror.addLineClass(lineNumber, 'background', 'pageLine');
|
||||||
r.push(lineNumber);
|
r.push(lineNumber);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,9 +67,6 @@
|
|||||||
.button(@silver);
|
.button(@silver);
|
||||||
}
|
}
|
||||||
small{
|
small{
|
||||||
position : absolute;
|
|
||||||
bottom : -15px;
|
|
||||||
left : 0px;
|
|
||||||
font-size : 0.6em;
|
font-size : 0.6em;
|
||||||
font-style : italic;
|
font-style : italic;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,86 +2,77 @@ const _ = require('lodash');
|
|||||||
|
|
||||||
const features = [
|
const features = [
|
||||||
'Astrological Botany',
|
'Astrological Botany',
|
||||||
'Astrological Chemistry',
|
|
||||||
'Biochemical Sorcery',
|
'Biochemical Sorcery',
|
||||||
'Civil Alchemy',
|
'Civil Divination',
|
||||||
'Consecrated Biochemistry',
|
'Consecrated Augury',
|
||||||
'Demonic Anthropology',
|
'Demonic Anthropology',
|
||||||
'Divinatory Mineralogy',
|
'Divinatory Mineralogy',
|
||||||
'Genetic Banishing',
|
|
||||||
'Hermetic Geography',
|
|
||||||
'Immunological Incantations',
|
|
||||||
'Nuclear Illusionism',
|
|
||||||
'Ritual Astronomy',
|
|
||||||
'Seismological Divination',
|
|
||||||
'Spiritual Biochemistry',
|
|
||||||
'Statistical Occultism',
|
|
||||||
'Police Necromancer',
|
|
||||||
'Sixgun Poisoner',
|
|
||||||
'Pharmaceutical Gunslinger',
|
|
||||||
'Infernal Banker',
|
|
||||||
'Spell Analyst',
|
|
||||||
'Gunslinger Corruptor',
|
|
||||||
'Torque Interfacer',
|
|
||||||
'Exo Interfacer',
|
'Exo Interfacer',
|
||||||
|
'Genetic Banishing',
|
||||||
'Gunpowder Torturer',
|
'Gunpowder Torturer',
|
||||||
'Orbital Gravedigger',
|
'Gunslinger Corruptor',
|
||||||
'Phased Linguist',
|
'Hermetic Geography',
|
||||||
'Mathematical Pharmacist',
|
'Immunological Cultist',
|
||||||
'Plasma Outlaw',
|
|
||||||
'Malefic Chemist',
|
'Malefic Chemist',
|
||||||
'Police Cultist'
|
'Mathematical Pharmacy',
|
||||||
|
'Nuclear Biochemistry',
|
||||||
|
'Orbital Gravedigger',
|
||||||
|
'Pharmaceutical Outlaw',
|
||||||
|
'Phased Linguist',
|
||||||
|
'Plasma Gunslinger',
|
||||||
|
'Police Necromancer',
|
||||||
|
'Ritual Astronomy',
|
||||||
|
'Sixgun Poisoner',
|
||||||
|
'Seismological Alchemy',
|
||||||
|
'Spiritual Illusionism',
|
||||||
|
'Statistical Occultism',
|
||||||
|
'Spell Analyst',
|
||||||
|
'Torque Interfacer'
|
||||||
];
|
];
|
||||||
|
|
||||||
const classnames = ['Archivist', 'Fancyman', 'Linguist', 'Fletcher',
|
const classnames = ['Ackerman', 'Berserker-Typist', 'Concierge', 'Fishmonger',
|
||||||
'Notary', 'Berserker-Typist', 'Fishmongerer', 'Manicurist', 'Haberdasher', 'Concierge'];
|
'Haberdasher', 'Manicurist', 'Netrunner', 'Weirkeeper'];
|
||||||
|
|
||||||
const levels = ['1st', '2nd', '3rd', '4th', '5th', '6th', '7th', '8th', '9th', '10th', '11th', '12th', '13th', '14th', '15th', '16th', '17th', '18th', '19th', '20th'];
|
const levels = ['1st', '2nd', '3rd', '4th', '5th',
|
||||||
|
'6th', '7th', '8th', '9th', '10th',
|
||||||
|
'11th', '12th', '13th', '14th', '15th',
|
||||||
|
'16th', '17th', '18th', '19th', '20th'];
|
||||||
|
|
||||||
const profBonus = [2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6];
|
const profBonus = [2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6];
|
||||||
|
|
||||||
const getFeature = (level)=>{
|
const maxes = [4, 3, 3, 3, 3, 2, 2, 1, 1];
|
||||||
let res = [];
|
|
||||||
if(_.includes([4, 6, 8, 12, 14, 16, 19], level+1)){
|
const drawSlots = function(Slots, rows, padding){
|
||||||
res = ['Ability Score Improvement'];
|
let slots = Number(Slots);
|
||||||
}
|
return _.times(rows, function(i){
|
||||||
res = _.union(res, _.sampleSize(features, _.sample([0, 1, 1, 1, 1, 1])));
|
const max = maxes[i];
|
||||||
if(!res.length) return '─';
|
if(slots < 1) return _.pad('—', padding);
|
||||||
return res.join(', ');
|
const res = _.min([max, slots]);
|
||||||
|
slots -= res;
|
||||||
|
return _.pad(res.toString(), padding);
|
||||||
|
}).join(' | ');
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
full : function(){
|
full : function(classes){
|
||||||
const classname = _.sample(classnames);
|
const classname = _.sample(classnames);
|
||||||
|
|
||||||
const maxes = [4, 3, 3, 3, 3, 2, 2, 1, 1];
|
|
||||||
const drawSlots = function(Slots){
|
|
||||||
let slots = Number(Slots);
|
|
||||||
return _.times(9, function(i){
|
|
||||||
const max = maxes[i];
|
|
||||||
if(slots < 1) return '—';
|
|
||||||
const res = _.min([max, slots]);
|
|
||||||
slots -= res;
|
|
||||||
return res;
|
|
||||||
}).join(' | ');
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
let cantrips = 3;
|
let cantrips = 3;
|
||||||
let spells = 1;
|
let spells = 1;
|
||||||
let slots = 2;
|
let slots = 2;
|
||||||
return `{{classTable,wide\n##### The ${classname}\n` +
|
return `{{${classes}\n##### The ${classname}\n` +
|
||||||
`| Level | Proficiency | Features | Cantrips | Spells | --- Spell Slots Per Level --- |||||||||\n`+
|
`| Level | Proficiency | Features | Cantrips | Spells | --- Spell Slots Per Spell Level ---|||||||||\n`+
|
||||||
`| ^| Bonus ^| ^| Known ^| Known ^| 1st | 2nd | 3rd | 4th | 5th | 6th | 7th | 8th | 9th |\n`+
|
`| ^| Bonus ^| ^| Known ^| Known ^|1st |2nd |3rd |4th |5th |6th |7th |8th |9th |\n`+
|
||||||
`|:-----:|:-----------:|:---------|:--------:|:------:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|\n${
|
`|:-----:|:-----------:|:-------------|:--------:|:------:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|\n${
|
||||||
_.map(levels, function(levelName, level){
|
_.map(levels, function(levelName, level){
|
||||||
const res = [
|
const res = [
|
||||||
levelName,
|
_.pad(levelName, 5),
|
||||||
`+${profBonus[level]}`,
|
_.pad(`+${profBonus[level]}`, 2),
|
||||||
getFeature(level),
|
_.padEnd(_.sample(features), 21),
|
||||||
cantrips,
|
_.pad(cantrips.toString(), 8),
|
||||||
spells,
|
_.pad(spells.toString(), 6),
|
||||||
drawSlots(slots)
|
drawSlots(slots, 9, 2),
|
||||||
].join(' | ');
|
].join(' | ');
|
||||||
|
|
||||||
cantrips += _.random(0, 1);
|
cantrips += _.random(0, 1);
|
||||||
@@ -92,24 +83,50 @@ module.exports = {
|
|||||||
}).join('\n')}\n}}\n\n`;
|
}).join('\n')}\n}}\n\n`;
|
||||||
},
|
},
|
||||||
|
|
||||||
half : function(){
|
half : function(classes){
|
||||||
const classname = _.sample(classnames);
|
const classname = _.sample(classnames);
|
||||||
|
|
||||||
let featureScore = 1;
|
let featureScore = 1;
|
||||||
return `<div class='classTable'>\n##### The ${classname}\n` +
|
return `{{${classes}\n##### The ${classname}\n` +
|
||||||
`| Level | Proficiency Bonus | Features | ${_.sample(features)}|\n` +
|
`| Level | Proficiency Bonus | Features | ${_.pad(_.sample(features), 21)} |\n` +
|
||||||
`|:---:|:---:|:---|:---:|\n${
|
`|:-----:|:-----------------:|:---------|:---------------------:|\n${
|
||||||
_.map(levels, function(levelName, level){
|
_.map(levels, function(levelName, level){
|
||||||
const res = [
|
const res = [
|
||||||
levelName,
|
_.pad(levelName, 5),
|
||||||
`+${profBonus[level]}`,
|
_.pad(`+${profBonus[level]}`, 2),
|
||||||
getFeature(level),
|
_.padEnd(_.sample(features), 23),
|
||||||
`+${featureScore}`
|
_.pad(`+${featureScore}`, 21),
|
||||||
].join(' | ');
|
].join(' | ');
|
||||||
|
|
||||||
featureScore += _.random(0, 1);
|
featureScore += _.random(0, 1);
|
||||||
|
|
||||||
return `| ${res} |`;
|
return `| ${res} |`;
|
||||||
}).join('\n')}\n</div>\n\n`;
|
}).join('\n')}\n}}\n\n`;
|
||||||
|
},
|
||||||
|
|
||||||
|
third : function(classes){
|
||||||
|
const classname = _.sample(classnames);
|
||||||
|
|
||||||
|
let cantrips = 3;
|
||||||
|
let spells = 1;
|
||||||
|
let slots = 2;
|
||||||
|
return `{{${classes}\n##### ${classname} Spellcasting\n` +
|
||||||
|
`| Class | Cantrips | Spells |--- Spells Slots per Spell Level ---||||\n` +
|
||||||
|
`| Level ^| Known ^| Known ^| 1st | 2nd | 3rd | 4th |\n` +
|
||||||
|
`|:------:|:--------:|:-------:|:-------:|:-------:|:-------:|:-------:|\n${
|
||||||
|
_.map(levels, function(levelName, level){
|
||||||
|
const res = [
|
||||||
|
_.pad(levelName, 6),
|
||||||
|
_.pad(cantrips.toString(), 8),
|
||||||
|
_.pad(spells.toString(), 7),
|
||||||
|
drawSlots(slots, 4, 7),
|
||||||
|
].join(' | ');
|
||||||
|
|
||||||
|
cantrips += _.random(0, 1);
|
||||||
|
spells += _.random(0, 1);
|
||||||
|
slots += _.random(0, 1);
|
||||||
|
|
||||||
|
return `| ${res} |`;
|
||||||
|
}).join('\n')}\n}}\n\n`;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -44,8 +44,8 @@ module.exports = [
|
|||||||
{{wide
|
{{wide
|
||||||
Everything in here will be extra wide. Tables, text, everything!
|
Everything in here will be extra wide. Tables, text, everything!
|
||||||
Beware though, CSS columns can behave a bit weird sometimes. You may
|
Beware though, CSS columns can behave a bit weird sometimes. You may
|
||||||
have to rely on the automatic column-break rather than \`\column\` if
|
have to manually place column breaks with \`\column\` to make the
|
||||||
you mix columns and wide blocks on the same page.
|
surrounding text flow with this wide block the way you want.
|
||||||
}}
|
}}
|
||||||
\n`
|
\n`
|
||||||
},
|
},
|
||||||
@@ -262,12 +262,32 @@ module.exports = [
|
|||||||
{
|
{
|
||||||
name : 'Class Table',
|
name : 'Class Table',
|
||||||
icon : 'fas fa-table',
|
icon : 'fas fa-table',
|
||||||
gen : ClassTableGen.full,
|
gen : ClassTableGen.full('classTable,frame,wide'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name : 'Half Class Table',
|
name : 'Class Table (unframed)',
|
||||||
|
icon : 'fas fa-border-none',
|
||||||
|
gen : ClassTableGen.full('classTable,wide'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name : '1/2 Class Table',
|
||||||
icon : 'fas fa-list-alt',
|
icon : 'fas fa-list-alt',
|
||||||
gen : ClassTableGen.half,
|
gen : ClassTableGen.half('classTable,frame'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name : '1/2 Class Table (unframed)',
|
||||||
|
icon : 'fas fa-border-none',
|
||||||
|
gen : ClassTableGen.half('classTable'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name : '1/3 Class Table',
|
||||||
|
icon : 'fas fa-border-all',
|
||||||
|
gen : ClassTableGen.third('classTable,frame'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name : '1/3 Class Table (unframed)',
|
||||||
|
icon : 'fas fa-border-none',
|
||||||
|
gen : ClassTableGen.third('classTable'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name : 'Table',
|
name : 'Table',
|
||||||
|
|||||||
@@ -305,7 +305,7 @@ module.exports = [
|
|||||||
name : 'Ink Friendly',
|
name : 'Ink Friendly',
|
||||||
icon : 'fas fa-tint',
|
icon : 'fas fa-tint',
|
||||||
gen : dedent`
|
gen : dedent`
|
||||||
/* Ink Friendly */',
|
/* Ink Friendly */
|
||||||
.phb, .phb blockquote, .phb hr+blockquote {
|
.phb, .phb blockquote, .phb hr+blockquote {
|
||||||
background : white;
|
background : white;
|
||||||
box-shadow : 0px 0px 3px;
|
box-shadow : 0px 0px 3px;
|
||||||
|
|||||||
@@ -196,11 +196,14 @@ const EditPage = createClass({
|
|||||||
|
|
||||||
const transfer = this.state.saveGoogle == _.isNil(this.state.brew.googleId);
|
const transfer = this.state.saveGoogle == _.isNil(this.state.brew.googleId);
|
||||||
|
|
||||||
|
const brew = this.state.brew;
|
||||||
|
brew.pageCount = ((brew.renderer=='legacy' ? brew.text.match(/\\page/g) : brew.text.match(/^\\page$/gm)) || []).length + 1;
|
||||||
|
|
||||||
if(this.state.saveGoogle) {
|
if(this.state.saveGoogle) {
|
||||||
if(transfer) {
|
if(transfer) {
|
||||||
const res = await request
|
const res = await request
|
||||||
.post('/api/newGoogle/')
|
.post('/api/newGoogle/')
|
||||||
.send(this.state.brew)
|
.send(brew)
|
||||||
.catch((err)=>{
|
.catch((err)=>{
|
||||||
console.log(err.status === 401
|
console.log(err.status === 401
|
||||||
? 'Not signed in!'
|
? 'Not signed in!'
|
||||||
@@ -211,7 +214,7 @@ const EditPage = createClass({
|
|||||||
if(!res) { return; }
|
if(!res) { return; }
|
||||||
|
|
||||||
console.log('Deleting Local Copy');
|
console.log('Deleting Local Copy');
|
||||||
await request.delete(`/api/${this.state.brew.editId}`)
|
await request.delete(`/api/${brew.editId}`)
|
||||||
.send()
|
.send()
|
||||||
.catch((err)=>{
|
.catch((err)=>{
|
||||||
console.log('Error deleting Local Copy');
|
console.log('Error deleting Local Copy');
|
||||||
@@ -221,8 +224,8 @@ const EditPage = createClass({
|
|||||||
history.replaceState(null, null, `/edit/${this.savedBrew.googleId}${this.savedBrew.editId}`); //update URL to match doc ID
|
history.replaceState(null, null, `/edit/${this.savedBrew.googleId}${this.savedBrew.editId}`); //update URL to match doc ID
|
||||||
} else {
|
} else {
|
||||||
const res = await request
|
const res = await request
|
||||||
.put(`/api/updateGoogle/${this.state.brew.editId}`)
|
.put(`/api/updateGoogle/${brew.editId}`)
|
||||||
.send(this.state.brew)
|
.send(brew)
|
||||||
.catch((err)=>{
|
.catch((err)=>{
|
||||||
console.log(err.status === 401
|
console.log(err.status === 401
|
||||||
? 'Not signed in!'
|
? 'Not signed in!'
|
||||||
@@ -236,14 +239,14 @@ const EditPage = createClass({
|
|||||||
} else {
|
} else {
|
||||||
if(transfer) {
|
if(transfer) {
|
||||||
const res = await request.post('/api')
|
const res = await request.post('/api')
|
||||||
.send(this.state.brew)
|
.send(brew)
|
||||||
.catch((err)=>{
|
.catch((err)=>{
|
||||||
console.log('Error creating Local Copy');
|
console.log('Error creating Local Copy');
|
||||||
this.setState({ errors: err });
|
this.setState({ errors: err });
|
||||||
return;
|
return;
|
||||||
});
|
});
|
||||||
|
|
||||||
await request.get(`/api/removeGoogle/${this.state.brew.googleId}${this.state.brew.editId}`)
|
await request.get(`/api/removeGoogle/${brew.googleId}${brew.editId}`)
|
||||||
.send()
|
.send()
|
||||||
.catch((err)=>{
|
.catch((err)=>{
|
||||||
console.log('Error Deleting Google Brew');
|
console.log('Error Deleting Google Brew');
|
||||||
@@ -253,8 +256,8 @@ const EditPage = createClass({
|
|||||||
history.replaceState(null, null, `/edit/${this.savedBrew.editId}`); //update URL to match doc ID
|
history.replaceState(null, null, `/edit/${this.savedBrew.editId}`); //update URL to match doc ID
|
||||||
} else {
|
} else {
|
||||||
const res = await request
|
const res = await request
|
||||||
.put(`/api/update/${this.state.brew.editId}`)
|
.put(`/api/update/${brew.editId}`)
|
||||||
.send(this.state.brew)
|
.send(brew)
|
||||||
.catch((err)=>{
|
.catch((err)=>{
|
||||||
console.log('Error Updating Local Brew');
|
console.log('Error Updating Local Brew');
|
||||||
this.setState({ errors: err });
|
this.setState({ errors: err });
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.page {
|
.page {
|
||||||
padding-bottom : 1.6cm;
|
padding-bottom : 1.3cm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -37,7 +37,10 @@ After clicking the "Print" item in the navbar a new page will open and a print d
|
|||||||
|
|
||||||
If you want to save ink or have a monochrome printer, add the {{fas,fa-tint}} **Ink Friendly** snippet to your brew before you print
|
If you want to save ink or have a monochrome printer, add the {{fas,fa-tint}} **Ink Friendly** snippet to your brew before you print
|
||||||
|
|
||||||
|
<img src='https://i.imgur.com/hMna6G0.png' style='position:absolute;bottom:50px;left:120px;width:180px' />
|
||||||
|
|
||||||
|
<div class='pageNumber'>1</div>
|
||||||
|
<div class='footnote'>PART 1 | FANCINESS</div>
|
||||||
|
|
||||||
\column
|
\column
|
||||||
|
|
||||||
@@ -75,15 +78,6 @@ If you'd like to credit The Homebrewery in your brew, I'd be flattered! Just ref
|
|||||||
If you are looking for more 5e Homebrew resources check out [r/UnearthedArcana](https://www.reddit.com/r/UnearthedArcana/) and their list of useful resources [here](https://www.reddit.com/r/UnearthedArcana/comments/3uwxx9/resources_open_to_the_community/).
|
If you are looking for more 5e Homebrew resources check out [r/UnearthedArcana](https://www.reddit.com/r/UnearthedArcana/) and their list of useful resources [here](https://www.reddit.com/r/UnearthedArcana/comments/3uwxx9/resources_open_to_the_community/).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<img src='https://i.imgur.com/hMna6G0.png' style='position:absolute;bottom:50px;left:120px;width:180px' />
|
|
||||||
|
|
||||||
<div class='pageNumber'>1</div>
|
|
||||||
<div class='footnote'>PART 1 | FANCINESS</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
\page
|
\page
|
||||||
|
|
||||||
## Markdown+
|
## Markdown+
|
||||||
|
|||||||
@@ -161,6 +161,8 @@ const NewPage = createClass({
|
|||||||
brew.text = brew.text.slice(index + 5);
|
brew.text = brew.text.slice(index + 5);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
brew.pageCount=((brew.renderer=='legacy' ? brew.text.match(/\\page/g) : brew.text.match(/^\\page$/gm)) || []).length + 1;
|
||||||
|
|
||||||
if(this.state.saveGoogle) {
|
if(this.state.saveGoogle) {
|
||||||
const res = await request
|
const res = await request
|
||||||
.post('/api/newGoogle/')
|
.post('/api/newGoogle/')
|
||||||
|
|||||||
@@ -37,20 +37,21 @@ const PrintPage = createClass({
|
|||||||
|
|
||||||
renderPages : function(){
|
renderPages : function(){
|
||||||
if(this.props.brew.renderer == 'legacy') {
|
if(this.props.brew.renderer == 'legacy') {
|
||||||
return _.map(this.state.brewText.split('\\page'), (page, index)=>{
|
return _.map(this.state.brewText.split('\\page'), (pageText, index)=>{
|
||||||
return <div
|
return <div
|
||||||
className='phb page'
|
className='phb page'
|
||||||
id={`p${index + 1}`}
|
id={`p${index + 1}`}
|
||||||
dangerouslySetInnerHTML={{ __html: MarkdownLegacy.render(page) }}
|
dangerouslySetInnerHTML={{ __html: MarkdownLegacy.render(pageText) }}
|
||||||
key={index} />;
|
key={index} />;
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
return _.map(this.state.brewText.split(/^\\page/gm), (page, index)=>{
|
return _.map(this.state.brewText.split(/^\\page$/gm), (pageText, index)=>{
|
||||||
return <div
|
pageText += `\n\\column\n `; //Artificial column break at page end to emulate column-fill:auto (until `wide` is used, when column-fill:balance will reappear)
|
||||||
className='phb3 page'
|
return (
|
||||||
id={`p${index + 1}`}
|
<div className='page' id={`p${index + 1}`} key={index} >
|
||||||
dangerouslySetInnerHTML={{ __html: Markdown.render(page) }}
|
<div className='columnWrapper' dangerouslySetInnerHTML={{ __html: Markdown.render(pageText) }} />
|
||||||
key={index} />;
|
</div>
|
||||||
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ const BrewItem = createClass({
|
|||||||
if(!this.props.brew.editId) return;
|
if(!this.props.brew.editId) return;
|
||||||
|
|
||||||
return <a onClick={this.deleteBrew}>
|
return <a onClick={this.deleteBrew}>
|
||||||
<i className='fas fa-trash-alt' />
|
<i className='fas fa-trash-alt' title='Delete' />
|
||||||
</a>;
|
</a>;
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -61,7 +61,7 @@ const BrewItem = createClass({
|
|||||||
}
|
}
|
||||||
|
|
||||||
return <a href={`/edit/${editLink}`} target='_blank' rel='noopener noreferrer'>
|
return <a href={`/edit/${editLink}`} target='_blank' rel='noopener noreferrer'>
|
||||||
<i className='fas fa-pencil-alt' />
|
<i className='fas fa-pencil-alt' title='Edit' />
|
||||||
</a>;
|
</a>;
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -74,7 +74,7 @@ const BrewItem = createClass({
|
|||||||
}
|
}
|
||||||
|
|
||||||
return <a href={`/share/${shareLink}`} target='_blank' rel='noopener noreferrer'>
|
return <a href={`/share/${shareLink}`} target='_blank' rel='noopener noreferrer'>
|
||||||
<i className='fas fa-share-alt' />
|
<i className='fas fa-share-alt' title='Share' />
|
||||||
</a>;
|
</a>;
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -87,7 +87,7 @@ const BrewItem = createClass({
|
|||||||
}
|
}
|
||||||
|
|
||||||
return <a href={`/download/${shareLink}`}>
|
return <a href={`/download/${shareLink}`}>
|
||||||
<i className='fas fa-download' />
|
<i className='fas fa-download' title='Download' />
|
||||||
</a>;
|
</a>;
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -99,31 +99,33 @@ const BrewItem = createClass({
|
|||||||
</span>;
|
</span>;
|
||||||
},
|
},
|
||||||
|
|
||||||
getTooltipData : function(){
|
|
||||||
const dateFormatString = 'YYYY-MM-DD HH:mm:ss';
|
|
||||||
let outputString = `Created: ${this.props.brew.createdAt ? moment(this.props.brew.createdAt).local().format(dateFormatString) : 'UNKNOWN'}\n`;
|
|
||||||
outputString += `Last updated: ${this.props.brew.updatedAt ? moment(this.props.brew.updatedAt).local().format(dateFormatString) : 'UNKNOWN'}`;
|
|
||||||
return outputString;
|
|
||||||
},
|
|
||||||
|
|
||||||
render : function(){
|
render : function(){
|
||||||
const brew = this.props.brew;
|
const brew = this.props.brew;
|
||||||
return <div className='brewItem' title={this.getTooltipData()}>
|
const dateFormatString = 'YYYY-MM-DD HH:mm:ss';
|
||||||
|
|
||||||
|
return <div className='brewItem'>
|
||||||
|
<div className='text'>
|
||||||
<h2>{brew.title}</h2>
|
<h2>{brew.title}</h2>
|
||||||
<p className='description'>{brew.description}</p>
|
<p className='description'>{brew.description}</p>
|
||||||
|
</div>
|
||||||
<hr />
|
<hr />
|
||||||
|
|
||||||
<div className='info'>
|
<div className='info'>
|
||||||
<span>
|
<span title={`Last viewed: ${moment(brew.lastViewed).local().format(dateFormatString)}`}>
|
||||||
<i className='fas fa-user' /> {brew.authors.join(', ')}
|
<i className='fas fa-eye'/> {brew.views}
|
||||||
</span>
|
</span>
|
||||||
<span>
|
{brew.pageCount &&
|
||||||
<i className='fas fa-eye' /> {brew.views}
|
<span title={`Page count: ${brew.pageCount}`}>
|
||||||
|
<i className='far fa-file' /> {brew.pageCount}
|
||||||
</span>
|
</span>
|
||||||
|
}
|
||||||
<span>
|
<span>
|
||||||
<i className='fas fa-sync-alt' /> {moment(brew.updatedAt).fromNow()}
|
<i className='fas fa-sync-alt' /> {moment(brew.updatedAt).fromNow()}
|
||||||
</span>
|
</span>
|
||||||
{this.renderGoogleDriveIcon()}
|
{this.renderGoogleDriveIcon()}
|
||||||
|
<br />
|
||||||
|
<span title={`Authors:\n${brew.authors.join('\n')}`}>
|
||||||
|
<i className='fas fa-user'/> {brew.authors.join(', ')}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className='links'>
|
<div className='links'>
|
||||||
|
|||||||
@@ -10,24 +10,28 @@
|
|||||||
min-height : 105px;
|
min-height : 105px;
|
||||||
margin-right : 15px;
|
margin-right : 15px;
|
||||||
margin-bottom : 15px;
|
margin-bottom : 15px;
|
||||||
padding : 5px 15px 5px 8px;
|
padding : 5px 15px 2px 8px;
|
||||||
padding-right : 15px;
|
padding-right : 15px;
|
||||||
border : 1px solid #c9ad6a;
|
border : 1px solid #c9ad6a;
|
||||||
border-radius : 5px;
|
border-radius : 5px;
|
||||||
-webkit-column-break-inside : avoid;
|
-webkit-column-break-inside : avoid;
|
||||||
page-break-inside : avoid;
|
page-break-inside : avoid;
|
||||||
break-inside : avoid;
|
break-inside : avoid;
|
||||||
|
.text {
|
||||||
|
min-height : 54px;
|
||||||
h4{
|
h4{
|
||||||
margin-bottom : 5px;
|
margin-bottom : 5px;
|
||||||
font-size : 2.2em;
|
font-size : 2.2em;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
.info{
|
.info{
|
||||||
position: absolute;
|
position: initial;
|
||||||
bottom: 0px;
|
bottom: 2px;
|
||||||
margin-bottom: 4px;
|
margin-bottom: 4px;
|
||||||
font-family : ScalySans;
|
font-family : ScalySans;
|
||||||
font-size : 1.2em;
|
font-size : 1.2em;
|
||||||
&>span{
|
&>span{
|
||||||
|
display : float;
|
||||||
margin-right : 12px;
|
margin-right : 12px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,8 @@ const UserPage = createClass({
|
|||||||
getInitialState : function() {
|
getInitialState : function() {
|
||||||
return {
|
return {
|
||||||
sortType : 'alpha',
|
sortType : 'alpha',
|
||||||
sortDir : 'asc'
|
sortDir : 'asc',
|
||||||
|
filterString : ''
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
getUsernameWithS : function() {
|
getUsernameWithS : function() {
|
||||||
@@ -44,7 +45,7 @@ const UserPage = createClass({
|
|||||||
renderBrews : function(brews){
|
renderBrews : function(brews){
|
||||||
if(!brews || !brews.length) return <div className='noBrews'>No Brews.</div>;
|
if(!brews || !brews.length) return <div className='noBrews'>No Brews.</div>;
|
||||||
|
|
||||||
const sortedBrews = this.sortBrews(brews, this.state.sortType);
|
const sortedBrews = this.sortBrews(brews);
|
||||||
|
|
||||||
return _.map(sortedBrews, (brew, idx)=>{
|
return _.map(sortedBrews, (brew, idx)=>{
|
||||||
return <BrewItem brew={brew} key={idx}/>;
|
return <BrewItem brew={brew} key={idx}/>;
|
||||||
@@ -52,6 +53,7 @@ const UserPage = createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
sortBrewOrder : function(brew){
|
sortBrewOrder : function(brew){
|
||||||
|
if(!brew.title){brew.title = 'No Title';}
|
||||||
const mapping = {
|
const mapping = {
|
||||||
'alpha' : _.deburr(brew.title.toLowerCase()),
|
'alpha' : _.deburr(brew.title.toLowerCase()),
|
||||||
'created' : moment(brew.createdAt).format(),
|
'created' : moment(brew.createdAt).format(),
|
||||||
@@ -90,6 +92,26 @@ const UserPage = createClass({
|
|||||||
</td>;
|
</td>;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
handleFilterTextChange : function(e){
|
||||||
|
this.setState({
|
||||||
|
filterString : e.target.value
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
},
|
||||||
|
|
||||||
|
renderFilterOption : function(){
|
||||||
|
return <td>
|
||||||
|
<label>
|
||||||
|
<i className='fas fa-search'></i>
|
||||||
|
<input
|
||||||
|
type='search'
|
||||||
|
placeholder='search title/description'
|
||||||
|
onChange={this.handleFilterTextChange}
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
</td>;
|
||||||
|
},
|
||||||
|
|
||||||
renderSortOptions : function(){
|
renderSortOptions : function(){
|
||||||
return <div className='sort-container'>
|
return <div className='sort-container'>
|
||||||
<table>
|
<table>
|
||||||
@@ -114,6 +136,7 @@ const UserPage = createClass({
|
|||||||
{`${(this.state.sortDir == 'asc' ? '\u25B2 ASC' : '\u25BC DESC')}`}
|
{`${(this.state.sortDir == 'asc' ? '\u25B2 ASC' : '\u25BC DESC')}`}
|
||||||
</button>
|
</button>
|
||||||
</td>
|
</td>
|
||||||
|
{this.renderFilterOption()}
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
@@ -121,7 +144,12 @@ const UserPage = createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
getSortedBrews : function(){
|
getSortedBrews : function(){
|
||||||
return _.groupBy(this.props.brews, (brew)=>{
|
const testString = _.deburr(this.state.filterString).toLowerCase();
|
||||||
|
const brewCollection = this.state.filterString ? _.filter(this.props.brews, (brew)=>{
|
||||||
|
return (_.deburr(brew.title).toLowerCase().includes(testString)) ||
|
||||||
|
(_.deburr(brew.description).toLowerCase().includes(testString));
|
||||||
|
}) : this.props.brews;
|
||||||
|
return _.groupBy(brewCollection, (brew)=>{
|
||||||
return (brew.published ? 'published' : 'private');
|
return (brew.published ? 'published' : 'private');
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -34,8 +34,9 @@
|
|||||||
font-family : 'Open Sans', sans-serif;
|
font-family : 'Open Sans', sans-serif;
|
||||||
position : fixed;
|
position : fixed;
|
||||||
top : 35px;
|
top : 35px;
|
||||||
|
left : calc(50vw - 408px);
|
||||||
border : 2px solid #58180D;
|
border : 2px solid #58180D;
|
||||||
width : 675px;
|
width : 800px;
|
||||||
background-color : #EEE5CE;
|
background-color : #EEE5CE;
|
||||||
padding : 2px;
|
padding : 2px;
|
||||||
text-align : center;
|
text-align : center;
|
||||||
@@ -52,6 +53,9 @@
|
|||||||
vertical-align : middle;
|
vertical-align : middle;
|
||||||
tbody tr{
|
tbody tr{
|
||||||
background-color: transparent !important;
|
background-color: transparent !important;
|
||||||
|
i{
|
||||||
|
padding-right : 5px
|
||||||
|
}
|
||||||
button{
|
button{
|
||||||
background-color : transparent;
|
background-color : transparent;
|
||||||
color : #58180D;
|
color : #58180D;
|
||||||
|
|||||||
290
package-lock.json
generated
290
package-lock.json
generated
@@ -1,11 +1,11 @@
|
|||||||
{
|
{
|
||||||
"name": "homebrewery",
|
"name": "homebrewery",
|
||||||
"version": "2.13.3",
|
"version": "2.13.4",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"version": "2.13.3",
|
"version": "2.13.4",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
"@babel/preset-react": "^7.14.5",
|
"@babel/preset-react": "^7.14.5",
|
||||||
"body-parser": "^1.19.0",
|
"body-parser": "^1.19.0",
|
||||||
"classnames": "^2.3.1",
|
"classnames": "^2.3.1",
|
||||||
"codemirror": "^5.62.2",
|
"codemirror": "^5.62.3",
|
||||||
"cookie-parser": "^1.4.5",
|
"cookie-parser": "^1.4.5",
|
||||||
"create-react-class": "^15.7.0",
|
"create-react-class": "^15.7.0",
|
||||||
"dedent-tabs": "^0.9.0",
|
"dedent-tabs": "^0.9.0",
|
||||||
@@ -27,7 +27,7 @@
|
|||||||
"jwt-simple": "^0.5.6",
|
"jwt-simple": "^0.5.6",
|
||||||
"less": "^3.13.1",
|
"less": "^3.13.1",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"marked": "2.1.3",
|
"marked": "3.0.2",
|
||||||
"markedLegacy": "npm:marked@^0.3.19",
|
"markedLegacy": "npm:marked@^0.3.19",
|
||||||
"moment": "^2.29.1",
|
"moment": "^2.29.1",
|
||||||
"mongoose": "^5.13.7",
|
"mongoose": "^5.13.7",
|
||||||
@@ -38,14 +38,14 @@
|
|||||||
"react": "^16.14.0",
|
"react": "^16.14.0",
|
||||||
"react-dom": "^16.14.0",
|
"react-dom": "^16.14.0",
|
||||||
"react-frame-component": "4.1.3",
|
"react-frame-component": "4.1.3",
|
||||||
"react-router-dom": "5.2.0",
|
"react-router-dom": "5.2.1",
|
||||||
"sanitize-filename": "1.6.3",
|
"sanitize-filename": "1.6.3",
|
||||||
"superagent": "^6.1.0",
|
"superagent": "^6.1.0",
|
||||||
"vitreum": "git+https://git@github.com/calculuschild/vitreum.git"
|
"vitreum": "git+https://git@github.com/calculuschild/vitreum.git"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"eslint": "^7.32.0",
|
"eslint": "^7.32.0",
|
||||||
"eslint-plugin-react": "^7.24.0",
|
"eslint-plugin-react": "^7.25.1",
|
||||||
"pico-check": "^2.1.3"
|
"pico-check": "^2.1.3"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -1665,11 +1665,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/runtime": {
|
"node_modules/@babel/runtime": {
|
||||||
"version": "7.9.6",
|
"version": "7.15.3",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.9.6.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.15.3.tgz",
|
||||||
"integrity": "sha512-64AF1xY3OAkFHqOb9s4jpgk1Mm5vDZ4L3acHvAml+53nO1XbXLuDodsVpO4OIUsmemlUHMxNdYMNJmsvOwLrvQ==",
|
"integrity": "sha512-OvwMLqNXkCXSz1kSm58sEsNuhqOx/fKpnUnKnFB5v8uDda5bLNEHNgKPvhDN6IU0LDcnHQ90LlJ0Q6jnyBSIBA==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"regenerator-runtime": "^0.13.4"
|
"regenerator-runtime": "^0.13.4"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.9.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/runtime/node_modules/regenerator-runtime": {
|
"node_modules/@babel/runtime/node_modules/regenerator-runtime": {
|
||||||
@@ -3126,9 +3129,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/codemirror": {
|
"node_modules/codemirror": {
|
||||||
"version": "5.62.2",
|
"version": "5.62.3",
|
||||||
"resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.62.2.tgz",
|
"resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.62.3.tgz",
|
||||||
"integrity": "sha512-tVFMUa4J3Q8JUd1KL9yQzQB0/BJt7ZYZujZmTPgo/54Lpuq3ez4C8x/ATUY/wv7b7X3AUq8o3Xd+2C5ZrCGWHw=="
|
"integrity": "sha512-zZAyOfN8TU67ngqrxhOgtkSAGV9jSpN1snbl8elPtnh9Z5A11daR405+dhLzLnuXrwX0WCShWlybxPN3QC/9Pg=="
|
||||||
},
|
},
|
||||||
"node_modules/collection-visit": {
|
"node_modules/collection-visit": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
@@ -3856,14 +3859,15 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/eslint-plugin-react": {
|
"node_modules/eslint-plugin-react": {
|
||||||
"version": "7.24.0",
|
"version": "7.25.1",
|
||||||
"resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.24.0.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.25.1.tgz",
|
||||||
"integrity": "sha512-KJJIx2SYx7PBx3ONe/mEeMz4YE0Lcr7feJTCMyyKb/341NcjuAgim3Acgan89GfPv7nxXK2+0slu0CWXYM4x+Q==",
|
"integrity": "sha512-P4j9K1dHoFXxDNP05AtixcJEvIT6ht8FhYKsrkY0MPCPaUMYijhpWwNiRDZVtA8KFuZOkGSeft6QwH8KuVpJug==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"array-includes": "^3.1.3",
|
"array-includes": "^3.1.3",
|
||||||
"array.prototype.flatmap": "^1.2.4",
|
"array.prototype.flatmap": "^1.2.4",
|
||||||
"doctrine": "^2.1.0",
|
"doctrine": "^2.1.0",
|
||||||
|
"estraverse": "^5.2.0",
|
||||||
"has": "^1.0.3",
|
"has": "^1.0.3",
|
||||||
"jsx-ast-utils": "^2.4.1 || ^3.0.0",
|
"jsx-ast-utils": "^2.4.1 || ^3.0.0",
|
||||||
"minimatch": "^3.0.4",
|
"minimatch": "^3.0.4",
|
||||||
@@ -3893,6 +3897,15 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/eslint-plugin-react/node_modules/estraverse": {
|
||||||
|
"version": "5.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz",
|
||||||
|
"integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/eslint-plugin-react/node_modules/resolve": {
|
"node_modules/eslint-plugin-react/node_modules/resolve": {
|
||||||
"version": "2.0.0-next.3",
|
"version": "2.0.0-next.3",
|
||||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.3.tgz",
|
"resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.3.tgz",
|
||||||
@@ -5961,14 +5974,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/marked": {
|
"node_modules/marked": {
|
||||||
"version": "2.1.3",
|
"version": "3.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/marked/-/marked-2.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/marked/-/marked-3.0.2.tgz",
|
||||||
"integrity": "sha512-/Q+7MGzaETqifOMWYEA7HVMaZb4XbcRfaOzcSsHZEith83KGlvaSG33u0SKu89Mj5h+T8V2hM+8O45Qc5XTgwA==",
|
"integrity": "sha512-TMJQQ79Z0e3rJYazY0tIoMsFzteUGw9fB3FD+gzuIT3zLuG9L9ckIvUfF51apdJkcqc208jJN2KbtPbOvXtbjA==",
|
||||||
"bin": {
|
"bin": {
|
||||||
"marked": "bin/marked"
|
"marked": "bin/marked"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 10"
|
"node": ">= 12"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/markedLegacy": {
|
"node_modules/markedLegacy": {
|
||||||
@@ -6185,15 +6198,6 @@
|
|||||||
"node": ">=4"
|
"node": ">=4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/mini-create-react-context": {
|
|
||||||
"version": "0.4.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/mini-create-react-context/-/mini-create-react-context-0.4.0.tgz",
|
|
||||||
"integrity": "sha512-b0TytUgFSbgFJGzJqXPKCFCBWigAjpjo+Fl7Vf7ZbKRDptszpppKxXH6DRXEABZ/gcEQczeb0iZ7JvL8e8jjCA==",
|
|
||||||
"dependencies": {
|
|
||||||
"@babel/runtime": "^7.5.5",
|
|
||||||
"tiny-warning": "^1.0.3"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/minimalistic-assert": {
|
"node_modules/minimalistic-assert": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
|
||||||
@@ -7287,12 +7291,42 @@
|
|||||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.12.0.tgz",
|
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.12.0.tgz",
|
||||||
"integrity": "sha512-rPCkf/mWBtKc97aLL9/txD8DZdemK0vkA3JMLShjlJB3Pj3s+lpf1KaBzMfQrAmhMQB0n1cU/SUGgKKBCe837Q=="
|
"integrity": "sha512-rPCkf/mWBtKc97aLL9/txD8DZdemK0vkA3JMLShjlJB3Pj3s+lpf1KaBzMfQrAmhMQB0n1cU/SUGgKKBCe837Q=="
|
||||||
},
|
},
|
||||||
"node_modules/react-router": {
|
"node_modules/react-router-dom": {
|
||||||
"version": "5.2.0",
|
"version": "5.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-5.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.2.1.tgz",
|
||||||
"integrity": "sha512-smz1DUuFHRKdcJC0jobGo8cVbhO3x50tCL4icacOlcwDOEQPq4TMqwx3sY1TP+DvtTgz4nm3thuo7A+BK2U0Dw==",
|
"integrity": "sha512-xhFFkBGVcIVPbWM2KEYzED+nuHQPmulVa7sqIs3ESxzYd1pYg8N8rxPnQ4T2o1zu/2QeDUWcaqST131SO1LR3w==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.1.2",
|
"@babel/runtime": "^7.12.13",
|
||||||
|
"history": "^4.9.0",
|
||||||
|
"loose-envify": "^1.3.1",
|
||||||
|
"prop-types": "^15.6.2",
|
||||||
|
"react-router": "5.2.1",
|
||||||
|
"tiny-invariant": "^1.0.2",
|
||||||
|
"tiny-warning": "^1.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": ">=15"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/react-router-dom/node_modules/isarray": {
|
||||||
|
"version": "0.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
|
||||||
|
"integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
|
||||||
|
},
|
||||||
|
"node_modules/react-router-dom/node_modules/path-to-regexp": {
|
||||||
|
"version": "1.8.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz",
|
||||||
|
"integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==",
|
||||||
|
"dependencies": {
|
||||||
|
"isarray": "0.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/react-router-dom/node_modules/react-router": {
|
||||||
|
"version": "5.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-router/-/react-router-5.2.1.tgz",
|
||||||
|
"integrity": "sha512-lIboRiOtDLFdg1VTemMwud9vRVuOCZmUIT/7lUoZiSpPODiiH1UQlfXy+vPLC/7IWdFYnhRwAyNqA/+I7wnvKQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/runtime": "^7.12.13",
|
||||||
"history": "^4.9.0",
|
"history": "^4.9.0",
|
||||||
"hoist-non-react-statics": "^3.1.0",
|
"hoist-non-react-statics": "^3.1.0",
|
||||||
"loose-envify": "^1.3.1",
|
"loose-envify": "^1.3.1",
|
||||||
@@ -7302,75 +7336,22 @@
|
|||||||
"react-is": "^16.6.0",
|
"react-is": "^16.6.0",
|
||||||
"tiny-invariant": "^1.0.2",
|
"tiny-invariant": "^1.0.2",
|
||||||
"tiny-warning": "^1.0.0"
|
"tiny-warning": "^1.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": ">=15"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/react-router-dom": {
|
"node_modules/react-router-dom/node_modules/react-router/node_modules/mini-create-react-context": {
|
||||||
"version": "5.2.0",
|
"version": "0.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/mini-create-react-context/-/mini-create-react-context-0.4.1.tgz",
|
||||||
"integrity": "sha512-gxAmfylo2QUjcwxI63RhQ5G85Qqt4voZpUXSEqCwykV0baaOTQDR1f0PmY8AELqIyVc0NEZUj0Gov5lNGcXgsA==",
|
"integrity": "sha512-YWCYEmd5CQeHGSAKrYvXgmzzkrvssZcuuQDDeqkT+PziKGMgE+0MCCtcKbROzocGBG1meBLl2FotlRwf4gAzbQ==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.1.2",
|
"@babel/runtime": "^7.12.1",
|
||||||
"history": "^4.9.0",
|
"tiny-warning": "^1.0.3"
|
||||||
"loose-envify": "^1.3.1",
|
|
||||||
"prop-types": "^15.6.2",
|
|
||||||
"react-router": "5.2.0",
|
|
||||||
"tiny-invariant": "^1.0.2",
|
|
||||||
"tiny-warning": "^1.0.0"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"node_modules/react-router-dom/node_modules/prop-types": {
|
"peerDependencies": {
|
||||||
"version": "15.7.2",
|
"prop-types": "^15.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz",
|
"react": "^0.14.0 || ^15.0.0 || ^16.0.0 || ^17.0.0"
|
||||||
"integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==",
|
|
||||||
"dependencies": {
|
|
||||||
"loose-envify": "^1.4.0",
|
|
||||||
"object-assign": "^4.1.1",
|
|
||||||
"react-is": "^16.8.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/react-router-dom/node_modules/prop-types/node_modules/loose-envify": {
|
|
||||||
"version": "1.4.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
|
|
||||||
"integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
|
|
||||||
"dependencies": {
|
|
||||||
"js-tokens": "^3.0.0 || ^4.0.0"
|
|
||||||
},
|
|
||||||
"bin": {
|
|
||||||
"loose-envify": "cli.js"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/react-router/node_modules/isarray": {
|
|
||||||
"version": "0.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
|
|
||||||
"integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
|
|
||||||
},
|
|
||||||
"node_modules/react-router/node_modules/path-to-regexp": {
|
|
||||||
"version": "1.8.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz",
|
|
||||||
"integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==",
|
|
||||||
"dependencies": {
|
|
||||||
"isarray": "0.0.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/react-router/node_modules/prop-types": {
|
|
||||||
"version": "15.7.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz",
|
|
||||||
"integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==",
|
|
||||||
"dependencies": {
|
|
||||||
"loose-envify": "^1.4.0",
|
|
||||||
"object-assign": "^4.1.1",
|
|
||||||
"react-is": "^16.8.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/react-router/node_modules/prop-types/node_modules/loose-envify": {
|
|
||||||
"version": "1.4.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
|
|
||||||
"integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
|
|
||||||
"dependencies": {
|
|
||||||
"js-tokens": "^3.0.0 || ^4.0.0"
|
|
||||||
},
|
|
||||||
"bin": {
|
|
||||||
"loose-envify": "cli.js"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/read-only-stream": {
|
"node_modules/read-only-stream": {
|
||||||
@@ -10616,9 +10597,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@babel/runtime": {
|
"@babel/runtime": {
|
||||||
"version": "7.9.6",
|
"version": "7.15.3",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.9.6.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.15.3.tgz",
|
||||||
"integrity": "sha512-64AF1xY3OAkFHqOb9s4jpgk1Mm5vDZ4L3acHvAml+53nO1XbXLuDodsVpO4OIUsmemlUHMxNdYMNJmsvOwLrvQ==",
|
"integrity": "sha512-OvwMLqNXkCXSz1kSm58sEsNuhqOx/fKpnUnKnFB5v8uDda5bLNEHNgKPvhDN6IU0LDcnHQ90LlJ0Q6jnyBSIBA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"regenerator-runtime": "^0.13.4"
|
"regenerator-runtime": "^0.13.4"
|
||||||
},
|
},
|
||||||
@@ -11828,9 +11809,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"codemirror": {
|
"codemirror": {
|
||||||
"version": "5.62.2",
|
"version": "5.62.3",
|
||||||
"resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.62.2.tgz",
|
"resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.62.3.tgz",
|
||||||
"integrity": "sha512-tVFMUa4J3Q8JUd1KL9yQzQB0/BJt7ZYZujZmTPgo/54Lpuq3ez4C8x/ATUY/wv7b7X3AUq8o3Xd+2C5ZrCGWHw=="
|
"integrity": "sha512-zZAyOfN8TU67ngqrxhOgtkSAGV9jSpN1snbl8elPtnh9Z5A11daR405+dhLzLnuXrwX0WCShWlybxPN3QC/9Pg=="
|
||||||
},
|
},
|
||||||
"collection-visit": {
|
"collection-visit": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
@@ -12517,14 +12498,15 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"eslint-plugin-react": {
|
"eslint-plugin-react": {
|
||||||
"version": "7.24.0",
|
"version": "7.25.1",
|
||||||
"resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.24.0.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.25.1.tgz",
|
||||||
"integrity": "sha512-KJJIx2SYx7PBx3ONe/mEeMz4YE0Lcr7feJTCMyyKb/341NcjuAgim3Acgan89GfPv7nxXK2+0slu0CWXYM4x+Q==",
|
"integrity": "sha512-P4j9K1dHoFXxDNP05AtixcJEvIT6ht8FhYKsrkY0MPCPaUMYijhpWwNiRDZVtA8KFuZOkGSeft6QwH8KuVpJug==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"array-includes": "^3.1.3",
|
"array-includes": "^3.1.3",
|
||||||
"array.prototype.flatmap": "^1.2.4",
|
"array.prototype.flatmap": "^1.2.4",
|
||||||
"doctrine": "^2.1.0",
|
"doctrine": "^2.1.0",
|
||||||
|
"estraverse": "^5.2.0",
|
||||||
"has": "^1.0.3",
|
"has": "^1.0.3",
|
||||||
"jsx-ast-utils": "^2.4.1 || ^3.0.0",
|
"jsx-ast-utils": "^2.4.1 || ^3.0.0",
|
||||||
"minimatch": "^3.0.4",
|
"minimatch": "^3.0.4",
|
||||||
@@ -12545,6 +12527,12 @@
|
|||||||
"esutils": "^2.0.2"
|
"esutils": "^2.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"estraverse": {
|
||||||
|
"version": "5.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz",
|
||||||
|
"integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"resolve": {
|
"resolve": {
|
||||||
"version": "2.0.0-next.3",
|
"version": "2.0.0-next.3",
|
||||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.3.tgz",
|
"resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.3.tgz",
|
||||||
@@ -14071,9 +14059,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"marked": {
|
"marked": {
|
||||||
"version": "2.1.3",
|
"version": "3.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/marked/-/marked-2.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/marked/-/marked-3.0.2.tgz",
|
||||||
"integrity": "sha512-/Q+7MGzaETqifOMWYEA7HVMaZb4XbcRfaOzcSsHZEith83KGlvaSG33u0SKu89Mj5h+T8V2hM+8O45Qc5XTgwA=="
|
"integrity": "sha512-TMJQQ79Z0e3rJYazY0tIoMsFzteUGw9fB3FD+gzuIT3zLuG9L9ckIvUfF51apdJkcqc208jJN2KbtPbOvXtbjA=="
|
||||||
},
|
},
|
||||||
"markedLegacy": {
|
"markedLegacy": {
|
||||||
"version": "npm:marked@0.3.19",
|
"version": "npm:marked@0.3.19",
|
||||||
@@ -14247,15 +14235,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz",
|
||||||
"integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ=="
|
"integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ=="
|
||||||
},
|
},
|
||||||
"mini-create-react-context": {
|
|
||||||
"version": "0.4.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/mini-create-react-context/-/mini-create-react-context-0.4.0.tgz",
|
|
||||||
"integrity": "sha512-b0TytUgFSbgFJGzJqXPKCFCBWigAjpjo+Fl7Vf7ZbKRDptszpppKxXH6DRXEABZ/gcEQczeb0iZ7JvL8e8jjCA==",
|
|
||||||
"requires": {
|
|
||||||
"@babel/runtime": "^7.5.5",
|
|
||||||
"tiny-warning": "^1.0.3"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"minimalistic-assert": {
|
"minimalistic-assert": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
|
||||||
@@ -15108,19 +15087,16 @@
|
|||||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.12.0.tgz",
|
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.12.0.tgz",
|
||||||
"integrity": "sha512-rPCkf/mWBtKc97aLL9/txD8DZdemK0vkA3JMLShjlJB3Pj3s+lpf1KaBzMfQrAmhMQB0n1cU/SUGgKKBCe837Q=="
|
"integrity": "sha512-rPCkf/mWBtKc97aLL9/txD8DZdemK0vkA3JMLShjlJB3Pj3s+lpf1KaBzMfQrAmhMQB0n1cU/SUGgKKBCe837Q=="
|
||||||
},
|
},
|
||||||
"react-router": {
|
"react-router-dom": {
|
||||||
"version": "5.2.0",
|
"version": "5.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-5.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.2.1.tgz",
|
||||||
"integrity": "sha512-smz1DUuFHRKdcJC0jobGo8cVbhO3x50tCL4icacOlcwDOEQPq4TMqwx3sY1TP+DvtTgz4nm3thuo7A+BK2U0Dw==",
|
"integrity": "sha512-xhFFkBGVcIVPbWM2KEYzED+nuHQPmulVa7sqIs3ESxzYd1pYg8N8rxPnQ4T2o1zu/2QeDUWcaqST131SO1LR3w==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/runtime": "^7.1.2",
|
"@babel/runtime": "^7.12.13",
|
||||||
"history": "^4.9.0",
|
"history": "^4.9.0",
|
||||||
"hoist-non-react-statics": "^3.1.0",
|
|
||||||
"loose-envify": "^1.3.1",
|
"loose-envify": "^1.3.1",
|
||||||
"mini-create-react-context": "^0.4.0",
|
|
||||||
"path-to-regexp": "^1.7.0",
|
|
||||||
"prop-types": "^15.6.2",
|
"prop-types": "^15.6.2",
|
||||||
"react-is": "^16.6.0",
|
"react-router": "5.2.1",
|
||||||
"tiny-invariant": "^1.0.2",
|
"tiny-invariant": "^1.0.2",
|
||||||
"tiny-warning": "^1.0.0"
|
"tiny-warning": "^1.0.0"
|
||||||
},
|
},
|
||||||
@@ -15138,58 +15114,30 @@
|
|||||||
"isarray": "0.0.1"
|
"isarray": "0.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"prop-types": {
|
"react-router": {
|
||||||
"version": "15.7.2",
|
"version": "5.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz",
|
"resolved": "https://registry.npmjs.org/react-router/-/react-router-5.2.1.tgz",
|
||||||
"integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==",
|
"integrity": "sha512-lIboRiOtDLFdg1VTemMwud9vRVuOCZmUIT/7lUoZiSpPODiiH1UQlfXy+vPLC/7IWdFYnhRwAyNqA/+I7wnvKQ==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"loose-envify": "^1.4.0",
|
"@babel/runtime": "^7.12.13",
|
||||||
"object-assign": "^4.1.1",
|
|
||||||
"react-is": "^16.8.1"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"loose-envify": {
|
|
||||||
"version": "1.4.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
|
|
||||||
"integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
|
|
||||||
"requires": {
|
|
||||||
"js-tokens": "^3.0.0 || ^4.0.0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"react-router-dom": {
|
|
||||||
"version": "5.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.2.0.tgz",
|
|
||||||
"integrity": "sha512-gxAmfylo2QUjcwxI63RhQ5G85Qqt4voZpUXSEqCwykV0baaOTQDR1f0PmY8AELqIyVc0NEZUj0Gov5lNGcXgsA==",
|
|
||||||
"requires": {
|
|
||||||
"@babel/runtime": "^7.1.2",
|
|
||||||
"history": "^4.9.0",
|
"history": "^4.9.0",
|
||||||
|
"hoist-non-react-statics": "^3.1.0",
|
||||||
"loose-envify": "^1.3.1",
|
"loose-envify": "^1.3.1",
|
||||||
|
"mini-create-react-context": "^0.4.0",
|
||||||
|
"path-to-regexp": "^1.7.0",
|
||||||
"prop-types": "^15.6.2",
|
"prop-types": "^15.6.2",
|
||||||
"react-router": "5.2.0",
|
"react-is": "^16.6.0",
|
||||||
"tiny-invariant": "^1.0.2",
|
"tiny-invariant": "^1.0.2",
|
||||||
"tiny-warning": "^1.0.0"
|
"tiny-warning": "^1.0.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"prop-types": {
|
"mini-create-react-context": {
|
||||||
"version": "15.7.2",
|
"version": "0.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz",
|
"resolved": "https://registry.npmjs.org/mini-create-react-context/-/mini-create-react-context-0.4.1.tgz",
|
||||||
"integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==",
|
"integrity": "sha512-YWCYEmd5CQeHGSAKrYvXgmzzkrvssZcuuQDDeqkT+PziKGMgE+0MCCtcKbROzocGBG1meBLl2FotlRwf4gAzbQ==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"loose-envify": "^1.4.0",
|
"@babel/runtime": "^7.12.1",
|
||||||
"object-assign": "^4.1.1",
|
"tiny-warning": "^1.0.3"
|
||||||
"react-is": "^16.8.1"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"loose-envify": {
|
|
||||||
"version": "1.4.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
|
|
||||||
"integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
|
|
||||||
"requires": {
|
|
||||||
"js-tokens": "^3.0.0 || ^4.0.0"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
10
package.json
10
package.json
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "homebrewery",
|
"name": "homebrewery",
|
||||||
"description": "Create authentic looking D&D homebrews using only markdown",
|
"description": "Create authentic looking D&D homebrews using only markdown",
|
||||||
"version": "2.13.3",
|
"version": "2.13.4",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "14.15.x"
|
"node": "14.15.x"
|
||||||
},
|
},
|
||||||
@@ -46,7 +46,7 @@
|
|||||||
"@babel/preset-react": "^7.14.5",
|
"@babel/preset-react": "^7.14.5",
|
||||||
"body-parser": "^1.19.0",
|
"body-parser": "^1.19.0",
|
||||||
"classnames": "^2.3.1",
|
"classnames": "^2.3.1",
|
||||||
"codemirror": "^5.62.2",
|
"codemirror": "^5.62.3",
|
||||||
"cookie-parser": "^1.4.5",
|
"cookie-parser": "^1.4.5",
|
||||||
"create-react-class": "^15.7.0",
|
"create-react-class": "^15.7.0",
|
||||||
"dedent-tabs": "^0.9.0",
|
"dedent-tabs": "^0.9.0",
|
||||||
@@ -58,7 +58,7 @@
|
|||||||
"jwt-simple": "^0.5.6",
|
"jwt-simple": "^0.5.6",
|
||||||
"less": "^3.13.1",
|
"less": "^3.13.1",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"marked": "2.1.3",
|
"marked": "3.0.2",
|
||||||
"markedLegacy": "npm:marked@^0.3.19",
|
"markedLegacy": "npm:marked@^0.3.19",
|
||||||
"moment": "^2.29.1",
|
"moment": "^2.29.1",
|
||||||
"mongoose": "^5.13.7",
|
"mongoose": "^5.13.7",
|
||||||
@@ -69,14 +69,14 @@
|
|||||||
"react": "^16.14.0",
|
"react": "^16.14.0",
|
||||||
"react-dom": "^16.14.0",
|
"react-dom": "^16.14.0",
|
||||||
"react-frame-component": "4.1.3",
|
"react-frame-component": "4.1.3",
|
||||||
"react-router-dom": "5.2.0",
|
"react-router-dom": "5.2.1",
|
||||||
"sanitize-filename": "1.6.3",
|
"sanitize-filename": "1.6.3",
|
||||||
"superagent": "^6.1.0",
|
"superagent": "^6.1.0",
|
||||||
"vitreum": "git+https://git@github.com/calculuschild/vitreum.git"
|
"vitreum": "git+https://git@github.com/calculuschild/vitreum.git"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"eslint": "^7.32.0",
|
"eslint": "^7.32.0",
|
||||||
"eslint-plugin-react": "^7.24.0",
|
"eslint-plugin-react": "^7.25.1",
|
||||||
"pico-check": "^2.1.3"
|
"pico-check": "^2.1.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -135,7 +135,8 @@ app.get('/v3_preview', async (req, res, next)=>{
|
|||||||
app.get('/changelog', async (req, res, next)=>{
|
app.get('/changelog', async (req, res, next)=>{
|
||||||
const brew = {
|
const brew = {
|
||||||
title : 'Changelog',
|
title : 'Changelog',
|
||||||
text : changelogText
|
text : changelogText,
|
||||||
|
renderer : 'V3'
|
||||||
};
|
};
|
||||||
req.brew = brew;
|
req.brew = brew;
|
||||||
return next();
|
return next();
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ GoogleActions = {
|
|||||||
if(!account || !account.googleId){ // If not signed into Google
|
if(!account || !account.googleId){ // If not signed into Google
|
||||||
const err = new Error('Not Signed In');
|
const err = new Error('Not Signed In');
|
||||||
err.status = 401;
|
err.status = 401;
|
||||||
throw err;
|
throw (err);
|
||||||
}
|
}
|
||||||
|
|
||||||
const oAuth2Client = new google.auth.OAuth2(
|
const oAuth2Client = new google.auth.OAuth2(
|
||||||
@@ -60,6 +60,7 @@ GoogleActions = {
|
|||||||
.catch((err)=>{
|
.catch((err)=>{
|
||||||
console.log('Error searching Google Drive Folders');
|
console.log('Error searching Google Drive Folders');
|
||||||
console.error(err);
|
console.error(err);
|
||||||
|
throw (err);
|
||||||
});
|
});
|
||||||
|
|
||||||
let folderId;
|
let folderId;
|
||||||
@@ -69,8 +70,9 @@ GoogleActions = {
|
|||||||
resource : fileMetadata
|
resource : fileMetadata
|
||||||
})
|
})
|
||||||
.catch((err)=>{
|
.catch((err)=>{
|
||||||
console.log('Error creating google app folder');
|
console.log('Error creating Google Drive folder');
|
||||||
console.error(err);
|
console.error(err);
|
||||||
|
throw (err);
|
||||||
});
|
});
|
||||||
|
|
||||||
folderId = obj.data.id;
|
folderId = obj.data.id;
|
||||||
@@ -99,7 +101,9 @@ GoogleActions = {
|
|||||||
q : 'mimeType != \'application/vnd.google-apps.folder\' and trashed = false'
|
q : 'mimeType != \'application/vnd.google-apps.folder\' and trashed = false'
|
||||||
})
|
})
|
||||||
.catch((err)=>{
|
.catch((err)=>{
|
||||||
return console.error(`Error Listing Google Brews: ${err}`);
|
console.log(`Error Listing Google Brews`);
|
||||||
|
console.error(err);
|
||||||
|
throw (err);
|
||||||
//TODO: Should break out here, but continues on for some reason.
|
//TODO: Should break out here, but continues on for some reason.
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -116,7 +120,7 @@ GoogleActions = {
|
|||||||
updatedAt : file.modifiedTime,
|
updatedAt : file.modifiedTime,
|
||||||
gDrive : true,
|
gDrive : true,
|
||||||
googleId : file.id,
|
googleId : file.id,
|
||||||
|
pageCount : file.properties.pageCount,
|
||||||
title : file.properties.title,
|
title : file.properties.title,
|
||||||
description : file.description,
|
description : file.description,
|
||||||
views : file.properties.views,
|
views : file.properties.views,
|
||||||
@@ -126,7 +130,6 @@ GoogleActions = {
|
|||||||
systems : []
|
systems : []
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
return brews;
|
return brews;
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -136,7 +139,7 @@ GoogleActions = {
|
|||||||
const result = await drive.files.get({ fileId: id })
|
const result = await drive.files.get({ fileId: id })
|
||||||
.catch((err)=>{
|
.catch((err)=>{
|
||||||
console.log('error checking file exists...');
|
console.log('error checking file exists...');
|
||||||
console.log(err);
|
console.error(err);
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -151,19 +154,22 @@ GoogleActions = {
|
|||||||
if(await GoogleActions.existsGoogleBrew(auth, brew.googleId) == true) {
|
if(await GoogleActions.existsGoogleBrew(auth, brew.googleId) == true) {
|
||||||
await drive.files.update({
|
await drive.files.update({
|
||||||
fileId : brew.googleId,
|
fileId : brew.googleId,
|
||||||
resource : { name : `${brew.title}.txt`,
|
resource : {
|
||||||
|
name : `${brew.title}.txt`,
|
||||||
description : `${brew.description}`,
|
description : `${brew.description}`,
|
||||||
properties : { title : brew.title,
|
properties : {
|
||||||
|
title : brew.title,
|
||||||
published : brew.published,
|
published : brew.published,
|
||||||
lastViewed : brew.lastViewed,
|
|
||||||
views : brew.views,
|
|
||||||
version : brew.version,
|
version : brew.version,
|
||||||
renderer : brew.renderer,
|
renderer : brew.renderer,
|
||||||
tags : brew.tags,
|
tags : brew.tags,
|
||||||
systems : brew.systems.join() }
|
systems : brew.systems.join()
|
||||||
|
}
|
||||||
},
|
},
|
||||||
media : { mimeType : 'text/plain',
|
media : {
|
||||||
body : brew.text }
|
mimeType : 'text/plain',
|
||||||
|
body : brew.text
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.catch((err)=>{
|
.catch((err)=>{
|
||||||
console.log('Error saving to google');
|
console.log('Error saving to google');
|
||||||
@@ -195,6 +201,7 @@ GoogleActions = {
|
|||||||
'editId' : nanoid(12),
|
'editId' : nanoid(12),
|
||||||
'title' : brew.title,
|
'title' : brew.title,
|
||||||
'views' : '0',
|
'views' : '0',
|
||||||
|
'pageCount' : brew.pageCount,
|
||||||
'renderer' : brew.renderer || 'legacy'
|
'renderer' : brew.renderer || 'legacy'
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -230,6 +237,7 @@ GoogleActions = {
|
|||||||
updatedAt : new Date(),
|
updatedAt : new Date(),
|
||||||
gDrive : true,
|
gDrive : true,
|
||||||
googleId : obj.data.id,
|
googleId : obj.data.id,
|
||||||
|
pageCount : fileMetadata.properties.pageCount,
|
||||||
|
|
||||||
title : brew.title,
|
title : brew.title,
|
||||||
description : brew.description,
|
description : brew.description,
|
||||||
@@ -301,6 +309,7 @@ GoogleActions = {
|
|||||||
createdAt : obj.data.createdTime,
|
createdAt : obj.data.createdTime,
|
||||||
updatedAt : obj.data.modifiedTime,
|
updatedAt : obj.data.modifiedTime,
|
||||||
lastViewed : obj.data.properties.lastViewed,
|
lastViewed : obj.data.properties.lastViewed,
|
||||||
|
pageCount : obj.data.properties.pageCount,
|
||||||
views : parseInt(obj.data.properties.views) || 0, //brews with no view parameter will return undefined
|
views : parseInt(obj.data.properties.views) || 0, //brews with no view parameter will return undefined
|
||||||
version : parseInt(obj.data.properties.version) || 0,
|
version : parseInt(obj.data.properties.version) || 0,
|
||||||
renderer : obj.data.properties.renderer ? obj.data.properties.renderer : 'legacy',
|
renderer : obj.data.properties.renderer ? obj.data.properties.renderer : 'legacy',
|
||||||
@@ -361,8 +370,13 @@ GoogleActions = {
|
|||||||
|
|
||||||
await drive.files.update({
|
await drive.files.update({
|
||||||
fileId : brew.googleId,
|
fileId : brew.googleId,
|
||||||
resource : { properties : { views : brew.views + 1,
|
resource : {
|
||||||
lastViewed : new Date() } }
|
modifiedTime : brew.updatedAt,
|
||||||
|
properties : {
|
||||||
|
views : brew.views + 1,
|
||||||
|
lastViewed : new Date()
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.catch((err)=>{
|
.catch((err)=>{
|
||||||
console.log('Error updating Google views');
|
console.log('Error updating Google views');
|
||||||
|
|||||||
@@ -19,6 +19,15 @@ const getGoodBrewTitle = (text)=>{
|
|||||||
.slice(0, MAX_TITLE_LENGTH);
|
.slice(0, MAX_TITLE_LENGTH);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const excludePropsFromUpdate = (brew)=>{
|
||||||
|
// Remove undesired properties
|
||||||
|
const propsToExclude = ['views', 'lastViewed'];
|
||||||
|
for (const prop of propsToExclude) {
|
||||||
|
delete brew[prop];
|
||||||
|
};
|
||||||
|
return brew;
|
||||||
|
};
|
||||||
|
|
||||||
const mergeBrewText = (text, style)=>{
|
const mergeBrewText = (text, style)=>{
|
||||||
if(typeof style !== 'undefined') {
|
if(typeof style !== 'undefined') {
|
||||||
text = `\`\`\`css\n` +
|
text = `\`\`\`css\n` +
|
||||||
@@ -64,7 +73,8 @@ const newBrew = (req, res)=>{
|
|||||||
const updateBrew = (req, res)=>{
|
const updateBrew = (req, res)=>{
|
||||||
HomebrewModel.get({ editId: req.params.id })
|
HomebrewModel.get({ editId: req.params.id })
|
||||||
.then((brew)=>{
|
.then((brew)=>{
|
||||||
brew = _.merge(brew, req.body);
|
const updateBrew = excludePropsFromUpdate(req.body);
|
||||||
|
brew = _.merge(brew, updateBrew);
|
||||||
brew.text = mergeBrewText(brew.text, brew.style);
|
brew.text = mergeBrewText(brew.text, brew.style);
|
||||||
|
|
||||||
// Compress brew text to binary before saving
|
// Compress brew text to binary before saving
|
||||||
@@ -154,7 +164,7 @@ const updateGoogleBrew = async (req, res, next)=>{
|
|||||||
|
|
||||||
try { oAuth2Client = GoogleActions.authCheck(req.account, res); } catch (err) { return res.status(err.status).send(err.message); }
|
try { oAuth2Client = GoogleActions.authCheck(req.account, res); } catch (err) { return res.status(err.status).send(err.message); }
|
||||||
|
|
||||||
const brew = req.body;
|
const brew = excludePropsFromUpdate(req.body);
|
||||||
brew.text = mergeBrewText(brew.text, brew.style);
|
brew.text = mergeBrewText(brew.text, brew.style);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ const HomebrewSchema = mongoose.Schema({
|
|||||||
title : { type: String, default: '' },
|
title : { type: String, default: '' },
|
||||||
text : { type: String, default: '' },
|
text : { type: String, default: '' },
|
||||||
textBin : { type: Buffer },
|
textBin : { type: Buffer },
|
||||||
|
pageCount : { type: Number, default: 1 },
|
||||||
|
|
||||||
description : { type: String, default: '' },
|
description : { type: String, default: '' },
|
||||||
tags : { type: String, default: '' },
|
tags : { type: String, default: '' },
|
||||||
|
|||||||
@@ -65,13 +65,13 @@ const mustacheSpans = {
|
|||||||
raw : raw, // Text to consume from the source
|
raw : raw, // Text to consume from the source
|
||||||
text : text, // Additional custom properties
|
text : text, // Additional custom properties
|
||||||
tags : tags,
|
tags : tags,
|
||||||
tokens : this.inlineTokens(text) // inlineTokens to process **bold**, *italics*, etc.
|
tokens : this.lexer.inlineTokens(text) // inlineTokens to process **bold**, *italics*, etc.
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
renderer(token) {
|
renderer(token) {
|
||||||
return `<span class="inline-block${token.tags}>${this.parseInline(token.tokens)}</span>`; // parseInline to turn child tokens into HTML
|
return `<span class="inline-block${token.tags}>${this.parser.parseInline(token.tokens)}</span>`; // parseInline to turn child tokens into HTML
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -114,13 +114,13 @@ const mustacheDivs = {
|
|||||||
raw : raw, // Text to consume from the source
|
raw : raw, // Text to consume from the source
|
||||||
text : text, // Additional custom properties
|
text : text, // Additional custom properties
|
||||||
tags : tags,
|
tags : tags,
|
||||||
tokens : this.inline(this.blockTokens(text))
|
tokens : this.lexer.blockTokens(text)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
renderer(token) {
|
renderer(token) {
|
||||||
return `<div class="block${token.tags}>${this.parse(token.tokens)}</div>`; // parseInline to turn child tokens into HTML
|
return `<div class="block${token.tags}>${this.parser.parse(token.tokens)}</div>`; // parseInline to turn child tokens into HTML
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -149,7 +149,7 @@ const mustacheInjectInline = {
|
|||||||
},
|
},
|
||||||
renderer(token) {
|
renderer(token) {
|
||||||
token.type = token.originalType;
|
token.type = token.originalType;
|
||||||
const text = this.parseInline([token]);
|
const text = this.parser.parseInline([token]);
|
||||||
const openingTag = /(<[^\s<>]+)([^\n<>]*>.*)/s.exec(text);
|
const openingTag = /(<[^\s<>]+)([^\n<>]*>.*)/s.exec(text);
|
||||||
if(openingTag) {
|
if(openingTag) {
|
||||||
return `${openingTag[1]} class="${token.tags}${openingTag[2]}`;
|
return `${openingTag[1]} class="${token.tags}${openingTag[2]}`;
|
||||||
@@ -182,7 +182,7 @@ const mustacheInjectBlock = {
|
|||||||
},
|
},
|
||||||
renderer(token) {
|
renderer(token) {
|
||||||
token.type = token.originalType;
|
token.type = token.originalType;
|
||||||
const text = this.parse([token]);
|
const text = this.parser.parse([token]);
|
||||||
const openingTag = /(<[^\s<>]+)([^\n<>]*>.*)/s.exec(text);
|
const openingTag = /(<[^\s<>]+)([^\n<>]*>.*)/s.exec(text);
|
||||||
if(openingTag) {
|
if(openingTag) {
|
||||||
return `${openingTag[1]} class="${token.tags}${openingTag[2]}`;
|
return `${openingTag[1]} class="${token.tags}${openingTag[2]}`;
|
||||||
@@ -211,8 +211,8 @@ const definitionLists = {
|
|||||||
const definitions = [];
|
const definitions = [];
|
||||||
while (match = regex.exec(src)) {
|
while (match = regex.exec(src)) {
|
||||||
definitions.push({
|
definitions.push({
|
||||||
dt : this.inlineTokens(match[1].trim()),
|
dt : this.lexer.inlineTokens(match[1].trim()),
|
||||||
dd : this.inlineTokens(match[2].trim())
|
dd : this.lexer.inlineTokens(match[2].trim())
|
||||||
});
|
});
|
||||||
endIndex = regex.lastIndex;
|
endIndex = regex.lastIndex;
|
||||||
}
|
}
|
||||||
@@ -227,8 +227,8 @@ const definitionLists = {
|
|||||||
renderer(token) {
|
renderer(token) {
|
||||||
return `<dl>
|
return `<dl>
|
||||||
${token.definitions.reduce((html, def)=>{
|
${token.definitions.reduce((html, def)=>{
|
||||||
return `${html}<dt>${this.parseInline(def.dt)}</dt>`
|
return `${html}<dt>${this.parser.parseInline(def.dt)}</dt>`
|
||||||
+ `<dd>${this.parseInline(def.dd)}</dd>\n`;
|
+ `<dd>${this.parser.parseInline(def.dd)}</dd>\n`;
|
||||||
}, '')}
|
}, '')}
|
||||||
</dl>`;
|
</dl>`;
|
||||||
}
|
}
|
||||||
@@ -302,7 +302,7 @@ const spanTable = {
|
|||||||
row = item.header[j];
|
row = item.header[j];
|
||||||
for (k = 0; k < row.length; k++) {
|
for (k = 0; k < row.length; k++) {
|
||||||
row[k].tokens = [];
|
row[k].tokens = [];
|
||||||
this.inlineTokens(row[k].text, row[k].tokens);
|
this.lexer.inlineTokens(row[k].text, row[k].tokens);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -312,7 +312,7 @@ const spanTable = {
|
|||||||
row = item.rows[j];
|
row = item.rows[j];
|
||||||
for (k = 0; k < row.length; k++) {
|
for (k = 0; k < row.length; k++) {
|
||||||
row[k].tokens = [];
|
row[k].tokens = [];
|
||||||
this.inlineTokens(row[k].text, row[k].tokens);
|
this.lexer.inlineTokens(row[k].text, row[k].tokens);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return item;
|
return item;
|
||||||
@@ -329,7 +329,7 @@ const spanTable = {
|
|||||||
output += `<tr>`;
|
output += `<tr>`;
|
||||||
for (j = 0; j < row.length; j++) {
|
for (j = 0; j < row.length; j++) {
|
||||||
cell = row[j];
|
cell = row[j];
|
||||||
text = this.parseInline(cell.tokens);
|
text = this.parser.parseInline(cell.tokens);
|
||||||
output += getTableCell(text, cell, 'th', token.align[col]);
|
output += getTableCell(text, cell, 'th', token.align[col]);
|
||||||
col += cell.colspan;
|
col += cell.colspan;
|
||||||
}
|
}
|
||||||
@@ -344,7 +344,7 @@ const spanTable = {
|
|||||||
output += `<tr>`;
|
output += `<tr>`;
|
||||||
for (j = 0; j < row.length; j++) {
|
for (j = 0; j < row.length; j++) {
|
||||||
cell = row[j];
|
cell = row[j];
|
||||||
text = this.parseInline(cell.tokens);
|
text = this.parser.parseInline(cell.tokens);
|
||||||
output += getTableCell(text, cell, 'td', token.align[col]);
|
output += getTableCell(text, cell, 'td', token.align[col]);
|
||||||
col += cell.colspan;
|
col += cell.colspan;
|
||||||
}
|
}
|
||||||
@@ -527,7 +527,7 @@ const processStyleTags = (string)=>{
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
marked : Markdown,
|
marked : Markdown,
|
||||||
render : (rawBrewText)=>{
|
render : (rawBrewText)=>{
|
||||||
rawBrewText = rawBrewText.replace(/^\\column$/gm, `<div class='columnSplit'></div>`)
|
rawBrewText = rawBrewText.replace(/^\\column$/gm, `\n<div class='columnSplit'></div>\n`)
|
||||||
.replace(/^(:+)$/gm, (match)=>`${`<div class='blank'></div>`.repeat(match.length)}\n`);
|
.replace(/^(:+)$/gm, (match)=>`${`<div class='blank'></div>`.repeat(match.length)}\n`);
|
||||||
return Markdown(
|
return Markdown(
|
||||||
sanatizeScriptTags(rawBrewText),
|
sanatizeScriptTags(rawBrewText),
|
||||||
|
|||||||
@@ -34,9 +34,9 @@ body {
|
|||||||
letter-spacing : -0.02em;
|
letter-spacing : -0.02em;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.useColumns(@multiplier : 1){
|
.useColumns(@multiplier : 1, @fillMode: balance){
|
||||||
column-count : 2;
|
column-count : 2;
|
||||||
column-fill : auto;
|
column-fill : @fillMode;
|
||||||
column-gap : 0.9cm;
|
column-gap : 0.9cm;
|
||||||
column-width : 8cm * @multiplier;
|
column-width : 8cm * @multiplier;
|
||||||
-webkit-column-count : 2;
|
-webkit-column-count : 2;
|
||||||
@@ -46,6 +46,11 @@ body {
|
|||||||
-webkit-column-gap : 0.9cm;
|
-webkit-column-gap : 0.9cm;
|
||||||
-moz-column-gap : 0.9cm;
|
-moz-column-gap : 0.9cm;
|
||||||
}
|
}
|
||||||
|
.columnWrapper{
|
||||||
|
max-height : 100%;
|
||||||
|
column-span : all;
|
||||||
|
columns : inherit;
|
||||||
|
}
|
||||||
.page{
|
.page{
|
||||||
.useColumns();
|
.useColumns();
|
||||||
counter-increment : phb-page-numbers;
|
counter-increment : phb-page-numbers;
|
||||||
@@ -55,9 +60,9 @@ body {
|
|||||||
overflow : hidden;
|
overflow : hidden;
|
||||||
height : 279.4mm;
|
height : 279.4mm;
|
||||||
width : 215.9mm;
|
width : 215.9mm;
|
||||||
padding : 1.4cm 1.9cm 1.7cm;
|
|
||||||
background-color : @background;
|
background-color : @background;
|
||||||
background-image : @backgroundImage;
|
background-image : @backgroundImage;
|
||||||
|
padding : 1.4cm 1.9cm 1.7cm;
|
||||||
font-family : BookInsanityRemake;
|
font-family : BookInsanityRemake;
|
||||||
font-size : 0.34cm;
|
font-size : 0.34cm;
|
||||||
text-rendering : optimizeLegibility;
|
text-rendering : optimizeLegibility;
|
||||||
@@ -68,10 +73,13 @@ body {
|
|||||||
// *****************************/
|
// *****************************/
|
||||||
p{
|
p{
|
||||||
overflow-wrap : break-word; //TODO: MAKE ALL MARGINS TOP-ONLY. USE * + * STYLE SELECTORS
|
overflow-wrap : break-word; //TODO: MAKE ALL MARGINS TOP-ONLY. USE * + * STYLE SELECTORS
|
||||||
margin-bottom : 0.8em;
|
display : block;
|
||||||
line-height : 1.3em;
|
line-height : 1.3em;
|
||||||
|
&+* {
|
||||||
|
margin-top : 0.27cm;
|
||||||
|
}
|
||||||
&+p{
|
&+p{
|
||||||
margin-top : -0.8em;
|
margin-top : 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ul{
|
ul{
|
||||||
@@ -121,7 +129,7 @@ body {
|
|||||||
color : @headerText;
|
color : @headerText;
|
||||||
}
|
}
|
||||||
h1{
|
h1{
|
||||||
margin-bottom : 0.18cm;
|
margin-bottom : 0.18cm; //Margin-bottom only because this is WIDE
|
||||||
column-span : all;
|
column-span : all;
|
||||||
font-size : 0.89cm;
|
font-size : 0.89cm;
|
||||||
-webkit-column-span : all;
|
-webkit-column-span : all;
|
||||||
@@ -129,42 +137,41 @@ body {
|
|||||||
&+p::first-letter{
|
&+p::first-letter{
|
||||||
float : left;
|
float : left;
|
||||||
font-family : SolberaImitationRemake;
|
font-family : SolberaImitationRemake;
|
||||||
line-height : 0.8em;
|
line-height : 1em;
|
||||||
font-size: 3.5cm;
|
font-size : 3.5cm;
|
||||||
padding-left: 40px;
|
padding-left : 40px; //Allow background color to extend into margins
|
||||||
margin-left: -40px;
|
margin-left : -40px;
|
||||||
padding-top:10px;
|
margin-top :-0.3cm;
|
||||||
margin-top:-8px;
|
padding-bottom :2px;
|
||||||
padding-bottom:10px;
|
margin-bottom :-20px;
|
||||||
margin-bottom:-20px;
|
background-image : linear-gradient(-45deg, #322814, #998250, #322814);
|
||||||
background-image: linear-gradient(-45deg, #322814, #998250, #322814);
|
background-clip : text;
|
||||||
background-clip: text;
|
-webkit-background-clip : text;
|
||||||
-webkit-background-clip: text;
|
color : rgba(0, 0, 0, 0);
|
||||||
color: rgba(0, 0, 0, 0);
|
|
||||||
}
|
}
|
||||||
&+p::first-line{
|
&+p::first-line{
|
||||||
font-variant : small-caps;
|
font-variant : small-caps;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
h2{
|
h2{
|
||||||
margin-top : 0px;
|
//margin-top : 0px; //Font is misaligned. Shift up slightly
|
||||||
margin-bottom : 0.05cm;
|
//margin-bottom : 0.05cm;
|
||||||
font-size : 0.75cm;
|
font-size : 0.75cm;
|
||||||
}
|
}
|
||||||
h3{
|
h3{
|
||||||
margin-top : -0.1cm;
|
//margin-top : -0.1cm; //Font is misaligned. Shift up slightly
|
||||||
margin-bottom : 0.1cm;
|
//margin-bottom : 0.1cm;
|
||||||
font-size : 0.575cm;
|
font-size : 0.575cm;
|
||||||
border-bottom : 2px solid @headerUnderline;
|
border-bottom : 2px solid @headerUnderline;
|
||||||
}
|
}
|
||||||
h4{
|
h4{
|
||||||
margin-top : -0.02cm;
|
//margin-top : -0.02cm; //Font is misaligned. Shift up slightly
|
||||||
margin-bottom : 0.02cm;
|
//margin-bottom : 0.02cm;
|
||||||
font-size : 0.458cm;
|
font-size : 0.458cm;
|
||||||
}
|
}
|
||||||
h5{
|
h5{
|
||||||
margin-top : -0.02cm;
|
//margin-top : -0.02cm; //Font is misaligned. Shift up slightly
|
||||||
margin-bottom : 0.02cm;
|
//margin-bottom : 0.02cm;
|
||||||
font-family : ScalySansSmallCapsRemake;
|
font-family : ScalySansSmallCapsRemake;
|
||||||
font-size : 0.423cm;
|
font-size : 0.423cm;
|
||||||
font-weight : 900;
|
font-weight : 900;
|
||||||
@@ -206,7 +213,6 @@ body {
|
|||||||
border-width : 11px;
|
border-width : 11px;
|
||||||
border-image : @noteBorderImage 12;
|
border-image : @noteBorderImage 12;
|
||||||
border-image-outset : 9px 0px;
|
border-image-outset : 9px 0px;
|
||||||
box-shadow : 1px 4px 14px #888;
|
|
||||||
position : absolute;
|
position : absolute;
|
||||||
width : 100%;
|
width : 100%;
|
||||||
height : 100%;
|
height : 100%;
|
||||||
@@ -219,6 +225,7 @@ body {
|
|||||||
margin-left : -0.1em;
|
margin-left : -0.1em;
|
||||||
margin-right : -0.1em;
|
margin-right : -0.1em;
|
||||||
background-color : @noteGreen;
|
background-color : @noteGreen;
|
||||||
|
filter : drop-shadow(1px 4px 6px #888);
|
||||||
padding : 0.5em 0.6em;
|
padding : 0.5em 0.6em;
|
||||||
& + * {
|
& + * {
|
||||||
margin-top : 1.3em;
|
margin-top : 1.3em;
|
||||||
@@ -239,7 +246,7 @@ body {
|
|||||||
// ************************************/
|
// ************************************/
|
||||||
.descriptive{
|
.descriptive{
|
||||||
.useSansSerif();
|
.useSansSerif();
|
||||||
display : block-inline;
|
display : inline-block;
|
||||||
margin-top : 1.4em;
|
margin-top : 1.4em;
|
||||||
background-color : #faf7ea;
|
background-color : #faf7ea;
|
||||||
font-family : ScalySansRemake;
|
font-family : ScalySansRemake;
|
||||||
@@ -247,7 +254,7 @@ body {
|
|||||||
border-width : 7px;
|
border-width : 7px;
|
||||||
border-image : @descriptiveBoxImage 12 stretch;
|
border-image : @descriptiveBoxImage 12 stretch;
|
||||||
border-image-outset : 4px;
|
border-image-outset : 4px;
|
||||||
box-shadow : 0px 0px 6px #faf7ea;
|
filter : drop-shadow(0 0 3px #faf7ea);
|
||||||
padding : 0.1em;
|
padding : 0.1em;
|
||||||
& + * {
|
& + * {
|
||||||
margin-top : 1.4em;
|
margin-top : 1.4em;
|
||||||
@@ -329,7 +336,7 @@ body {
|
|||||||
border-image-outset : 0px 2px;
|
border-image-outset : 0px 2px;
|
||||||
background-blend-mode : overlay;
|
background-blend-mode : overlay;
|
||||||
background-attachment : fixed;
|
background-attachment : fixed;
|
||||||
box-shadow : 1px 4px 14px #888;
|
filter : drop-shadow(1px 4px 6px #888);
|
||||||
padding : 4px 2px;
|
padding : 4px 2px;
|
||||||
margin : 0px -6px 1em;
|
margin : 0px -6px 1em;
|
||||||
}
|
}
|
||||||
@@ -383,16 +390,19 @@ body {
|
|||||||
dl {
|
dl {
|
||||||
color : @headerText;
|
color : @headerText;
|
||||||
}
|
}
|
||||||
|
hr:last-of-type~dl{
|
||||||
|
color : inherit; // After the HRs, hanging indents remain black.
|
||||||
|
}
|
||||||
|
|
||||||
// Monster Ability table
|
// Monster Ability table
|
||||||
hr + table:first-of-type{
|
hr + table:first-of-type{
|
||||||
margin : 0;
|
margin : 0;
|
||||||
column-span : 1;
|
column-span : none;
|
||||||
color : @headerText;
|
color : @headerText;
|
||||||
background-color : transparent;
|
background-color : transparent;
|
||||||
border-style : none;
|
border-style : none;
|
||||||
border-image : none;
|
border-image : none;
|
||||||
-webkit-column-span : 1;
|
-webkit-column-span : none;
|
||||||
tr {
|
tr {
|
||||||
background-color : transparent;
|
background-color : transparent;
|
||||||
}
|
}
|
||||||
@@ -404,7 +414,7 @@ body {
|
|||||||
|
|
||||||
//Full Width
|
//Full Width
|
||||||
.monster.wide{
|
.monster.wide{
|
||||||
.useColumns(0.96);
|
.useColumns(0.96, @fillMode: balance);
|
||||||
}
|
}
|
||||||
|
|
||||||
//*****************************
|
//*****************************
|
||||||
@@ -501,6 +511,9 @@ body {
|
|||||||
break-after : always;
|
break-after : always;
|
||||||
-moz-column-break-after : always;
|
-moz-column-break-after : always;
|
||||||
break-before : column;
|
break-before : column;
|
||||||
|
&+* {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//Avoid breaking up
|
//Avoid breaking up
|
||||||
blockquote,table{
|
blockquote,table{
|
||||||
@@ -561,11 +574,20 @@ body {
|
|||||||
column-span : all;
|
column-span : all;
|
||||||
-webkit-column-span : all;
|
-webkit-column-span : all;
|
||||||
-moz-column-span : all;
|
-moz-column-span : all;
|
||||||
|
display : block;
|
||||||
|
margin-bottom : 0.34cm;
|
||||||
|
&+* {
|
||||||
|
margin-top : 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//*****************************
|
//*****************************
|
||||||
// * CLASS TABLE
|
// * CLASS TABLE
|
||||||
// *****************************/
|
// *****************************/
|
||||||
.page .classTable{
|
.page .classTable{
|
||||||
|
th[colspan]:not([rowspan]) {
|
||||||
|
white-space : nowrap;
|
||||||
|
}
|
||||||
|
&.frame {
|
||||||
margin-top : 25px;
|
margin-top : 25px;
|
||||||
margin-bottom : 40px;
|
margin-bottom : 40px;
|
||||||
border-collapse : separate;
|
border-collapse : separate;
|
||||||
@@ -577,6 +599,7 @@ body {
|
|||||||
border-image-slice : 150 200 150 200;
|
border-image-slice : 150 200 150 200;
|
||||||
border-image-source : @frameBorderImage;
|
border-image-source : @frameBorderImage;
|
||||||
border-image-width : 47px;
|
border-image-width : 47px;
|
||||||
|
}
|
||||||
h5{
|
h5{
|
||||||
margin-bottom : 10px;
|
margin-bottom : 10px;
|
||||||
}
|
}
|
||||||
@@ -650,7 +673,7 @@ body {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
&.wide{
|
&.wide{
|
||||||
.useColumns(0.96);
|
.useColumns(0.96, @fillMode: balance);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -665,7 +688,6 @@ body {
|
|||||||
.inline-block {
|
.inline-block {
|
||||||
display : inline-block;
|
display : inline-block;
|
||||||
text-indent : initial;
|
text-indent : initial;
|
||||||
line-height : 1.3em;
|
|
||||||
}
|
}
|
||||||
div {
|
div {
|
||||||
column-gap : 0.5cm; //Default spacing if a div uses multicolumns
|
column-gap : 0.5cm; //Default spacing if a div uses multicolumns
|
||||||
@@ -680,15 +702,18 @@ body {
|
|||||||
line-height : 1.3em;
|
line-height : 1.3em;
|
||||||
padding-left : 1em;
|
padding-left : 1em;
|
||||||
text-indent : -1em;
|
text-indent : -1em;
|
||||||
}
|
& + * {
|
||||||
dl + * {
|
|
||||||
margin-top : 0.28cm;
|
margin-top : 0.28cm;
|
||||||
}
|
}
|
||||||
dl + p {
|
& + dl {
|
||||||
margin-top : 0.5em;
|
margin-top : 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dl + * {
|
||||||
|
margin-top : 0.17cm;
|
||||||
}
|
}
|
||||||
p + dl {
|
p + dl {
|
||||||
margin-top: -0.5em;
|
margin-top: 0.17cm;
|
||||||
}
|
}
|
||||||
dt {
|
dt {
|
||||||
display : inline;
|
display : inline;
|
||||||
|
|||||||
@@ -231,11 +231,11 @@ body {
|
|||||||
// Monster Ability table
|
// Monster Ability table
|
||||||
hr+table{
|
hr+table{
|
||||||
margin : 0;
|
margin : 0;
|
||||||
column-span : 1;
|
column-span : none;
|
||||||
background-color : transparent;
|
background-color : transparent;
|
||||||
border-style : none;
|
border-style : none;
|
||||||
border-image : none;
|
border-image : none;
|
||||||
-webkit-column-span : 1;
|
-webkit-column-span : none;
|
||||||
tbody{
|
tbody{
|
||||||
tr:nth-child(odd), tr:nth-child(even){
|
tr:nth-child(odd), tr:nth-child(even){
|
||||||
background-color : transparent;
|
background-color : transparent;
|
||||||
@@ -416,7 +416,7 @@ body {
|
|||||||
// * DESCRIPTIVE TEXT BOX
|
// * DESCRIPTIVE TEXT BOX
|
||||||
// ************************************/
|
// ************************************/
|
||||||
.phb .descriptive{
|
.phb .descriptive{
|
||||||
display : block-inline;
|
display : inline-block;
|
||||||
margin-bottom : 1em;
|
margin-bottom : 1em;
|
||||||
background-color : #faf7ea;
|
background-color : #faf7ea;
|
||||||
font-family : ScalySans;
|
font-family : ScalySans;
|
||||||
|
|||||||
Reference in New Issue
Block a user