mirror of
https://github.com/naturalcrit/homebrewery.git
synced 2026-01-02 02:02:43 +00:00
Merge branch 'master' into marked-nonbreaking-spaces
This commit is contained in:
@@ -10,7 +10,7 @@ orbs:
|
|||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
docker:
|
docker:
|
||||||
- image: cimg/node:20.17.0
|
- image: cimg/node:20.18.0
|
||||||
- image: mongo:4.4
|
- image: mongo:4.4
|
||||||
|
|
||||||
working_directory: ~/homebrewery
|
working_directory: ~/homebrewery
|
||||||
|
|||||||
@@ -144,3 +144,4 @@ your contribution to the project, please join our [gitter chat][gitter-url].
|
|||||||
[github-mark-duplicate-url]: https://docs.github.com/en/free-pro-team@latest/github/managing-your-work-on-github/about-duplicate-issues-and-pull-requests
|
[github-mark-duplicate-url]: https://docs.github.com/en/free-pro-team@latest/github/managing-your-work-on-github/about-duplicate-issues-and-pull-requests
|
||||||
[github-pr-docs-url]: https://docs.github.com/en/free-pro-team@latest/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request
|
[github-pr-docs-url]: https://docs.github.com/en/free-pro-team@latest/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request
|
||||||
[gitter-url]: https://gitter.im/naturalcrit/Lobby
|
[gitter-url]: https://gitter.im/naturalcrit/Lobby
|
||||||
|
|
||||||
|
|||||||
@@ -3,14 +3,15 @@ import React, { useEffect, useState } from 'react';
|
|||||||
const BrewUtils = require('./brewUtils/brewUtils.jsx');
|
const BrewUtils = require('./brewUtils/brewUtils.jsx');
|
||||||
const NotificationUtils = require('./notificationUtils/notificationUtils.jsx');
|
const NotificationUtils = require('./notificationUtils/notificationUtils.jsx');
|
||||||
import AuthorUtils from './authorUtils/authorUtils.jsx';
|
import AuthorUtils from './authorUtils/authorUtils.jsx';
|
||||||
|
import LockTools from './lockTools/lockTools.jsx';
|
||||||
|
|
||||||
const tabGroups = ['brew', 'notifications', 'authors'];
|
const tabGroups = ['brew', 'notifications', 'authors', 'locks'];
|
||||||
|
|
||||||
const Admin = ()=>{
|
const Admin = ()=>{
|
||||||
const [currentTab, setCurrentTab] = useState('brew');
|
const [currentTab, setCurrentTab] = useState('');
|
||||||
|
|
||||||
useEffect(()=>{
|
useEffect(()=>{
|
||||||
setCurrentTab(localStorage.getItem('hbAdminTab'));
|
setCurrentTab(localStorage.getItem('hbAdminTab') || 'brew');
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(()=>{
|
useEffect(()=>{
|
||||||
@@ -40,6 +41,7 @@ const Admin = ()=>{
|
|||||||
{currentTab === 'brew' && <BrewUtils />}
|
{currentTab === 'brew' && <BrewUtils />}
|
||||||
{currentTab === 'notifications' && <NotificationUtils />}
|
{currentTab === 'notifications' && <NotificationUtils />}
|
||||||
{currentTab === 'authors' && <AuthorUtils />}
|
{currentTab === 'authors' && <AuthorUtils />}
|
||||||
|
{currentTab === 'locks' && <LockTools />}
|
||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
342
client/admin/lockTools/lockTools.jsx
Normal file
342
client/admin/lockTools/lockTools.jsx
Normal file
@@ -0,0 +1,342 @@
|
|||||||
|
/*eslint max-lines: ["warn", {"max": 500, "skipBlankLines": true, "skipComments": true}]*/
|
||||||
|
require('./lockTools.less');
|
||||||
|
const React = require('react');
|
||||||
|
const createClass = require('create-react-class');
|
||||||
|
|
||||||
|
import request from '../../homebrew/utils/request-middleware.js';
|
||||||
|
|
||||||
|
const LockTools = createClass({
|
||||||
|
displayName : 'LockTools',
|
||||||
|
getInitialState : function() {
|
||||||
|
return {
|
||||||
|
fetching : false,
|
||||||
|
reviewCount : 0
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
componentDidMount : function() {
|
||||||
|
this.updateReviewCount();
|
||||||
|
},
|
||||||
|
|
||||||
|
updateReviewCount : async function() {
|
||||||
|
const newCount = await request.get('/api/lock/count')
|
||||||
|
.then((res)=>{return res.body?.count || 'Unknown';});
|
||||||
|
if(newCount != this.state.reviewCount){
|
||||||
|
this.setState({
|
||||||
|
reviewCount : newCount
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
updateLockData : function(lock){
|
||||||
|
this.setState({
|
||||||
|
lock : lock
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
render : function() {
|
||||||
|
return <div className='lockTools'>
|
||||||
|
<h2>Lock Count</h2>
|
||||||
|
<p>Number of brews currently locked: {this.state.reviewCount}</p>
|
||||||
|
<button onClick={this.updateReviewCount}>REFRESH</button>
|
||||||
|
<hr />
|
||||||
|
<LockTable title='Locked Brews' text='Total Locked Brews' resultName='lockedDocuments' fetchURL='/api/locks' propertyNames={['shareId', 'title']} loadBrew={this.updateLockData} ></LockTable>
|
||||||
|
<hr />
|
||||||
|
<LockTable title='Brews Awaiting Review' text='Total Reviews Waiting' resultName='reviewDocuments' fetchURL='/api/lock/reviews' propertyNames={['shareId', 'title']} loadBrew={this.updateLockData} ></LockTable>
|
||||||
|
<hr />
|
||||||
|
<LockBrew key={this.state.lock?.key || 0} lock={this.state.lock}></LockBrew>
|
||||||
|
<hr />
|
||||||
|
<div style={{ columns: 2 }}>
|
||||||
|
<LockLookup title='Unlock Brew' fetchURL='/api/unlock' updateFn={this.updateReviewCount}></LockLookup>
|
||||||
|
<LockLookup title='Clear Review Request' fetchURL='/api/lock/review/remove'></LockLookup>
|
||||||
|
</div>
|
||||||
|
<hr />
|
||||||
|
</div>;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const LockBrew = createClass({
|
||||||
|
displayName : 'LockBrew',
|
||||||
|
getInitialState : function() {
|
||||||
|
// Default values
|
||||||
|
return {
|
||||||
|
brewId : this.props.lock?.shareId || '',
|
||||||
|
code : this.props.lock?.code || 455,
|
||||||
|
editMessage : this.props.lock?.editMessage || '',
|
||||||
|
shareMessage : this.props.lock?.shareMessage || 'This Brew has been locked.',
|
||||||
|
result : {},
|
||||||
|
overwrite : false,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
handleChange : function(e, varName) {
|
||||||
|
const output = {};
|
||||||
|
output[varName] = e.target.value;
|
||||||
|
this.setState(output);
|
||||||
|
},
|
||||||
|
|
||||||
|
submit : function(e){
|
||||||
|
e.preventDefault();
|
||||||
|
if(!this.state.editMessage) return;
|
||||||
|
const newLock = {
|
||||||
|
overwrite : this.state.overwrite,
|
||||||
|
code : parseInt(this.state.code) || 100,
|
||||||
|
editMessage : this.state.editMessage,
|
||||||
|
shareMessage : this.state.shareMessage,
|
||||||
|
applied : new Date
|
||||||
|
};
|
||||||
|
|
||||||
|
request.post(`/api/lock/${this.state.brewId}`)
|
||||||
|
.send(newLock)
|
||||||
|
.set('Content-Type', 'application/json')
|
||||||
|
.then((response)=>{
|
||||||
|
this.setState({ result: response.body });
|
||||||
|
})
|
||||||
|
.catch((err)=>{
|
||||||
|
this.setState({ result: err.response.body });
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
renderInput : function (name) {
|
||||||
|
return <input type='text' name={name} value={this.state[name]} onChange={(e)=>this.handleChange(e, name)} autoComplete='off' required/>;
|
||||||
|
},
|
||||||
|
|
||||||
|
renderResult : function(){
|
||||||
|
return <>
|
||||||
|
<h3>Result:</h3>
|
||||||
|
<table>
|
||||||
|
<tbody>
|
||||||
|
{Object.keys(this.state.result).map((key, idx)=>{
|
||||||
|
return <tr key={`${idx}-row`}>
|
||||||
|
<td key={`${idx}-key`}>{key}</td>
|
||||||
|
<td key={`${idx}-value`}>{this.state.result[key].toString()}
|
||||||
|
</td>
|
||||||
|
</tr>;
|
||||||
|
})}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</>;
|
||||||
|
},
|
||||||
|
|
||||||
|
render : function() {
|
||||||
|
return <div className='lockBrew'>
|
||||||
|
<div className='lockForm'>
|
||||||
|
<h2>Lock Brew</h2>
|
||||||
|
<form onSubmit={this.submit}>
|
||||||
|
<label>
|
||||||
|
ID:
|
||||||
|
{this.renderInput('brewId')}
|
||||||
|
</label>
|
||||||
|
<br />
|
||||||
|
<label>
|
||||||
|
Error Code:
|
||||||
|
{this.renderInput('code')}
|
||||||
|
</label>
|
||||||
|
<br />
|
||||||
|
<label>
|
||||||
|
Private Message:
|
||||||
|
{this.renderInput('editMessage')}
|
||||||
|
</label>
|
||||||
|
<br />
|
||||||
|
<label>
|
||||||
|
Public Message:
|
||||||
|
{this.renderInput('shareMessage')}
|
||||||
|
</label>
|
||||||
|
<br />
|
||||||
|
<label className='checkbox'>
|
||||||
|
Overwrite
|
||||||
|
<input name='overwrite' className='checkbox' type='checkbox' value={this.state.overwrite} onClick={()=>{return this.setState((prevState)=>{return { overwrite: !prevState.overwrite };});}} />
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
<input type='submit' />
|
||||||
|
</label>
|
||||||
|
</form>
|
||||||
|
{this.state.result && this.renderResult()}
|
||||||
|
</div>
|
||||||
|
<div className='lockSuggestions'>
|
||||||
|
<h2>Suggestions</h2>
|
||||||
|
<div className='lockCodes'>
|
||||||
|
<h3>Codes</h3>
|
||||||
|
<ul>
|
||||||
|
<li>455 - Generic Lock</li>
|
||||||
|
<li>456 - Copyright issues</li>
|
||||||
|
<li>457 - Confidential Information Leakage</li>
|
||||||
|
<li>458 - Sensitive Personal Information</li>
|
||||||
|
<li>459 - Defamation or Libel</li>
|
||||||
|
<li>460 - Hate Speech or Discrimination</li>
|
||||||
|
<li>461 - Illegal Activities</li>
|
||||||
|
<li>462 - Malware or Phishing</li>
|
||||||
|
<li>463 - Plagiarism</li>
|
||||||
|
<li>465 - Misrepresentation</li>
|
||||||
|
<li>466 - Inappropriate Content</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div className='lockMessages'>
|
||||||
|
<h3>Messages</h3>
|
||||||
|
<ul>
|
||||||
|
<li><b>Private Message:</b> This is the private message that is ONLY displayed to the authors of the locked brew. This message MUST specify exactly what actions must be taken in order to have the brew unlocked.</li>
|
||||||
|
<li><b>Public Message:</b> This is the public message that is displayed to the EVERYONE that attempts to view the locked brew.</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const LockTable = createClass({
|
||||||
|
displayName : 'LockTable',
|
||||||
|
getDefaultProps : function() {
|
||||||
|
return {
|
||||||
|
title : '',
|
||||||
|
text : '',
|
||||||
|
fetchURL : '/api/locks',
|
||||||
|
resultName : '',
|
||||||
|
propertyNames : ['shareId'],
|
||||||
|
loadBrew : ()=>{}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
getInitialState : function() {
|
||||||
|
return {
|
||||||
|
result : '',
|
||||||
|
error : '',
|
||||||
|
searching : false
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
lockKey : React.createRef(0),
|
||||||
|
|
||||||
|
clickFn : function (){
|
||||||
|
this.setState({ searching: true, error: null });
|
||||||
|
|
||||||
|
request.get(this.props.fetchURL)
|
||||||
|
.then((res)=>this.setState({ result: res.body }))
|
||||||
|
.catch((err)=>this.setState({ result: err.response.body }))
|
||||||
|
.finally(()=>{
|
||||||
|
this.setState({ searching: false });
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
updateBrewLockData : function (lockData){
|
||||||
|
this.lockKey.current++;
|
||||||
|
const brewData = {
|
||||||
|
key : this.lockKey.current,
|
||||||
|
shareId : lockData.shareId,
|
||||||
|
code : lockData.lock.code,
|
||||||
|
editMessage : lockData.lock.editMessage,
|
||||||
|
shareMessage : lockData.lock.shareMessage
|
||||||
|
};
|
||||||
|
this.props.loadBrew(brewData);
|
||||||
|
},
|
||||||
|
|
||||||
|
render : function () {
|
||||||
|
return <>
|
||||||
|
<div className='brewsAwaitingReview'>
|
||||||
|
<div className='brewBlock'>
|
||||||
|
<h2>{this.props.title}</h2>
|
||||||
|
<button onClick={this.clickFn}>
|
||||||
|
REFRESH
|
||||||
|
<i className={`fas ${!this.state.searching ? 'fa-search' : 'fa-spin fa-spinner'}`} />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
{this.state.result[this.props.resultName] &&
|
||||||
|
<>
|
||||||
|
<p>{this.props.text}: {this.state.result[this.props.resultName].length}</p>
|
||||||
|
<table className='lockTable'>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
{this.props.propertyNames.map((name, idx)=>{
|
||||||
|
return <th key={idx}>{name}</th>;
|
||||||
|
})}
|
||||||
|
<th>clip</th>
|
||||||
|
<th>load</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{this.state.result[this.props.resultName].map((result, resultIdx)=>{
|
||||||
|
return <tr className='row' key={`${resultIdx}-row`}>
|
||||||
|
{this.props.propertyNames.map((name, nameIdx)=>{
|
||||||
|
return <td key={`${resultIdx}-${nameIdx}`}>
|
||||||
|
{result[name].toString()}
|
||||||
|
</td>;
|
||||||
|
})}
|
||||||
|
<td className='icon' title='Copy ID to Clipboard' onClick={()=>{navigator.clipboard.writeText(result.shareId.toString());}}><i className='fa-regular fa-clipboard'></i></td>
|
||||||
|
<td className='icon' title='View Lock details' onClick={()=>{this.updateBrewLockData(result);}}><i className='fa-regular fa-circle-down'></i></td>
|
||||||
|
</tr>;
|
||||||
|
})}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</>;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const LockLookup = createClass({
|
||||||
|
displayName : 'LockLookup',
|
||||||
|
getDefaultProps : function() {
|
||||||
|
return {
|
||||||
|
fetchURL : '/api/lookup'
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
getInitialState : function() {
|
||||||
|
return {
|
||||||
|
query : '',
|
||||||
|
result : '',
|
||||||
|
error : '',
|
||||||
|
searching : false
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
handleChange(e){
|
||||||
|
this.setState({ query: e.target.value });
|
||||||
|
},
|
||||||
|
|
||||||
|
clickFn(){
|
||||||
|
this.setState({ searching: true, error: null });
|
||||||
|
|
||||||
|
request.put(`${this.props.fetchURL}/${this.state.query}`)
|
||||||
|
.then((res)=>this.setState({ result: res.body }))
|
||||||
|
.catch((err)=>this.setState({ result: err.response.body }))
|
||||||
|
.finally(()=>{
|
||||||
|
this.setState({ searching: false });
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
renderResult : function(){
|
||||||
|
return <div className='lockLookup'>
|
||||||
|
<h3>Result:</h3>
|
||||||
|
<table>
|
||||||
|
<tbody>
|
||||||
|
{Object.keys(this.state.result).map((key, idx)=>{
|
||||||
|
return <tr key={`${idx}-row`}>
|
||||||
|
<td key={`${idx}-key`}>{key}</td>
|
||||||
|
<td key={`${idx}-value`}>{this.state.result[key].toString()}
|
||||||
|
</td>
|
||||||
|
</tr>;
|
||||||
|
})}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>;
|
||||||
|
},
|
||||||
|
|
||||||
|
render : function() {
|
||||||
|
return <div className='brewLookup'>
|
||||||
|
<h2>{this.props.title}</h2>
|
||||||
|
<input type='text' value={this.state.query} onChange={this.handleChange} placeholder='share id' />
|
||||||
|
<button onClick={this.clickFn}>
|
||||||
|
<i className={`fas ${!this.state.searching ? 'fa-search' : 'fa-spin fa-spinner'}`} />
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{this.state.error
|
||||||
|
&& <div className='error'>{this.state.error.toString()}</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
{this.state.result && this.renderResult()}
|
||||||
|
</div>;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = LockTools;
|
||||||
66
client/admin/lockTools/lockTools.less
Normal file
66
client/admin/lockTools/lockTools.less
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
.lockTools {
|
||||||
|
.lockBrew {
|
||||||
|
columns : 2;
|
||||||
|
|
||||||
|
.lockForm {
|
||||||
|
break-inside : avoid;
|
||||||
|
|
||||||
|
label {
|
||||||
|
display : inline-block;
|
||||||
|
width : 100%;
|
||||||
|
line-height : 2.25em;
|
||||||
|
text-align : right;
|
||||||
|
input {
|
||||||
|
float : right;
|
||||||
|
width : 65%;
|
||||||
|
margin-left : 10px;
|
||||||
|
}
|
||||||
|
&.checkbox {
|
||||||
|
line-height: 1.5em;
|
||||||
|
input {
|
||||||
|
width : 1.5em;
|
||||||
|
height : 1.5em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.lockSuggestions {
|
||||||
|
line-height : 1.2em;
|
||||||
|
break-inside : avoid;
|
||||||
|
columns : 2;
|
||||||
|
h2 { column-span : all; }
|
||||||
|
h3 { margin-top : 0px; }
|
||||||
|
b { font-weight : 600; }
|
||||||
|
|
||||||
|
.lockCodes { break-inside : avoid; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.lockTable {
|
||||||
|
cursor : default;
|
||||||
|
break-inside : avoid;
|
||||||
|
.row:hover {
|
||||||
|
color : #000000;
|
||||||
|
background-color : #CCCCCC;
|
||||||
|
}
|
||||||
|
.icon {
|
||||||
|
cursor : pointer;
|
||||||
|
&:hover { text-shadow : 0px 0px 6px black; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
th, td {
|
||||||
|
padding : 4px 10px;
|
||||||
|
text-align : center;
|
||||||
|
}
|
||||||
|
table, td { border : 1px solid #333333; }
|
||||||
|
|
||||||
|
.brewLookup {
|
||||||
|
min-height : 175px;
|
||||||
|
break-inside : avoid;
|
||||||
|
h2 { margin-top : 0px; }
|
||||||
|
}
|
||||||
|
|
||||||
|
button i { padding-left : 5px; }
|
||||||
|
}
|
||||||
@@ -13,6 +13,8 @@ const MetadataEditor = require('./metadataEditor/metadataEditor.jsx');
|
|||||||
const EDITOR_THEME_KEY = 'HOMEBREWERY-EDITOR-THEME';
|
const EDITOR_THEME_KEY = 'HOMEBREWERY-EDITOR-THEME';
|
||||||
|
|
||||||
const PAGEBREAK_REGEX_V3 = /^(?=\\page(?: *{[^\n{}]*})?$)/m;
|
const PAGEBREAK_REGEX_V3 = /^(?=\\page(?: *{[^\n{}]*})?$)/m;
|
||||||
|
const SNIPPETBREAK_REGEX_V3 = /^\\snippet\ .*$/;
|
||||||
|
const SNIPPETBAR_HEIGHT = 25;
|
||||||
const DEFAULT_STYLE_TEXT = dedent`
|
const DEFAULT_STYLE_TEXT = dedent`
|
||||||
/*=======--- Example CSS styling ---=======*/
|
/*=======--- Example CSS styling ---=======*/
|
||||||
/* Any CSS here will apply to your document! */
|
/* Any CSS here will apply to your document! */
|
||||||
@@ -21,6 +23,13 @@ const DEFAULT_STYLE_TEXT = dedent`
|
|||||||
color: black;
|
color: black;
|
||||||
}`;
|
}`;
|
||||||
|
|
||||||
|
const DEFAULT_SNIPPET_TEXT = dedent`
|
||||||
|
\snippet example snippet
|
||||||
|
|
||||||
|
The text between \`\snippet title\` lines will become a snippet of name \`title\` as this example provides.
|
||||||
|
|
||||||
|
This snippet is accessible in the brew tab, and will be inherited if the brew is used as a theme.
|
||||||
|
`;
|
||||||
let isJumping = false;
|
let isJumping = false;
|
||||||
|
|
||||||
const Editor = createClass({
|
const Editor = createClass({
|
||||||
@@ -35,6 +44,7 @@ const Editor = createClass({
|
|||||||
onTextChange : ()=>{},
|
onTextChange : ()=>{},
|
||||||
onStyleChange : ()=>{},
|
onStyleChange : ()=>{},
|
||||||
onMetaChange : ()=>{},
|
onMetaChange : ()=>{},
|
||||||
|
onSnipChange : ()=>{},
|
||||||
reportError : ()=>{},
|
reportError : ()=>{},
|
||||||
|
|
||||||
onCursorPageChange : ()=>{},
|
onCursorPageChange : ()=>{},
|
||||||
@@ -51,7 +61,7 @@ const Editor = createClass({
|
|||||||
getInitialState : function() {
|
getInitialState : function() {
|
||||||
return {
|
return {
|
||||||
editorTheme : this.props.editorTheme,
|
editorTheme : this.props.editorTheme,
|
||||||
view : 'text' //'text', 'style', 'meta'
|
view : 'text' //'text', 'style', 'meta', 'snippet'
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -61,6 +71,7 @@ const Editor = createClass({
|
|||||||
isText : function() {return this.state.view == 'text';},
|
isText : function() {return this.state.view == 'text';},
|
||||||
isStyle : function() {return this.state.view == 'style';},
|
isStyle : function() {return this.state.view == 'style';},
|
||||||
isMeta : function() {return this.state.view == 'meta';},
|
isMeta : function() {return this.state.view == 'meta';},
|
||||||
|
isSnip : function() {return this.state.view == 'snippet';},
|
||||||
|
|
||||||
componentDidMount : function() {
|
componentDidMount : function() {
|
||||||
|
|
||||||
@@ -131,6 +142,7 @@ const Editor = createClass({
|
|||||||
|
|
||||||
handleViewChange : function(newView){
|
handleViewChange : function(newView){
|
||||||
this.props.setMoveArrows(newView === 'text');
|
this.props.setMoveArrows(newView === 'text');
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
view : newView
|
view : newView
|
||||||
}, ()=>{
|
}, ()=>{
|
||||||
@@ -140,7 +152,7 @@ const Editor = createClass({
|
|||||||
|
|
||||||
highlightCustomMarkdown : function(){
|
highlightCustomMarkdown : function(){
|
||||||
if(!this.codeEditor.current) return;
|
if(!this.codeEditor.current) return;
|
||||||
if(this.state.view === 'text') {
|
if((this.state.view === 'text') ||(this.state.view === 'snippet')) {
|
||||||
const codeMirror = this.codeEditor.current.codeMirror;
|
const codeMirror = this.codeEditor.current.codeMirror;
|
||||||
|
|
||||||
codeMirror.operation(()=>{ // Batch CodeMirror styling
|
codeMirror.operation(()=>{ // Batch CodeMirror styling
|
||||||
@@ -159,12 +171,18 @@ const Editor = createClass({
|
|||||||
|
|
||||||
for (let i=customHighlights.length - 1;i>=0;i--) customHighlights[i].clear();
|
for (let i=customHighlights.length - 1;i>=0;i--) customHighlights[i].clear();
|
||||||
|
|
||||||
|
let userSnippetCount = 1; // start snippet count from snippet 1
|
||||||
let editorPageCount = 1; // start page count from page 1
|
let editorPageCount = 1; // start page count from page 1
|
||||||
|
|
||||||
_.forEach(this.props.brew.text.split('\n'), (line, lineNumber)=>{
|
const whichSource = this.state.view === 'text' ? this.props.brew.text : this.props.brew.snippets;
|
||||||
|
_.forEach(whichSource?.split('\n'), (line, lineNumber)=>{
|
||||||
|
|
||||||
|
const tabHighlight = this.state.view === 'text' ? 'pageLine' : 'snippetLine';
|
||||||
|
const textOrSnip = this.state.view === 'text';
|
||||||
|
|
||||||
//reset custom line styles
|
//reset custom line styles
|
||||||
codeMirror.removeLineClass(lineNumber, 'background', 'pageLine');
|
codeMirror.removeLineClass(lineNumber, 'background', 'pageLine');
|
||||||
|
codeMirror.removeLineClass(lineNumber, 'background', 'snippetLine');
|
||||||
codeMirror.removeLineClass(lineNumber, 'text');
|
codeMirror.removeLineClass(lineNumber, 'text');
|
||||||
codeMirror.removeLineClass(lineNumber, 'wrap', 'sourceMoveFlash');
|
codeMirror.removeLineClass(lineNumber, 'wrap', 'sourceMoveFlash');
|
||||||
|
|
||||||
@@ -175,22 +193,24 @@ const Editor = createClass({
|
|||||||
|
|
||||||
// Styling for \page breaks
|
// Styling for \page breaks
|
||||||
if((this.props.renderer == 'legacy' && line.includes('\\page')) ||
|
if((this.props.renderer == 'legacy' && line.includes('\\page')) ||
|
||||||
(this.props.renderer == 'V3' && line.match(PAGEBREAK_REGEX_V3))) {
|
(this.props.renderer == 'V3' && line.match(textOrSnip ? PAGEBREAK_REGEX_V3 : SNIPPETBREAK_REGEX_V3))) {
|
||||||
|
|
||||||
if(lineNumber > 0) // Since \page is optional on first line of document,
|
if((lineNumber > 0) && (textOrSnip)) // Since \page is optional on first line of document,
|
||||||
editorPageCount += 1; // don't use it to increment page count; stay at 1
|
editorPageCount += 1; // don't use it to increment page count; stay at 1
|
||||||
|
else if(this.state.view !== 'text') userSnippetCount += 1;
|
||||||
|
|
||||||
// add back the original class 'background' but also add the new class '.pageline'
|
// add back the original class 'background' but also add the new class '.pageline'
|
||||||
codeMirror.addLineClass(lineNumber, 'background', 'pageLine');
|
codeMirror.addLineClass(lineNumber, 'background', tabHighlight);
|
||||||
const pageCountElement = Object.assign(document.createElement('span'), {
|
const pageCountElement = Object.assign(document.createElement('span'), {
|
||||||
className : 'editor-page-count',
|
className : 'editor-page-count',
|
||||||
textContent : editorPageCount
|
textContent : textOrSnip ? editorPageCount : userSnippetCount
|
||||||
});
|
});
|
||||||
codeMirror.setBookmark({ line: lineNumber, ch: line.length }, pageCountElement);
|
codeMirror.setBookmark({ line: lineNumber, ch: line.length }, pageCountElement);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// New Codemirror styling for V3 renderer
|
// New Codemirror styling for V3 renderer
|
||||||
if(this.props.renderer == 'V3') {
|
if(this.props.renderer === 'V3') {
|
||||||
if(line.match(/^\\column$/)){
|
if(line.match(/^\\column$/)){
|
||||||
codeMirror.addLineClass(lineNumber, 'text', 'columnSplit');
|
codeMirror.addLineClass(lineNumber, 'text', 'columnSplit');
|
||||||
}
|
}
|
||||||
@@ -446,6 +466,21 @@ const Editor = createClass({
|
|||||||
userThemes={this.props.userThemes}/>
|
userThemes={this.props.userThemes}/>
|
||||||
</>;
|
</>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(this.isSnip()){
|
||||||
|
if(!this.props.brew.snippets) { this.props.brew.snippets = DEFAULT_SNIPPET_TEXT; }
|
||||||
|
return <>
|
||||||
|
<CodeEditor key='codeEditor'
|
||||||
|
ref={this.codeEditor}
|
||||||
|
language='gfm'
|
||||||
|
view={this.state.view}
|
||||||
|
value={this.props.brew.snippets}
|
||||||
|
onChange={this.props.onSnipChange}
|
||||||
|
enableFolding={true}
|
||||||
|
editorTheme={this.state.editorTheme}
|
||||||
|
rerenderParent={this.rerenderParent} />
|
||||||
|
</>;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
redo : function(){
|
redo : function(){
|
||||||
@@ -486,7 +521,7 @@ const Editor = createClass({
|
|||||||
historySize={this.historySize()}
|
historySize={this.historySize()}
|
||||||
currentEditorTheme={this.state.editorTheme}
|
currentEditorTheme={this.state.editorTheme}
|
||||||
updateEditorTheme={this.updateEditorTheme}
|
updateEditorTheme={this.updateEditorTheme}
|
||||||
snippetBundle={this.props.snippetBundle}
|
themeBundle={this.props.themeBundle}
|
||||||
cursorPos={this.codeEditor.current?.getCursorPosition() || {}}
|
cursorPos={this.codeEditor.current?.getCursorPosition() || {}}
|
||||||
updateBrew={this.props.updateBrew}
|
updateBrew={this.props.updateBrew}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
.codeEditor {
|
.codeEditor {
|
||||||
height : 100%;
|
height : 100%;
|
||||||
.CodeMirror { height : 100%; }
|
.CodeMirror { height : 100%; }
|
||||||
.pageLine {
|
.pageLine, .snippetLine {
|
||||||
background : #33333328;
|
background : #33333328;
|
||||||
border-top : #333399 solid 1px;
|
border-top : #333399 solid 1px;
|
||||||
}
|
}
|
||||||
@@ -15,6 +15,10 @@
|
|||||||
float : right;
|
float : right;
|
||||||
color : grey;
|
color : grey;
|
||||||
}
|
}
|
||||||
|
.editor-snippet-count {
|
||||||
|
float : right;
|
||||||
|
color : grey;
|
||||||
|
}
|
||||||
.columnSplit {
|
.columnSplit {
|
||||||
font-style : italic;
|
font-style : italic;
|
||||||
color : grey;
|
color : grey;
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ const _ = require('lodash');
|
|||||||
const cx = require('classnames');
|
const cx = require('classnames');
|
||||||
|
|
||||||
import { loadHistory } from '../../utils/versionHistory.js';
|
import { loadHistory } from '../../utils/versionHistory.js';
|
||||||
|
import { brewSnippetsToJSON } from '../../../../shared/helpers.js';
|
||||||
|
|
||||||
//Import all themes
|
//Import all themes
|
||||||
const ThemeSnippets = {};
|
const ThemeSnippets = {};
|
||||||
@@ -40,7 +41,7 @@ const Snippetbar = createClass({
|
|||||||
unfoldCode : ()=>{},
|
unfoldCode : ()=>{},
|
||||||
updateEditorTheme : ()=>{},
|
updateEditorTheme : ()=>{},
|
||||||
cursorPos : {},
|
cursorPos : {},
|
||||||
snippetBundle : [],
|
themeBundle : [],
|
||||||
updateBrew : ()=>{}
|
updateBrew : ()=>{}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@@ -64,7 +65,10 @@ const Snippetbar = createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
componentDidUpdate : async function(prevProps, prevState) {
|
componentDidUpdate : async function(prevProps, prevState) {
|
||||||
if(prevProps.renderer != this.props.renderer || prevProps.theme != this.props.theme || prevProps.snippetBundle != this.props.snippetBundle) {
|
if(prevProps.renderer != this.props.renderer ||
|
||||||
|
prevProps.theme != this.props.theme ||
|
||||||
|
prevProps.themeBundle != this.props.themeBundle ||
|
||||||
|
prevProps.brew.snippets != this.props.brew.snippets) {
|
||||||
this.setState({
|
this.setState({
|
||||||
snippets : this.compileSnippets()
|
snippets : this.compileSnippets()
|
||||||
});
|
});
|
||||||
@@ -97,7 +101,7 @@ const Snippetbar = createClass({
|
|||||||
if(key == 'snippets') {
|
if(key == 'snippets') {
|
||||||
const result = _.reverse(_.unionBy(_.reverse(newValue), _.reverse(oldValue), 'name')); // Join snippets together, with preference for the child theme over the parent theme
|
const result = _.reverse(_.unionBy(_.reverse(newValue), _.reverse(oldValue), 'name')); // Join snippets together, with preference for the child theme over the parent theme
|
||||||
return result.filter((snip)=>snip.gen || snip.subsnippets);
|
return result.filter((snip)=>snip.gen || snip.subsnippets);
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
compileSnippets : function() {
|
compileSnippets : function() {
|
||||||
@@ -105,15 +109,21 @@ const Snippetbar = createClass({
|
|||||||
|
|
||||||
let oldSnippets = _.keyBy(compiledSnippets, 'groupName');
|
let oldSnippets = _.keyBy(compiledSnippets, 'groupName');
|
||||||
|
|
||||||
for (let snippets of this.props.snippetBundle) {
|
if(this.props.themeBundle.snippets) {
|
||||||
if(typeof(snippets) == 'string') // load staticThemes as needed; they were sent as just a file name
|
for (let snippets of this.props.themeBundle.snippets) {
|
||||||
snippets = ThemeSnippets[snippets];
|
if(typeof(snippets) == 'string') // load staticThemes as needed; they were sent as just a file name
|
||||||
|
snippets = ThemeSnippets[snippets];
|
||||||
|
|
||||||
const newSnippets = _.keyBy(_.cloneDeep(snippets), 'groupName');
|
const newSnippets = _.keyBy(_.cloneDeep(snippets), 'groupName');
|
||||||
compiledSnippets = _.values(_.mergeWith(oldSnippets, newSnippets, this.mergeCustomizer));
|
compiledSnippets = _.values(_.mergeWith(oldSnippets, newSnippets, this.mergeCustomizer));
|
||||||
|
|
||||||
oldSnippets = _.keyBy(compiledSnippets, 'groupName');
|
oldSnippets = _.keyBy(compiledSnippets, 'groupName');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const userSnippetsasJSON = brewSnippetsToJSON(this.props.brew.title || 'New Document', this.props.brew.snippets, this.props.themeBundle.snippets);
|
||||||
|
compiledSnippets.push(userSnippetsasJSON);
|
||||||
|
|
||||||
return compiledSnippets;
|
return compiledSnippets;
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -207,8 +217,6 @@ const Snippetbar = createClass({
|
|||||||
renderEditorButtons : function(){
|
renderEditorButtons : function(){
|
||||||
if(!this.props.showEditButtons) return;
|
if(!this.props.showEditButtons) return;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='editors'>
|
<div className='editors'>
|
||||||
{this.props.view !== 'meta' && <><div className='historyTools'>
|
{this.props.view !== 'meta' && <><div className='historyTools'>
|
||||||
@@ -242,7 +250,6 @@ const Snippetbar = createClass({
|
|||||||
</div>
|
</div>
|
||||||
</div></>}
|
</div></>}
|
||||||
|
|
||||||
|
|
||||||
<div className='tabs'>
|
<div className='tabs'>
|
||||||
<div className={cx('text', { selected: this.props.view === 'text' })}
|
<div className={cx('text', { selected: this.props.view === 'text' })}
|
||||||
onClick={()=>this.props.onViewChange('text')}>
|
onClick={()=>this.props.onViewChange('text')}>
|
||||||
@@ -252,6 +259,10 @@ const Snippetbar = createClass({
|
|||||||
onClick={()=>this.props.onViewChange('style')}>
|
onClick={()=>this.props.onViewChange('style')}>
|
||||||
<i className='fa fa-paint-brush' />
|
<i className='fa fa-paint-brush' />
|
||||||
</div>
|
</div>
|
||||||
|
<div className={cx('snippet', { selected: this.props.view === 'snippet' })}
|
||||||
|
onClick={()=>this.props.onViewChange('snippet')}>
|
||||||
|
<i className='fas fa-th-list' />
|
||||||
|
</div>
|
||||||
<div className={cx('meta', { selected: this.props.view === 'meta' })}
|
<div className={cx('meta', { selected: this.props.view === 'meta' })}
|
||||||
onClick={()=>this.props.onViewChange('meta')}>
|
onClick={()=>this.props.onViewChange('meta')}>
|
||||||
<i className='fas fa-info-circle' />
|
<i className='fas fa-info-circle' />
|
||||||
@@ -272,11 +283,6 @@ const Snippetbar = createClass({
|
|||||||
|
|
||||||
module.exports = Snippetbar;
|
module.exports = Snippetbar;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const SnippetGroup = createClass({
|
const SnippetGroup = createClass({
|
||||||
displayName : 'SnippetGroup',
|
displayName : 'SnippetGroup',
|
||||||
getDefaultProps : function() {
|
getDefaultProps : function() {
|
||||||
@@ -310,7 +316,8 @@ const SnippetGroup = createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
render : function(){
|
render : function(){
|
||||||
return <div className='snippetGroup snippetBarButton'>
|
const snippetGroup = `snippetGroup snippetBarButton ${this.props.snippets.length === 0 ? 'disabledSnippets' : ''}`;
|
||||||
|
return <div className={snippetGroup}>
|
||||||
<div className='text'>
|
<div className='text'>
|
||||||
<i className={this.props.icon} />
|
<i className={this.props.icon} />
|
||||||
<span className='groupName'>{this.props.groupName}</span>
|
<span className='groupName'>{this.props.groupName}</span>
|
||||||
|
|||||||
@@ -14,13 +14,13 @@
|
|||||||
.snippets {
|
.snippets {
|
||||||
display : flex;
|
display : flex;
|
||||||
justify-content : flex-start;
|
justify-content : flex-start;
|
||||||
min-width : 327.58px;
|
min-width : 432.18px; //must be controlled every time an item is added, must be hardcoded for the wrapping as it is applied
|
||||||
}
|
}
|
||||||
|
|
||||||
.editors {
|
.editors {
|
||||||
display : flex;
|
display : flex;
|
||||||
justify-content : flex-end;
|
justify-content : flex-end;
|
||||||
min-width : 225px;
|
min-width : 250px; //must be controlled every time an item is added, must be hardcoded for the wrapping as it is applied
|
||||||
|
|
||||||
&:only-child {min-width : unset; margin-left : auto;}
|
&:only-child {min-width : unset; margin-left : auto;}
|
||||||
|
|
||||||
@@ -51,6 +51,9 @@
|
|||||||
&.meta {
|
&.meta {
|
||||||
.tooltipLeft('Properties');
|
.tooltipLeft('Properties');
|
||||||
}
|
}
|
||||||
|
&.snip {
|
||||||
|
.tooltipLeft('Snippets');
|
||||||
|
}
|
||||||
&.undo {
|
&.undo {
|
||||||
.tooltipLeft('Undo');
|
.tooltipLeft('Undo');
|
||||||
font-size : 0.75em;
|
font-size : 0.75em;
|
||||||
@@ -226,8 +229,15 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.disabledSnippets {
|
||||||
|
color: grey;
|
||||||
|
cursor: not-allowed;
|
||||||
|
|
||||||
|
&:hover { background-color: #DDDDDD;}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@container editor (width < 553px) {
|
@container editor (width < 683px) {
|
||||||
.snippetBar {
|
.snippetBar {
|
||||||
.editors {
|
.editors {
|
||||||
flex : 1;
|
flex : 1;
|
||||||
|
|||||||
@@ -150,6 +150,18 @@ const EditPage = createClass({
|
|||||||
}), ()=>{if(this.state.autoSave) this.trySave();});
|
}), ()=>{if(this.state.autoSave) this.trySave();});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
handleSnipChange : function(snippet){
|
||||||
|
//If there are errors, run the validator on every change to give quick feedback
|
||||||
|
let htmlErrors = this.state.htmlErrors;
|
||||||
|
if(htmlErrors.length) htmlErrors = Markdown.validate(snippet);
|
||||||
|
|
||||||
|
this.setState((prevState)=>({
|
||||||
|
brew : { ...prevState.brew, snippets: snippet },
|
||||||
|
isPending : true,
|
||||||
|
htmlErrors : htmlErrors,
|
||||||
|
}), ()=>{if(this.state.autoSave) this.trySave();});
|
||||||
|
},
|
||||||
|
|
||||||
handleStyleChange : function(style){
|
handleStyleChange : function(style){
|
||||||
this.setState((prevState)=>({
|
this.setState((prevState)=>({
|
||||||
brew : { ...prevState.brew, style: style }
|
brew : { ...prevState.brew, style: style }
|
||||||
@@ -443,7 +455,7 @@ const EditPage = createClass({
|
|||||||
<Meta name='robots' content='noindex, nofollow' />
|
<Meta name='robots' content='noindex, nofollow' />
|
||||||
{this.renderNavbar()}
|
{this.renderNavbar()}
|
||||||
|
|
||||||
{this.props.brew.lock && <LockNotification shareId={this.props.brew.shareId} message={this.props.brew.lock.editMessage} />}
|
{this.props.brew.lock && <LockNotification shareId={this.props.brew.shareId} message={this.props.brew.lock.editMessage} reviewRequested={this.props.brew.lock.reviewRequested} />}
|
||||||
<div className='content'>
|
<div className='content'>
|
||||||
<SplitPane onDragFinish={this.handleSplitMove}>
|
<SplitPane onDragFinish={this.handleSplitMove}>
|
||||||
<Editor
|
<Editor
|
||||||
@@ -451,12 +463,12 @@ const EditPage = createClass({
|
|||||||
brew={this.state.brew}
|
brew={this.state.brew}
|
||||||
onTextChange={this.handleTextChange}
|
onTextChange={this.handleTextChange}
|
||||||
onStyleChange={this.handleStyleChange}
|
onStyleChange={this.handleStyleChange}
|
||||||
|
onSnipChange={this.handleSnipChange}
|
||||||
onMetaChange={this.handleMetaChange}
|
onMetaChange={this.handleMetaChange}
|
||||||
reportError={this.errorReported}
|
reportError={this.errorReported}
|
||||||
renderer={this.state.brew.renderer}
|
renderer={this.state.brew.renderer}
|
||||||
userThemes={this.props.userThemes}
|
userThemes={this.props.userThemes}
|
||||||
themeBundle={this.state.themeBundle}
|
themeBundle={this.state.themeBundle}
|
||||||
snippetBundle={this.state.themeBundle.snippets}
|
|
||||||
updateBrew={this.updateBrew}
|
updateBrew={this.updateBrew}
|
||||||
onCursorPageChange={this.handleEditorCursorPageChange}
|
onCursorPageChange={this.handleEditorCursorPageChange}
|
||||||
onViewPageChange={this.handleEditorViewPageChange}
|
onViewPageChange={this.handleEditorViewPageChange}
|
||||||
|
|||||||
@@ -1,17 +1,30 @@
|
|||||||
require('./lockNotification.less');
|
import './lockNotification.less';
|
||||||
const React = require('react');
|
import * as React from 'react';
|
||||||
|
import request from '../../../utils/request-middleware.js';
|
||||||
import Dialog from '../../../../components/dialog.jsx';
|
import Dialog from '../../../../components/dialog.jsx';
|
||||||
|
|
||||||
function LockNotification(props) {
|
function LockNotification(props) {
|
||||||
props = {
|
props = {
|
||||||
shareId : 0,
|
shareId : 0,
|
||||||
disableLock : ()=>{},
|
disableLock : ()=>{},
|
||||||
message : '',
|
lock : {},
|
||||||
|
message : 'Unable to retrieve Lock Message',
|
||||||
|
reviewRequested : false,
|
||||||
...props
|
...props
|
||||||
};
|
};
|
||||||
|
|
||||||
const removeLock = ()=>{
|
const [reviewState, setReviewState] = React.useState(props.reviewRequested);
|
||||||
alert(`Not yet implemented - ID ${props.shareId}`);
|
|
||||||
|
const removeLock = async ()=>{
|
||||||
|
await request.put(`/api/lock/review/request/${props.shareId}`)
|
||||||
|
.then(()=>{
|
||||||
|
setReviewState(true);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const renderReviewButton = function(){
|
||||||
|
if(reviewState){ return <button className='inactive'>REVIEW REQUESTED</button>; };
|
||||||
|
return <button onClick={removeLock}>REQUEST LOCK REMOVAL</button>;
|
||||||
};
|
};
|
||||||
|
|
||||||
return <Dialog className='lockNotification' blocking closeText='CONTINUE TO EDITOR' >
|
return <Dialog className='lockNotification' blocking closeText='CONTINUE TO EDITOR' >
|
||||||
@@ -19,11 +32,11 @@ function LockNotification(props) {
|
|||||||
<p>This brew been locked by the Administrators. It will not be accessible by any method other than the Editor until the lock is removed.</p>
|
<p>This brew been locked by the Administrators. It will not be accessible by any method other than the Editor until the lock is removed.</p>
|
||||||
<hr />
|
<hr />
|
||||||
<h3>LOCK REASON</h3>
|
<h3>LOCK REASON</h3>
|
||||||
<p>{props.message || 'Unable to retrieve Lock Message'}</p>
|
<p>{props.message}</p>
|
||||||
<hr />
|
<hr />
|
||||||
<p>Once you have resolved this issue, click REQUEST LOCK REMOVAL to notify the Administrators for review.</p>
|
<p>Once you have resolved this issue, click REQUEST LOCK REMOVAL to notify the Administrators for review.</p>
|
||||||
<p>Click CONTINUE TO EDITOR to temporarily hide this notification; it will reappear the next time the page is reloaded.</p>
|
<p>Click CONTINUE TO EDITOR to temporarily hide this notification; it will reappear the next time the page is reloaded.</p>
|
||||||
<button onClick={removeLock}>REQUEST LOCK REMOVAL</button>
|
{renderReviewButton()}
|
||||||
</Dialog>;
|
</Dialog>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -11,10 +11,12 @@
|
|||||||
&::backdrop { background-color : #000000AA; }
|
&::backdrop { background-color : #000000AA; }
|
||||||
|
|
||||||
button {
|
button {
|
||||||
|
padding : 2px 15px;
|
||||||
margin : 10px;
|
margin : 10px;
|
||||||
color : white;
|
color : white;
|
||||||
background-color : #333333;
|
background-color : #333333;
|
||||||
|
|
||||||
|
&.inactive,
|
||||||
&:hover { background-color : #777777; }
|
&:hover { background-color : #777777; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -194,13 +194,47 @@ const errorIndex = (props)=>{
|
|||||||
|
|
||||||
**Brew ID:** ${props.brew.brewId}
|
**Brew ID:** ${props.brew.brewId}
|
||||||
|
|
||||||
**Brew Title:** ${escape(props.brew.brewTitle)}`,
|
**Brew Title:** ${escape(props.brew.brewTitle)}
|
||||||
|
|
||||||
|
**Brew Authors:** ${props.brew.authors?.map((author)=>{return `[${author}](/user/${author})`;}).join(', ') || 'Unable to list authors'}`,
|
||||||
|
|
||||||
// ####### Admin page error #######
|
// ####### Admin page error #######
|
||||||
'52' : dedent`
|
'52' : dedent`
|
||||||
## Access Denied
|
## Access Denied
|
||||||
You need to provide correct administrator credentials to access this page.`,
|
You need to provide correct administrator credentials to access this page.`,
|
||||||
|
|
||||||
|
// ####### Lock Errors
|
||||||
|
|
||||||
|
'60' : dedent`Lock Error: General`,
|
||||||
|
|
||||||
|
'61' : dedent`Lock Get Error: Unable to get lock count`,
|
||||||
|
|
||||||
|
'62' : dedent`Lock Set Error: Cannot lock`,
|
||||||
|
|
||||||
|
'63' : dedent`Lock Set Error: Brew not found`,
|
||||||
|
|
||||||
|
'64' : dedent`Lock Set Error: Already locked`,
|
||||||
|
|
||||||
|
'65' : dedent`Lock Remove Error: Cannot unlock`,
|
||||||
|
|
||||||
|
'66' : dedent`Lock Remove Error: Brew not found`,
|
||||||
|
|
||||||
|
'67' : dedent`Lock Remove Error: Not locked`,
|
||||||
|
|
||||||
|
'68' : dedent`Lock Get Review Error: Cannot get review requests`,
|
||||||
|
|
||||||
|
'69' : dedent`Lock Set Review Error: Cannot set review request`,
|
||||||
|
|
||||||
|
'70' : dedent`Lock Set Review Error: Brew not found`,
|
||||||
|
|
||||||
|
'71' : dedent`Lock Set Review Error: Review already requested`,
|
||||||
|
|
||||||
|
'72' : dedent`Lock Remove Review Error: Cannot clear review request`,
|
||||||
|
|
||||||
|
'73' : dedent`Lock Remove Review Error: Brew not found`,
|
||||||
|
|
||||||
|
// ####### Other Errors
|
||||||
|
|
||||||
'90' : dedent` An unexpected error occurred while looking for these brews.
|
'90' : dedent` An unexpected error occurred while looking for these brews.
|
||||||
Try again in a few minutes.`,
|
Try again in a few minutes.`,
|
||||||
|
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ const HomePage = createClass({
|
|||||||
onTextChange={this.handleTextChange}
|
onTextChange={this.handleTextChange}
|
||||||
renderer={this.state.brew.renderer}
|
renderer={this.state.brew.renderer}
|
||||||
showEditButtons={false}
|
showEditButtons={false}
|
||||||
snippetBundle={this.state.themeBundle.snippets}
|
themeBundle={this.state.themeBundle}
|
||||||
onCursorPageChange={this.handleEditorCursorPageChange}
|
onCursorPageChange={this.handleEditorCursorPageChange}
|
||||||
onViewPageChange={this.handleEditorViewPageChange}
|
onViewPageChange={this.handleEditorViewPageChange}
|
||||||
currentEditorViewPageNum={this.state.currentEditorViewPageNum}
|
currentEditorViewPageNum={this.state.currentEditorViewPageNum}
|
||||||
|
|||||||
@@ -141,6 +141,18 @@ const NewPage = createClass({
|
|||||||
localStorage.setItem(STYLEKEY, style);
|
localStorage.setItem(STYLEKEY, style);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
handleSnipChange : function(snippet){
|
||||||
|
//If there are errors, run the validator on every change to give quick feedback
|
||||||
|
let htmlErrors = this.state.htmlErrors;
|
||||||
|
if(htmlErrors.length) htmlErrors = Markdown.validate(snippet);
|
||||||
|
|
||||||
|
this.setState((prevState)=>({
|
||||||
|
brew : { ...prevState.brew, snippets: snippet },
|
||||||
|
isPending : true,
|
||||||
|
htmlErrors : htmlErrors,
|
||||||
|
}), ()=>{if(this.state.autoSave) this.trySave();});
|
||||||
|
},
|
||||||
|
|
||||||
handleMetaChange : function(metadata, field=undefined){
|
handleMetaChange : function(metadata, field=undefined){
|
||||||
if(field == 'theme' || field == 'renderer') // Fetch theme bundle only if theme or renderer was changed
|
if(field == 'theme' || field == 'renderer') // Fetch theme bundle only if theme or renderer was changed
|
||||||
fetchThemeBundle(this, metadata.renderer, metadata.theme);
|
fetchThemeBundle(this, metadata.renderer, metadata.theme);
|
||||||
@@ -231,10 +243,10 @@ const NewPage = createClass({
|
|||||||
onTextChange={this.handleTextChange}
|
onTextChange={this.handleTextChange}
|
||||||
onStyleChange={this.handleStyleChange}
|
onStyleChange={this.handleStyleChange}
|
||||||
onMetaChange={this.handleMetaChange}
|
onMetaChange={this.handleMetaChange}
|
||||||
|
onSnipChange={this.handleSnipChange}
|
||||||
renderer={this.state.brew.renderer}
|
renderer={this.state.brew.renderer}
|
||||||
userThemes={this.props.userThemes}
|
userThemes={this.props.userThemes}
|
||||||
themeBundle={this.state.themeBundle}
|
themeBundle={this.state.themeBundle}
|
||||||
snippetBundle={this.state.themeBundle.snippets}
|
|
||||||
onCursorPageChange={this.handleEditorCursorPageChange}
|
onCursorPageChange={this.handleEditorCursorPageChange}
|
||||||
onViewPageChange={this.handleEditorViewPageChange}
|
onViewPageChange={this.handleEditorViewPageChange}
|
||||||
currentEditorViewPageNum={this.state.currentEditorViewPageNum}
|
currentEditorViewPageNum={this.state.currentEditorViewPageNum}
|
||||||
|
|||||||
225
package-lock.json
generated
225
package-lock.json
generated
@@ -73,7 +73,7 @@
|
|||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^20.18.x",
|
"node": "^20.18.x",
|
||||||
"npm": "^10.2.x"
|
"npm": "^10.8.x"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@ampproject/remapping": {
|
"node_modules/@ampproject/remapping": {
|
||||||
@@ -143,13 +143,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/generator": {
|
"node_modules/@babel/generator": {
|
||||||
"version": "7.27.0",
|
"version": "7.26.10",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.27.0.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.10.tgz",
|
||||||
"integrity": "sha512-VybsKvpiN1gU1sdMZIp7FcqphVVKEwcuj02x73uvcHE0PTihx1nlBcowYWhDwjpoAXRv43+gDzyggGnn1XZhVw==",
|
"integrity": "sha512-rRHT8siFIXQrAYOYqZQVsAr8vJ+cBNqcVAY6m5V8/4QqzaPl+zDBe6cLEPRDuNOUf3ww8RfJVlOyQMoSI+5Ang==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/parser": "^7.27.0",
|
"@babel/parser": "^7.26.10",
|
||||||
"@babel/types": "^7.27.0",
|
"@babel/types": "^7.26.10",
|
||||||
"@jridgewell/gen-mapping": "^0.3.5",
|
"@jridgewell/gen-mapping": "^0.3.5",
|
||||||
"@jridgewell/trace-mapping": "^0.3.25",
|
"@jridgewell/trace-mapping": "^0.3.25",
|
||||||
"jsesc": "^3.0.2"
|
"jsesc": "^3.0.2"
|
||||||
@@ -392,12 +392,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/parser": {
|
"node_modules/@babel/parser": {
|
||||||
"version": "7.27.0",
|
"version": "7.26.10",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.0.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.10.tgz",
|
||||||
"integrity": "sha512-iaepho73/2Pz7w2eMS0Q5f83+0RKI7i4xmiYeBmDzfRVbQtTOG7Ts0S4HzJVsTMGI9keU8rNfuZr8DKfSt7Yyg==",
|
"integrity": "sha512-6aQR2zGE/QFi8JpDLjUZEPYOs7+mhKXm86VaKFiLP35JQwQb6bwUE+XbvkH0EptsYhbNBSUGaUBLKqxH1xSgsA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/types": "^7.27.0"
|
"@babel/types": "^7.26.10"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"parser": "bin/babel-parser.js"
|
"parser": "bin/babel-parser.js"
|
||||||
@@ -549,7 +549,6 @@
|
|||||||
"version": "7.26.0",
|
"version": "7.26.0",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.26.0.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.26.0.tgz",
|
||||||
"integrity": "sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A==",
|
"integrity": "sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A==",
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/helper-plugin-utils": "^7.25.9"
|
"@babel/helper-plugin-utils": "^7.25.9"
|
||||||
},
|
},
|
||||||
@@ -1678,9 +1677,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/runtime": {
|
"node_modules/@babel/runtime": {
|
||||||
"version": "7.25.9",
|
"version": "7.27.0",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.9.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.0.tgz",
|
||||||
"integrity": "sha512-4zpTHZ9Cm6L9L+uIqghQX8ZXg8HKFcjYO3qHoO8zTmRm6HQUJ8SSJ+KRvbMBZn0EGVlT4DRYeQ/6hjlyXBh+Kg==",
|
"integrity": "sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"regenerator-runtime": "^0.14.0"
|
"regenerator-runtime": "^0.14.0"
|
||||||
},
|
},
|
||||||
@@ -1689,30 +1689,30 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/template": {
|
"node_modules/@babel/template": {
|
||||||
"version": "7.27.0",
|
"version": "7.26.9",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.0.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.26.9.tgz",
|
||||||
"integrity": "sha512-2ncevenBqXI6qRMukPlXwHKHchC7RyMuu4xv5JBXRfOGVcTy1mXCD12qrp7Jsoxll1EV3+9sE4GugBVRjT2jFA==",
|
"integrity": "sha512-qyRplbeIpNZhmzOysF/wFMuP9sctmh2cFzRAZOn1YapxBsE1i9bJIY586R/WBLfLcmcBlM8ROBiQURnnNy+zfA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/code-frame": "^7.26.2",
|
"@babel/code-frame": "^7.26.2",
|
||||||
"@babel/parser": "^7.27.0",
|
"@babel/parser": "^7.26.9",
|
||||||
"@babel/types": "^7.27.0"
|
"@babel/types": "^7.26.9"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.9.0"
|
"node": ">=6.9.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/traverse": {
|
"node_modules/@babel/traverse": {
|
||||||
"version": "7.27.0",
|
"version": "7.26.10",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.27.0.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.10.tgz",
|
||||||
"integrity": "sha512-19lYZFzYVQkkHkl4Cy4WrAVcqBkgvV2YM2TU3xG6DIwO7O3ecbDPfW3yM3bjAGcqcQHi+CCtjMR3dIEHxsd6bA==",
|
"integrity": "sha512-k8NuDrxr0WrPH5Aupqb2LCVURP/S0vBEn5mK6iH+GIYob66U5EtoZvcdudR2jQ4cmTwhEwW1DLB+Yyas9zjF6A==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/code-frame": "^7.26.2",
|
"@babel/code-frame": "^7.26.2",
|
||||||
"@babel/generator": "^7.27.0",
|
"@babel/generator": "^7.26.10",
|
||||||
"@babel/parser": "^7.27.0",
|
"@babel/parser": "^7.26.10",
|
||||||
"@babel/template": "^7.27.0",
|
"@babel/template": "^7.26.9",
|
||||||
"@babel/types": "^7.27.0",
|
"@babel/types": "^7.26.10",
|
||||||
"debug": "^4.3.1",
|
"debug": "^4.3.1",
|
||||||
"globals": "^11.1.0"
|
"globals": "^11.1.0"
|
||||||
},
|
},
|
||||||
@@ -1730,9 +1730,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/types": {
|
"node_modules/@babel/types": {
|
||||||
"version": "7.27.0",
|
"version": "7.26.10",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.0.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.10.tgz",
|
||||||
"integrity": "sha512-H45s8fVLYjbhFH62dIJ3WtmJ6RSPt/3DRO0ZcT2SUiYiQyz3BLVb9ADEnLl91m74aQPS3AzzeajZHYOalWe3bg==",
|
"integrity": "sha512-emqcG3vHrpxUKTrxcblR36dcrcoRDvKmnL/dCL6ZsHaShW80qxCAcNhzQZrpeM765VzEos+xOi4s+r4IXzTwdQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/helper-string-parser": "^7.25.9",
|
"@babel/helper-string-parser": "^7.25.9",
|
||||||
@@ -3275,6 +3275,7 @@
|
|||||||
"version": "4.3.0",
|
"version": "4.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||||
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"color-convert": "^2.0.1"
|
"color-convert": "^2.0.1"
|
||||||
},
|
},
|
||||||
@@ -3336,6 +3337,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz",
|
||||||
"integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==",
|
"integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"call-bound": "^1.0.3",
|
"call-bound": "^1.0.3",
|
||||||
"is-array-buffer": "^3.0.5"
|
"is-array-buffer": "^3.0.5"
|
||||||
@@ -3432,6 +3434,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz",
|
"resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz",
|
||||||
"integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==",
|
"integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"call-bind": "^1.0.8",
|
"call-bind": "^1.0.8",
|
||||||
"define-properties": "^1.2.1",
|
"define-properties": "^1.2.1",
|
||||||
@@ -3467,6 +3470,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz",
|
||||||
"integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==",
|
"integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"array-buffer-byte-length": "^1.0.1",
|
"array-buffer-byte-length": "^1.0.1",
|
||||||
"call-bind": "^1.0.8",
|
"call-bind": "^1.0.8",
|
||||||
@@ -3530,6 +3534,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz",
|
||||||
"integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==",
|
"integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
@@ -3584,6 +3589,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz",
|
||||||
"integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==",
|
"integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"possible-typed-array-names": "^1.0.0"
|
"possible-typed-array-names": "^1.0.0"
|
||||||
},
|
},
|
||||||
@@ -3750,6 +3756,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-import-meta/-/babel-plugin-transform-import-meta-2.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/babel-plugin-transform-import-meta/-/babel-plugin-transform-import-meta-2.3.2.tgz",
|
||||||
"integrity": "sha512-902o4GiQqI1GqAXfD5rEoz0PJamUfJ3VllpdWaNsFTwdaNjFSFHawvBO+cp5K2j+g2h3bZ4lnM1Xb6yFYGihtA==",
|
"integrity": "sha512-902o4GiQqI1GqAXfD5rEoz0PJamUfJ3VllpdWaNsFTwdaNjFSFHawvBO+cp5K2j+g2h3bZ4lnM1Xb6yFYGihtA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "BSD",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/template": "^7.25.9",
|
"@babel/template": "^7.25.9",
|
||||||
"tslib": "^2.8.1"
|
"tslib": "^2.8.1"
|
||||||
@@ -4286,6 +4293,7 @@
|
|||||||
"version": "1.0.8",
|
"version": "1.0.8",
|
||||||
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz",
|
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz",
|
||||||
"integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==",
|
"integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"call-bind-apply-helpers": "^1.0.0",
|
"call-bind-apply-helpers": "^1.0.0",
|
||||||
"es-define-property": "^1.0.0",
|
"es-define-property": "^1.0.0",
|
||||||
@@ -4349,9 +4357,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/caniuse-lite": {
|
"node_modules/caniuse-lite": {
|
||||||
"version": "1.0.30001699",
|
"version": "1.0.30001704",
|
||||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001699.tgz",
|
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001704.tgz",
|
||||||
"integrity": "sha512-b+uH5BakXZ9Do9iK+CkDmctUSEqZl+SP056vc5usa0PL+ev5OHw003rZXcnjNDv3L8P5j6rwT6C0BPKSikW08w==",
|
"integrity": "sha512-+L2IgBbV6gXB4ETf0keSvLr7JUrRVbIaB/lrQ1+z8mRcQiisG5k+lG6O4n6Y5q6f5EuNfaYXKgymucphlEXQew==",
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
@@ -4524,6 +4532,7 @@
|
|||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||||
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"color-name": "~1.1.4"
|
"color-name": "~1.1.4"
|
||||||
},
|
},
|
||||||
@@ -4534,7 +4543,8 @@
|
|||||||
"node_modules/color-name": {
|
"node_modules/color-name": {
|
||||||
"version": "1.1.4",
|
"version": "1.1.4",
|
||||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
|
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
||||||
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/colord": {
|
"node_modules/colord": {
|
||||||
"version": "2.9.3",
|
"version": "2.9.3",
|
||||||
@@ -4715,12 +4725,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/core-js-compat": {
|
"node_modules/core-js-compat": {
|
||||||
"version": "3.40.0",
|
"version": "3.41.0",
|
||||||
"resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.40.0.tgz",
|
"resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.41.0.tgz",
|
||||||
"integrity": "sha512-0XEDpr5y5mijvw8Lbc6E5AkjrHfp7eEoPlu36SWeAbcL8fn1G1ANe8DBlo2XoNN89oVpxWwOjYIPVzR4ZvsKCQ==",
|
"integrity": "sha512-RFsU9LySVue9RTwdDVX/T0e2Y6jRYWXERKElIjpuEOEnxaXffI0X7RUwVzfYLfzuLXSNJDYoRYUAmRUcyln20A==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"browserslist": "^4.24.3"
|
"browserslist": "^4.24.4"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
@@ -4893,6 +4903,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
|
||||||
"integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
|
"integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"path-key": "^3.1.0",
|
"path-key": "^3.1.0",
|
||||||
"shebang-command": "^2.0.0",
|
"shebang-command": "^2.0.0",
|
||||||
@@ -4938,6 +4949,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.1.0.tgz",
|
||||||
"integrity": "sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==",
|
"integrity": "sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"mdn-data": "2.12.2",
|
"mdn-data": "2.12.2",
|
||||||
"source-map-js": "^1.0.1"
|
"source-map-js": "^1.0.1"
|
||||||
@@ -5039,6 +5051,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz",
|
||||||
"integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==",
|
"integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"call-bound": "^1.0.3",
|
"call-bound": "^1.0.3",
|
||||||
"es-errors": "^1.3.0",
|
"es-errors": "^1.3.0",
|
||||||
@@ -5056,6 +5069,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz",
|
||||||
"integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==",
|
"integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"call-bound": "^1.0.3",
|
"call-bound": "^1.0.3",
|
||||||
"es-errors": "^1.3.0",
|
"es-errors": "^1.3.0",
|
||||||
@@ -5073,6 +5087,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz",
|
||||||
"integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==",
|
"integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"call-bound": "^1.0.2",
|
"call-bound": "^1.0.2",
|
||||||
"es-errors": "^1.3.0",
|
"es-errors": "^1.3.0",
|
||||||
@@ -5367,6 +5382,7 @@
|
|||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
|
||||||
"integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
|
"integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"call-bind-apply-helpers": "^1.0.1",
|
"call-bind-apply-helpers": "^1.0.1",
|
||||||
"es-errors": "^1.3.0",
|
"es-errors": "^1.3.0",
|
||||||
@@ -5401,9 +5417,9 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/electron-to-chromium": {
|
"node_modules/electron-to-chromium": {
|
||||||
"version": "1.5.97",
|
"version": "1.5.118",
|
||||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.97.tgz",
|
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.118.tgz",
|
||||||
"integrity": "sha512-HKLtaH02augM7ZOdYRuO19rWDeY+QSJ1VxnXFa/XDFLf07HvM90pALIJFgrO+UVaajI3+aJMMpojoUTLZyQ7JQ==",
|
"integrity": "sha512-yNDUus0iultYyVoEFLnQeei7LOQkL8wg8GQpkPCRrOlJXlcCwa6eGKZkxQ9ciHsqZyYbj8Jd94X1CTPzGm+uIA==",
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
"node_modules/elliptic": {
|
"node_modules/elliptic": {
|
||||||
@@ -5505,6 +5521,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.7.tgz",
|
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.7.tgz",
|
||||||
"integrity": "sha512-OygGC8kIcDhXX+6yAZRGLqwi2CmEXCbLQixeGUgYeR+Qwlppqmo7DIDr8XibtEBZp+fJcoYpoatp5qwLMEdcqQ==",
|
"integrity": "sha512-OygGC8kIcDhXX+6yAZRGLqwi2CmEXCbLQixeGUgYeR+Qwlppqmo7DIDr8XibtEBZp+fJcoYpoatp5qwLMEdcqQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"array-buffer-byte-length": "^1.0.2",
|
"array-buffer-byte-length": "^1.0.2",
|
||||||
"arraybuffer.prototype.slice": "^1.0.4",
|
"arraybuffer.prototype.slice": "^1.0.4",
|
||||||
@@ -5565,6 +5582,7 @@
|
|||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
|
||||||
"integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
|
"integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
|
||||||
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
}
|
}
|
||||||
@@ -5583,6 +5601,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.2.1.tgz",
|
||||||
"integrity": "sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w==",
|
"integrity": "sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"call-bind": "^1.0.8",
|
"call-bind": "^1.0.8",
|
||||||
"call-bound": "^1.0.3",
|
"call-bound": "^1.0.3",
|
||||||
@@ -5647,6 +5666,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz",
|
||||||
"integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==",
|
"integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"is-callable": "^1.2.7",
|
"is-callable": "^1.2.7",
|
||||||
"is-date-object": "^1.0.5",
|
"is-date-object": "^1.0.5",
|
||||||
@@ -5740,6 +5760,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-28.11.0.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-28.11.0.tgz",
|
||||||
"integrity": "sha512-QAfipLcNCWLVocVbZW8GimKn5p5iiMcgGbRzz8z/P5q7xw+cNEpYqyzFMtIF/ZgF2HLOyy+dYBut+DoYolvqig==",
|
"integrity": "sha512-QAfipLcNCWLVocVbZW8GimKn5p5iiMcgGbRzz8z/P5q7xw+cNEpYqyzFMtIF/ZgF2HLOyy+dYBut+DoYolvqig==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/utils": "^6.0.0 || ^7.0.0 || ^8.0.0"
|
"@typescript-eslint/utils": "^6.0.0 || ^7.0.0 || ^8.0.0"
|
||||||
},
|
},
|
||||||
@@ -6178,6 +6199,7 @@
|
|||||||
"version": "2.2.0",
|
"version": "2.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/express-static-gzip/-/express-static-gzip-2.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/express-static-gzip/-/express-static-gzip-2.2.0.tgz",
|
||||||
"integrity": "sha512-4ZQ0pHX0CAauxmzry2/8XFLM6aZA4NBvg9QezSlsEO1zLnl7vMFa48/WIcjzdfOiEUS4S1npPPKP2NHHYAp6qg==",
|
"integrity": "sha512-4ZQ0pHX0CAauxmzry2/8XFLM6aZA4NBvg9QezSlsEO1zLnl7vMFa48/WIcjzdfOiEUS4S1npPPKP2NHHYAp6qg==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"parseurl": "^1.3.3",
|
"parseurl": "^1.3.3",
|
||||||
"serve-static": "^1.16.2"
|
"serve-static": "^1.16.2"
|
||||||
@@ -6333,6 +6355,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
|
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
|
||||||
"integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
|
"integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@nodelib/fs.stat": "^2.0.2",
|
"@nodelib/fs.stat": "^2.0.2",
|
||||||
"@nodelib/fs.walk": "^1.2.3",
|
"@nodelib/fs.walk": "^1.2.3",
|
||||||
@@ -6381,7 +6404,8 @@
|
|||||||
"version": "3.0.3",
|
"version": "3.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.3.tgz",
|
||||||
"integrity": "sha512-aLrHthzCjH5He4Z2H9YZ+v6Ujb9ocRuW6ZzkJQOrTxleEijANq4v1TsaPaVG1PZcuurEzrLcWRyYBYXD5cEiaw==",
|
"integrity": "sha512-aLrHthzCjH5He4Z2H9YZ+v6Ujb9ocRuW6ZzkJQOrTxleEijANq4v1TsaPaVG1PZcuurEzrLcWRyYBYXD5cEiaw==",
|
||||||
"dev": true
|
"dev": true,
|
||||||
|
"license": "BSD-3-Clause"
|
||||||
},
|
},
|
||||||
"node_modules/fastest-levenshtein": {
|
"node_modules/fastest-levenshtein": {
|
||||||
"version": "1.0.16",
|
"version": "1.0.16",
|
||||||
@@ -6498,6 +6522,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
|
"resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
|
||||||
"integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==",
|
"integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"is-callable": "^1.1.3"
|
"is-callable": "^1.1.3"
|
||||||
}
|
}
|
||||||
@@ -6572,6 +6597,7 @@
|
|||||||
"version": "11.3.0",
|
"version": "11.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.0.tgz",
|
||||||
"integrity": "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==",
|
"integrity": "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"graceful-fs": "^4.2.0",
|
"graceful-fs": "^4.2.0",
|
||||||
"jsonfile": "^6.0.1",
|
"jsonfile": "^6.0.1",
|
||||||
@@ -6587,6 +6613,20 @@
|
|||||||
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
|
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
|
"node_modules/fsevents": {
|
||||||
|
"version": "2.3.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
|
||||||
|
"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
|
||||||
|
"hasInstallScript": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"darwin"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/function-bind": {
|
"node_modules/function-bind": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
|
||||||
@@ -6601,6 +6641,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz",
|
"resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz",
|
||||||
"integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==",
|
"integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"call-bind": "^1.0.8",
|
"call-bind": "^1.0.8",
|
||||||
"call-bound": "^1.0.3",
|
"call-bound": "^1.0.3",
|
||||||
@@ -6757,6 +6798,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz",
|
||||||
"integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==",
|
"integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"call-bound": "^1.0.3",
|
"call-bound": "^1.0.3",
|
||||||
"es-errors": "^1.3.0",
|
"es-errors": "^1.3.0",
|
||||||
@@ -6962,6 +7004,7 @@
|
|||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
|
||||||
"integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
|
"integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
|
||||||
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
},
|
},
|
||||||
@@ -7002,6 +7045,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz",
|
||||||
"integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==",
|
"integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
},
|
},
|
||||||
@@ -7035,6 +7079,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz",
|
||||||
"integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==",
|
"integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"dunder-proto": "^1.0.0"
|
"dunder-proto": "^1.0.0"
|
||||||
},
|
},
|
||||||
@@ -7049,6 +7094,7 @@
|
|||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
|
||||||
"integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
|
"integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
|
||||||
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
},
|
},
|
||||||
@@ -7491,6 +7537,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz",
|
||||||
"integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==",
|
"integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"es-errors": "^1.3.0",
|
"es-errors": "^1.3.0",
|
||||||
"hasown": "^2.0.2",
|
"hasown": "^2.0.2",
|
||||||
@@ -7526,6 +7573,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz",
|
||||||
"integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==",
|
"integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"call-bind": "^1.0.8",
|
"call-bind": "^1.0.8",
|
||||||
"call-bound": "^1.0.3",
|
"call-bound": "^1.0.3",
|
||||||
@@ -7550,6 +7598,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz",
|
||||||
"integrity": "sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==",
|
"integrity": "sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"has-tostringtag": "^1.0.0"
|
"has-tostringtag": "^1.0.0"
|
||||||
},
|
},
|
||||||
@@ -7565,6 +7614,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz",
|
||||||
"integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==",
|
"integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"has-bigints": "^1.0.2"
|
"has-bigints": "^1.0.2"
|
||||||
},
|
},
|
||||||
@@ -7592,6 +7642,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.1.tgz",
|
||||||
"integrity": "sha512-l9qO6eFlUETHtuihLcYOaLKByJ1f+N4kthcU9YjHy3N+B3hWv0y/2Nd0mu/7lTFnRQHTrSdXF50HQ3bl5fEnng==",
|
"integrity": "sha512-l9qO6eFlUETHtuihLcYOaLKByJ1f+N4kthcU9YjHy3N+B3hWv0y/2Nd0mu/7lTFnRQHTrSdXF50HQ3bl5fEnng==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"call-bound": "^1.0.2",
|
"call-bound": "^1.0.2",
|
||||||
"has-tostringtag": "^1.0.2"
|
"has-tostringtag": "^1.0.2"
|
||||||
@@ -7614,6 +7665,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz",
|
"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz",
|
||||||
"integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==",
|
"integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
},
|
},
|
||||||
@@ -7653,6 +7705,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz",
|
||||||
"integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==",
|
"integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"call-bound": "^1.0.2",
|
"call-bound": "^1.0.2",
|
||||||
"get-intrinsic": "^1.2.6",
|
"get-intrinsic": "^1.2.6",
|
||||||
@@ -7670,6 +7723,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz",
|
||||||
"integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==",
|
"integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"call-bound": "^1.0.2",
|
"call-bound": "^1.0.2",
|
||||||
"has-tostringtag": "^1.0.2"
|
"has-tostringtag": "^1.0.2"
|
||||||
@@ -7717,6 +7771,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz",
|
||||||
"integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==",
|
"integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"call-bound": "^1.0.3"
|
"call-bound": "^1.0.3"
|
||||||
},
|
},
|
||||||
@@ -7751,6 +7806,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz",
|
"resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz",
|
||||||
"integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==",
|
"integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"has-tostringtag": "^1.0.0"
|
"has-tostringtag": "^1.0.0"
|
||||||
},
|
},
|
||||||
@@ -7778,6 +7834,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz",
|
||||||
"integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==",
|
"integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
},
|
},
|
||||||
@@ -7799,6 +7856,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz",
|
||||||
"integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==",
|
"integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"call-bound": "^1.0.3",
|
"call-bound": "^1.0.3",
|
||||||
"has-tostringtag": "^1.0.2"
|
"has-tostringtag": "^1.0.2"
|
||||||
@@ -7839,6 +7897,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz",
|
||||||
"integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==",
|
"integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"call-bound": "^1.0.2",
|
"call-bound": "^1.0.2",
|
||||||
"gopd": "^1.2.0",
|
"gopd": "^1.2.0",
|
||||||
@@ -7857,6 +7916,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz",
|
||||||
"integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==",
|
"integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
},
|
},
|
||||||
@@ -7869,6 +7929,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz",
|
||||||
"integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==",
|
"integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"call-bound": "^1.0.3"
|
"call-bound": "^1.0.3"
|
||||||
},
|
},
|
||||||
@@ -7896,6 +7957,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz",
|
||||||
"integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==",
|
"integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"call-bound": "^1.0.3",
|
"call-bound": "^1.0.3",
|
||||||
"has-tostringtag": "^1.0.2"
|
"has-tostringtag": "^1.0.2"
|
||||||
@@ -7912,6 +7974,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz",
|
||||||
"integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==",
|
"integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"call-bound": "^1.0.2",
|
"call-bound": "^1.0.2",
|
||||||
"has-symbols": "^1.1.0",
|
"has-symbols": "^1.1.0",
|
||||||
@@ -7929,6 +7992,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz",
|
"resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz",
|
||||||
"integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==",
|
"integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"which-typed-array": "^1.1.16"
|
"which-typed-array": "^1.1.16"
|
||||||
},
|
},
|
||||||
@@ -7944,6 +8008,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz",
|
||||||
"integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==",
|
"integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
},
|
},
|
||||||
@@ -7956,6 +8021,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.0.tgz",
|
||||||
"integrity": "sha512-SXM8Nwyys6nT5WP6pltOwKytLV7FqQ4UiibxVmW+EIosHcmCqkkjViTb5SNssDlkCiEYRP1/pdWUKVvZBmsR2Q==",
|
"integrity": "sha512-SXM8Nwyys6nT5WP6pltOwKytLV7FqQ4UiibxVmW+EIosHcmCqkkjViTb5SNssDlkCiEYRP1/pdWUKVvZBmsR2Q==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"call-bound": "^1.0.2"
|
"call-bound": "^1.0.2"
|
||||||
},
|
},
|
||||||
@@ -7971,6 +8037,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz",
|
||||||
"integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==",
|
"integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"call-bound": "^1.0.3",
|
"call-bound": "^1.0.3",
|
||||||
"get-intrinsic": "^1.2.6"
|
"get-intrinsic": "^1.2.6"
|
||||||
@@ -8001,7 +8068,8 @@
|
|||||||
"version": "2.0.5",
|
"version": "2.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
|
||||||
"integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==",
|
"integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==",
|
||||||
"dev": true
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/isexe": {
|
"node_modules/isexe": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
@@ -8131,6 +8199,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.4.tgz",
|
"resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.4.tgz",
|
||||||
"integrity": "sha512-x4WH0BWmrMmg4oHHl+duwubhrvczGlyuGAZu3nvrf0UXOfPu8IhZObFEr7DE/iv01YgVZrsOiRcqw2srkKEDIA==",
|
"integrity": "sha512-x4WH0BWmrMmg4oHHl+duwubhrvczGlyuGAZu3nvrf0UXOfPu8IhZObFEr7DE/iv01YgVZrsOiRcqw2srkKEDIA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"define-data-property": "^1.1.4",
|
"define-data-property": "^1.1.4",
|
||||||
"es-object-atoms": "^1.0.0",
|
"es-object-atoms": "^1.0.0",
|
||||||
@@ -9814,7 +9883,8 @@
|
|||||||
"version": "4.4.2",
|
"version": "4.4.2",
|
||||||
"resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz",
|
"resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz",
|
||||||
"integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==",
|
"integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==",
|
||||||
"dev": true
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/loose-envify": {
|
"node_modules/loose-envify": {
|
||||||
"version": "1.4.0",
|
"version": "1.4.0",
|
||||||
@@ -9983,6 +10053,7 @@
|
|||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
|
||||||
"integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
|
"integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
|
||||||
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
}
|
}
|
||||||
@@ -10013,7 +10084,8 @@
|
|||||||
"version": "2.12.2",
|
"version": "2.12.2",
|
||||||
"resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.12.2.tgz",
|
"resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.12.2.tgz",
|
||||||
"integrity": "sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==",
|
"integrity": "sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==",
|
||||||
"dev": true
|
"dev": true,
|
||||||
|
"license": "CC0-1.0"
|
||||||
},
|
},
|
||||||
"node_modules/media-typer": {
|
"node_modules/media-typer": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
@@ -10479,6 +10551,13 @@
|
|||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
|
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
|
||||||
},
|
},
|
||||||
|
"node_modules/nan": {
|
||||||
|
"version": "2.20.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/nan/-/nan-2.20.0.tgz",
|
||||||
|
"integrity": "sha512-bk3gXBZDGILuuo/6sKtr0DQmSThYHLtNCdSdXk9YkxD/jK6X2vmCyyXBBxyqZ4XcnzTyYEAThfX3DCEnLf6igw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
"node_modules/nanoid": {
|
"node_modules/nanoid": {
|
||||||
"version": "5.1.5",
|
"version": "5.1.5",
|
||||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.1.5.tgz",
|
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.1.5.tgz",
|
||||||
@@ -10806,6 +10885,7 @@
|
|||||||
"version": "1.13.3",
|
"version": "1.13.3",
|
||||||
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz",
|
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz",
|
||||||
"integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==",
|
"integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==",
|
||||||
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
},
|
},
|
||||||
@@ -10838,6 +10918,7 @@
|
|||||||
"version": "4.1.7",
|
"version": "4.1.7",
|
||||||
"resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz",
|
"resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz",
|
||||||
"integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==",
|
"integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"call-bind": "^1.0.8",
|
"call-bind": "^1.0.8",
|
||||||
"call-bound": "^1.0.3",
|
"call-bound": "^1.0.3",
|
||||||
@@ -10905,6 +10986,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz",
|
||||||
"integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==",
|
"integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"call-bind": "^1.0.8",
|
"call-bind": "^1.0.8",
|
||||||
"call-bound": "^1.0.3",
|
"call-bound": "^1.0.3",
|
||||||
@@ -11344,6 +11426,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz",
|
||||||
"integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==",
|
"integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
}
|
}
|
||||||
@@ -11852,6 +11935,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.9.tgz",
|
"resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.9.tgz",
|
||||||
"integrity": "sha512-r0Ay04Snci87djAsI4U+WNRcSw5S4pOH7qFjd/veA5gC7TbqESR3tcj28ia95L/fYUDw11JKP7uqUKUAfVvV5Q==",
|
"integrity": "sha512-r0Ay04Snci87djAsI4U+WNRcSw5S4pOH7qFjd/veA5gC7TbqESR3tcj28ia95L/fYUDw11JKP7uqUKUAfVvV5Q==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"call-bind": "^1.0.8",
|
"call-bind": "^1.0.8",
|
||||||
"define-properties": "^1.2.1",
|
"define-properties": "^1.2.1",
|
||||||
@@ -11953,6 +12037,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.3.tgz",
|
"resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.3.tgz",
|
||||||
"integrity": "sha512-vqlC04+RQoFalODCbCumG2xIOvapzVMHwsyIGM/SIE8fRhFFsXeH8/QQ+s0T0kDAhKc4k30s73/0ydkHQz6HlQ==",
|
"integrity": "sha512-vqlC04+RQoFalODCbCumG2xIOvapzVMHwsyIGM/SIE8fRhFFsXeH8/QQ+s0T0kDAhKc4k30s73/0ydkHQz6HlQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"call-bind": "^1.0.7",
|
"call-bind": "^1.0.7",
|
||||||
"define-properties": "^1.2.1",
|
"define-properties": "^1.2.1",
|
||||||
@@ -12036,6 +12121,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
|
||||||
"integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
|
"integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
@@ -12196,6 +12282,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz",
|
||||||
"integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==",
|
"integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"call-bind": "^1.0.8",
|
"call-bind": "^1.0.8",
|
||||||
"call-bound": "^1.0.2",
|
"call-bound": "^1.0.2",
|
||||||
@@ -12244,6 +12331,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz",
|
||||||
"integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==",
|
"integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"call-bound": "^1.0.2",
|
"call-bound": "^1.0.2",
|
||||||
"es-errors": "^1.3.0",
|
"es-errors": "^1.3.0",
|
||||||
@@ -12507,6 +12595,7 @@
|
|||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
|
||||||
"integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
|
"integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"es-errors": "^1.3.0",
|
"es-errors": "^1.3.0",
|
||||||
"object-inspect": "^1.13.3",
|
"object-inspect": "^1.13.3",
|
||||||
@@ -12525,6 +12614,7 @@
|
|||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
|
||||||
"integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
|
"integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"es-errors": "^1.3.0",
|
"es-errors": "^1.3.0",
|
||||||
"object-inspect": "^1.13.3"
|
"object-inspect": "^1.13.3"
|
||||||
@@ -12540,6 +12630,7 @@
|
|||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
|
||||||
"integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
|
"integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"call-bound": "^1.0.2",
|
"call-bound": "^1.0.2",
|
||||||
"es-errors": "^1.3.0",
|
"es-errors": "^1.3.0",
|
||||||
@@ -12557,6 +12648,7 @@
|
|||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
|
||||||
"integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
|
"integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"call-bound": "^1.0.2",
|
"call-bound": "^1.0.2",
|
||||||
"es-errors": "^1.3.0",
|
"es-errors": "^1.3.0",
|
||||||
@@ -12647,6 +12739,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz",
|
||||||
"integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==",
|
"integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ansi-styles": "^4.0.0",
|
"ansi-styles": "^4.0.0",
|
||||||
"astral-regex": "^2.0.0",
|
"astral-regex": "^2.0.0",
|
||||||
@@ -13023,6 +13116,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz",
|
"resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz",
|
||||||
"integrity": "sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==",
|
"integrity": "sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"call-bind": "^1.0.8",
|
"call-bind": "^1.0.8",
|
||||||
"call-bound": "^1.0.3",
|
"call-bound": "^1.0.3",
|
||||||
@@ -13061,6 +13155,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz",
|
"resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz",
|
||||||
"integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==",
|
"integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"call-bind": "^1.0.8",
|
"call-bind": "^1.0.8",
|
||||||
"call-bound": "^1.0.2",
|
"call-bound": "^1.0.2",
|
||||||
@@ -13082,6 +13177,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz",
|
"resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz",
|
||||||
"integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==",
|
"integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"call-bind": "^1.0.8",
|
"call-bind": "^1.0.8",
|
||||||
"call-bound": "^1.0.2",
|
"call-bound": "^1.0.2",
|
||||||
@@ -13233,6 +13329,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/stylelint-config-recess-order/-/stylelint-config-recess-order-6.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/stylelint-config-recess-order/-/stylelint-config-recess-order-6.0.0.tgz",
|
||||||
"integrity": "sha512-1KqrttqpIrCYFAVQ1/bbgXo7EvvcjmkxxmnzVr+U66Xr2OlrNZqQ5+44Tmct6grCWY6wGTIBh2tSANqcmwIM2g==",
|
"integrity": "sha512-1KqrttqpIrCYFAVQ1/bbgXo7EvvcjmkxxmnzVr+U66Xr2OlrNZqQ5+44Tmct6grCWY6wGTIBh2tSANqcmwIM2g==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"stylelint-order": "^6.0.4"
|
"stylelint-order": "^6.0.4"
|
||||||
},
|
},
|
||||||
@@ -13358,6 +13455,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.3.tgz",
|
||||||
"integrity": "sha512-bAH5jbK/F3T3Jls4I0SO1hmPR0dKU0a7+SY6n1yzRtG54FLO8d6w/nxLFX2Nb7dBu6cCWXPaAME6cYqFUMmuCA==",
|
"integrity": "sha512-bAH5jbK/F3T3Jls4I0SO1hmPR0dKU0a7+SY6n1yzRtG54FLO8d6w/nxLFX2Nb7dBu6cCWXPaAME6cYqFUMmuCA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 4"
|
"node": ">= 4"
|
||||||
}
|
}
|
||||||
@@ -13592,6 +13690,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/table/-/table-6.9.0.tgz",
|
"resolved": "https://registry.npmjs.org/table/-/table-6.9.0.tgz",
|
||||||
"integrity": "sha512-9kY+CygyYM6j02t5YFHbNz2FN5QmYGv9zAjVp4lCDjlCw7amdckXlEt/bjMhUIfj4ThGRE4gCUH5+yGnNuPo5A==",
|
"integrity": "sha512-9kY+CygyYM6j02t5YFHbNz2FN5QmYGv9zAjVp4lCDjlCw7amdckXlEt/bjMhUIfj4ThGRE4gCUH5+yGnNuPo5A==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "BSD-3-Clause",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ajv": "^8.0.1",
|
"ajv": "^8.0.1",
|
||||||
"lodash.truncate": "^4.4.2",
|
"lodash.truncate": "^4.4.2",
|
||||||
@@ -13608,6 +13707,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
|
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
|
||||||
"integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
|
"integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"fast-deep-equal": "^3.1.3",
|
"fast-deep-equal": "^3.1.3",
|
||||||
"fast-uri": "^3.0.1",
|
"fast-uri": "^3.0.1",
|
||||||
@@ -13623,7 +13723,8 @@
|
|||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
|
||||||
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
|
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
|
||||||
"dev": true
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/test-exclude": {
|
"node_modules/test-exclude": {
|
||||||
"version": "6.0.0",
|
"version": "6.0.0",
|
||||||
@@ -13964,6 +14065,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz",
|
||||||
"integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==",
|
"integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"call-bound": "^1.0.3",
|
"call-bound": "^1.0.3",
|
||||||
"es-errors": "^1.3.0",
|
"es-errors": "^1.3.0",
|
||||||
@@ -13978,6 +14080,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz",
|
||||||
"integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==",
|
"integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"call-bind": "^1.0.8",
|
"call-bind": "^1.0.8",
|
||||||
"for-each": "^0.3.3",
|
"for-each": "^0.3.3",
|
||||||
@@ -13997,6 +14100,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz",
|
||||||
"integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==",
|
"integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"available-typed-arrays": "^1.0.7",
|
"available-typed-arrays": "^1.0.7",
|
||||||
"call-bind": "^1.0.8",
|
"call-bind": "^1.0.8",
|
||||||
@@ -14018,6 +14122,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz",
|
||||||
"integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==",
|
"integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"call-bind": "^1.0.7",
|
"call-bind": "^1.0.7",
|
||||||
"for-each": "^0.3.3",
|
"for-each": "^0.3.3",
|
||||||
@@ -14068,6 +14173,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz",
|
||||||
"integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==",
|
"integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"call-bound": "^1.0.3",
|
"call-bound": "^1.0.3",
|
||||||
"has-bigints": "^1.0.2",
|
"has-bigints": "^1.0.2",
|
||||||
@@ -14244,9 +14350,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/update-browserslist-db": {
|
"node_modules/update-browserslist-db": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz",
|
||||||
"integrity": "sha512-PPypAm5qvlD7XMZC3BujecnaOxwhrtoFR+Dqkk5Aa/6DssiH0ibKoketaj9w8LP7Bont1rYeoV5plxD7RTEPRg==",
|
"integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==",
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
@@ -14586,6 +14692,25 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/watchify/node_modules/fsevents": {
|
||||||
|
"version": "1.2.13",
|
||||||
|
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz",
|
||||||
|
"integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==",
|
||||||
|
"deprecated": "The v1 package contains DANGEROUS / INSECURE binaries. Upgrade to safe fsevents v2",
|
||||||
|
"hasInstallScript": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"darwin"
|
||||||
|
],
|
||||||
|
"dependencies": {
|
||||||
|
"bindings": "^1.5.0",
|
||||||
|
"nan": "^2.12.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/watchify/node_modules/glob-parent": {
|
"node_modules/watchify/node_modules/glob-parent": {
|
||||||
"version": "3.1.0",
|
"version": "3.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
|
||||||
@@ -14817,6 +14942,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz",
|
||||||
"integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==",
|
"integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"is-bigint": "^1.1.0",
|
"is-bigint": "^1.1.0",
|
||||||
"is-boolean-object": "^1.2.1",
|
"is-boolean-object": "^1.2.1",
|
||||||
@@ -14836,6 +14962,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz",
|
||||||
"integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==",
|
"integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"call-bound": "^1.0.2",
|
"call-bound": "^1.0.2",
|
||||||
"function.prototype.name": "^1.1.6",
|
"function.prototype.name": "^1.1.6",
|
||||||
@@ -14863,6 +14990,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz",
|
||||||
"integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==",
|
"integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"is-map": "^2.0.3",
|
"is-map": "^2.0.3",
|
||||||
"is-set": "^2.0.3",
|
"is-set": "^2.0.3",
|
||||||
@@ -14881,6 +15009,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.18.tgz",
|
"resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.18.tgz",
|
||||||
"integrity": "sha512-qEcY+KJYlWyLH9vNbsr6/5j59AXk5ni5aakf8ldzBvGde6Iz4sxZGkJyWSAueTG7QhOvNRYb1lDdFmL5Td0QKA==",
|
"integrity": "sha512-qEcY+KJYlWyLH9vNbsr6/5j59AXk5ni5aakf8ldzBvGde6Iz4sxZGkJyWSAueTG7QhOvNRYb1lDdFmL5Td0QKA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"available-typed-arrays": "^1.0.7",
|
"available-typed-arrays": "^1.0.7",
|
||||||
"call-bind": "^1.0.8",
|
"call-bind": "^1.0.8",
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
"version": "3.18.1",
|
"version": "3.18.1",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"engines": {
|
"engines": {
|
||||||
"npm": "^10.2.x",
|
"npm": "^10.8.x",
|
||||||
"node": "^20.18.x"
|
"node": "^20.18.x"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
/*eslint max-lines: ["warn", {"max": 500, "skipBlankLines": true, "skipComments": true}]*/
|
||||||
import { model as HomebrewModel } from './homebrew.model.js';
|
import { model as HomebrewModel } from './homebrew.model.js';
|
||||||
import { model as NotificationModel } from './notifications.model.js';
|
import { model as NotificationModel } from './notifications.model.js';
|
||||||
import express from 'express';
|
import express from 'express';
|
||||||
@@ -11,6 +12,7 @@ import { splitTextStyleAndMetadata } from '../shared/helpers.js';
|
|||||||
|
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
|
|
||||||
|
|
||||||
process.env.ADMIN_USER = process.env.ADMIN_USER || 'admin';
|
process.env.ADMIN_USER = process.env.ADMIN_USER || 'admin';
|
||||||
process.env.ADMIN_PASS = process.env.ADMIN_PASS || 'password3';
|
process.env.ADMIN_PASS = process.env.ADMIN_PASS || 'password3';
|
||||||
|
|
||||||
@@ -162,6 +164,180 @@ router.get('/admin/stats', mw.adminOnly, async (req, res)=>{
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// ####################### LOCKS
|
||||||
|
|
||||||
|
router.get('/api/lock/count', mw.adminOnly, asyncHandler(async (req, res)=>{
|
||||||
|
|
||||||
|
const countLocksQuery = {
|
||||||
|
lock : { $exists: true }
|
||||||
|
};
|
||||||
|
const count = await HomebrewModel.countDocuments(countLocksQuery)
|
||||||
|
.catch((error)=>{
|
||||||
|
throw { name: 'Lock Count Error', message: 'Unable to get lock count', status: 500, HBErrorCode: '61', error };
|
||||||
|
});
|
||||||
|
|
||||||
|
return res.json({ count });
|
||||||
|
|
||||||
|
}));
|
||||||
|
|
||||||
|
router.get('/api/locks', mw.adminOnly, asyncHandler(async (req, res)=>{
|
||||||
|
const countLocksPipeline = [
|
||||||
|
{
|
||||||
|
$match :
|
||||||
|
{
|
||||||
|
'lock' : { '$exists': 1 }
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
$project : {
|
||||||
|
shareId : 1,
|
||||||
|
editId : 1,
|
||||||
|
title : 1,
|
||||||
|
lock : 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
||||||
|
const lockedDocuments = await HomebrewModel.aggregate(countLocksPipeline)
|
||||||
|
.catch((error)=>{
|
||||||
|
throw { name: 'Can Not Get Locked Brews', message: 'Unable to get locked brew collection', status: 500, HBErrorCode: '68', error };
|
||||||
|
});
|
||||||
|
return res.json({
|
||||||
|
lockedDocuments
|
||||||
|
});
|
||||||
|
|
||||||
|
}));
|
||||||
|
|
||||||
|
router.post('/api/lock/:id', mw.adminOnly, asyncHandler(async (req, res)=>{
|
||||||
|
|
||||||
|
const lock = req.body;
|
||||||
|
|
||||||
|
lock.applied = new Date;
|
||||||
|
|
||||||
|
const filter = {
|
||||||
|
shareId : req.params.id
|
||||||
|
};
|
||||||
|
|
||||||
|
const brew = await HomebrewModel.findOne(filter);
|
||||||
|
|
||||||
|
if(!brew) throw { name: 'Brew Not Found', message: 'Cannot find brew to lock', shareId: req.params.id, status: 500, HBErrorCode: '63' };
|
||||||
|
|
||||||
|
if(brew.lock && !lock.overwrite) {
|
||||||
|
throw { name: 'Already Locked', message: 'Lock already exists on brew', shareId: req.params.id, title: brew.title, status: 500, HBErrorCode: '64' };
|
||||||
|
}
|
||||||
|
|
||||||
|
lock.overwrite = undefined;
|
||||||
|
|
||||||
|
brew.lock = lock;
|
||||||
|
brew.markModified('lock');
|
||||||
|
|
||||||
|
await brew.save()
|
||||||
|
.catch((error)=>{
|
||||||
|
throw { name: 'Lock Error', message: 'Unable to set lock', shareId: req.params.id, status: 500, HBErrorCode: '62', error };
|
||||||
|
});
|
||||||
|
|
||||||
|
return res.json({ name: 'LOCKED', message: `Lock applied to brew ID ${brew.shareId} - ${brew.title}`, ...lock });
|
||||||
|
|
||||||
|
}));
|
||||||
|
|
||||||
|
router.put('/api/unlock/:id', mw.adminOnly, asyncHandler(async (req, res)=>{
|
||||||
|
|
||||||
|
const filter = {
|
||||||
|
shareId : req.params.id
|
||||||
|
};
|
||||||
|
|
||||||
|
const brew = await HomebrewModel.findOne(filter);
|
||||||
|
|
||||||
|
if(!brew) throw { name: 'Brew Not Found', message: 'Cannot find brew to unlock', shareId: req.params.id, status: 500, HBErrorCode: '66' };
|
||||||
|
|
||||||
|
if(!brew.lock) throw { name: 'Not Locked', message: 'Cannot unlock as brew is not locked', shareId: req.params.id, status: 500, HBErrorCode: '67' };
|
||||||
|
|
||||||
|
brew.lock = undefined;
|
||||||
|
brew.markModified('lock');
|
||||||
|
|
||||||
|
await brew.save()
|
||||||
|
.catch((error)=>{
|
||||||
|
throw { name: 'Cannot Unlock', message: 'Unable to clear lock', shareId: req.params.id, status: 500, HBErrorCode: '65', error };
|
||||||
|
});
|
||||||
|
|
||||||
|
return res.json({ name: 'Unlocked', message: `Lock removed from brew ID ${req.params.id}` });
|
||||||
|
}));
|
||||||
|
|
||||||
|
router.get('/api/lock/reviews', mw.adminOnly, asyncHandler(async (req, res)=>{
|
||||||
|
const countReviewsPipeline = [
|
||||||
|
{
|
||||||
|
$match :
|
||||||
|
{
|
||||||
|
'lock.reviewRequested' : { '$exists': 1 }
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
$project : {
|
||||||
|
shareId : 1,
|
||||||
|
editId : 1,
|
||||||
|
title : 1,
|
||||||
|
lock : 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
||||||
|
const reviewDocuments = await HomebrewModel.aggregate(countReviewsPipeline)
|
||||||
|
.catch((error)=>{
|
||||||
|
throw { name: 'Can Not Get Reviews', message: 'Unable to get review collection', status: 500, HBErrorCode: '68', error };
|
||||||
|
});
|
||||||
|
return res.json({
|
||||||
|
reviewDocuments
|
||||||
|
});
|
||||||
|
|
||||||
|
}));
|
||||||
|
|
||||||
|
router.put('/api/lock/review/request/:id', asyncHandler(async (req, res)=>{
|
||||||
|
// === This route is NOT Admin only ===
|
||||||
|
// Any user can request a review of their document
|
||||||
|
const filter = {
|
||||||
|
shareId : req.params.id,
|
||||||
|
lock : { $exists: 1 }
|
||||||
|
};
|
||||||
|
|
||||||
|
const brew = await HomebrewModel.findOne(filter);
|
||||||
|
if(!brew) { throw { name: 'Brew Not Found', message: `Cannot find a locked brew with ID ${req.params.id}`, code: 500, HBErrorCode: '70' }; };
|
||||||
|
|
||||||
|
if(brew.lock.reviewRequested){
|
||||||
|
throw { name: 'Review Already Requested', message: `Review already requested for brew ${brew.shareId} - ${brew.title}`, code: 500, HBErrorCode: '71' };
|
||||||
|
};
|
||||||
|
|
||||||
|
brew.lock.reviewRequested = new Date();
|
||||||
|
brew.markModified('lock');
|
||||||
|
|
||||||
|
await brew.save()
|
||||||
|
.catch((error)=>{
|
||||||
|
throw { name: 'Can Not Set Review Request', message: `Unable to set request for review on brew ID ${req.params.id}`, code: 500, HBErrorCode: '69', error };
|
||||||
|
});
|
||||||
|
|
||||||
|
return res.json({ name: 'Review Requested', message: `Review requested on brew ID ${brew.shareId} - ${brew.title}` });
|
||||||
|
|
||||||
|
}));
|
||||||
|
|
||||||
|
router.put('/api/lock/review/remove/:id', mw.adminOnly, asyncHandler(async (req, res)=>{
|
||||||
|
|
||||||
|
const filter = {
|
||||||
|
shareId : req.params.id,
|
||||||
|
'lock.reviewRequested' : { $exists: 1 }
|
||||||
|
};
|
||||||
|
|
||||||
|
const brew = await HomebrewModel.findOne(filter);
|
||||||
|
if(!brew) { throw { name: 'Can Not Clear Review Request', message: `Brew ID ${req.params.id} does not have a review pending!`, HBErrorCode: '73' }; };
|
||||||
|
|
||||||
|
brew.lock.reviewRequested = undefined;
|
||||||
|
brew.markModified('lock');
|
||||||
|
|
||||||
|
await brew.save()
|
||||||
|
.catch((error)=>{
|
||||||
|
throw { name: 'Can Not Clear Review Request', message: `Unable to remove request for review on brew ID ${req.params.id}`, HBErrorCode: '72', error };
|
||||||
|
});
|
||||||
|
|
||||||
|
return res.json({ name: 'Review Request Cleared', message: `Review request removed for brew ID ${brew.shareId} - ${brew.title}` });
|
||||||
|
|
||||||
|
}));
|
||||||
|
|
||||||
// ####################### NOTIFICATIONS
|
// ####################### NOTIFICATIONS
|
||||||
|
|
||||||
router.get('/admin/notification/all', async (req, res, next)=>{
|
router.get('/admin/notification/all', async (req, res, next)=>{
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
|
/*eslint max-lines: ["warn", {"max": 1000, "skipBlankLines": true, "skipComments": true}]*/
|
||||||
import supertest from 'supertest';
|
import supertest from 'supertest';
|
||||||
import HBApp from './app.js';
|
import HBApp from './app.js';
|
||||||
import { model as NotificationModel } from './notifications.model.js';
|
import { model as NotificationModel } from './notifications.model.js';
|
||||||
|
import { model as HomebrewModel } from './homebrew.model.js';
|
||||||
|
|
||||||
|
|
||||||
// Mimic https responses to avoid being redirected all the time
|
// Mimic https responses to avoid being redirected all the time
|
||||||
@@ -114,4 +116,590 @@ describe('Tests for admin api', ()=>{
|
|||||||
expect(response.body).toEqual({ message: 'Notification not found' });
|
expect(response.body).toEqual({ message: 'Notification not found' });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('Locks', ()=>{
|
||||||
|
describe('Count', ()=>{
|
||||||
|
it('Count of all locked documents', async ()=>{
|
||||||
|
const testNumber = 16777216; // 8^8, because why not
|
||||||
|
|
||||||
|
jest.spyOn(HomebrewModel, 'countDocuments')
|
||||||
|
.mockImplementationOnce(()=>{
|
||||||
|
return Promise.resolve(testNumber);
|
||||||
|
});
|
||||||
|
|
||||||
|
const response = await app
|
||||||
|
.set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`)
|
||||||
|
.get('/api/lock/count');
|
||||||
|
|
||||||
|
expect(response.status).toBe(200);
|
||||||
|
expect(response.body).toEqual({ count: testNumber });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Handle error while fetching count of locked documents', async ()=>{
|
||||||
|
jest.spyOn(HomebrewModel, 'countDocuments')
|
||||||
|
.mockImplementationOnce(()=>{
|
||||||
|
return Promise.reject();
|
||||||
|
});
|
||||||
|
|
||||||
|
const response = await app
|
||||||
|
.set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`)
|
||||||
|
.get('/api/lock/count');
|
||||||
|
|
||||||
|
expect(response.status).toBe(500);
|
||||||
|
expect(response.body).toEqual({
|
||||||
|
HBErrorCode : '61',
|
||||||
|
message : 'Unable to get lock count',
|
||||||
|
name : 'Lock Count Error',
|
||||||
|
originalUrl : '/api/lock/count',
|
||||||
|
status : 500,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Lists', ()=>{
|
||||||
|
it('Get list of all locked documents', async ()=>{
|
||||||
|
const testLocks = ['a', 'b'];
|
||||||
|
|
||||||
|
jest.spyOn(HomebrewModel, 'aggregate')
|
||||||
|
.mockImplementationOnce(()=>{
|
||||||
|
return Promise.resolve(testLocks);
|
||||||
|
});
|
||||||
|
|
||||||
|
const response = await app
|
||||||
|
.set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`)
|
||||||
|
.get('/api/locks');
|
||||||
|
|
||||||
|
expect(response.status).toBe(200);
|
||||||
|
expect(response.body).toEqual({ lockedDocuments: testLocks });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Handle error while fetching list of all locked documents', async ()=>{
|
||||||
|
jest.spyOn(HomebrewModel, 'aggregate')
|
||||||
|
.mockImplementationOnce(()=>{
|
||||||
|
return Promise.reject();
|
||||||
|
});
|
||||||
|
|
||||||
|
const response = await app
|
||||||
|
.set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`)
|
||||||
|
.get('/api/locks');
|
||||||
|
|
||||||
|
expect(response.status).toBe(500);
|
||||||
|
expect(response.body).toEqual({
|
||||||
|
HBErrorCode : '68',
|
||||||
|
message : 'Unable to get locked brew collection',
|
||||||
|
name : 'Can Not Get Locked Brews',
|
||||||
|
originalUrl : '/api/locks',
|
||||||
|
status : 500
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Get list of all locked documents with pending review requests', async ()=>{
|
||||||
|
const testLocks = ['a', 'b'];
|
||||||
|
|
||||||
|
jest.spyOn(HomebrewModel, 'aggregate')
|
||||||
|
.mockImplementationOnce(()=>{
|
||||||
|
return Promise.resolve(testLocks);
|
||||||
|
});
|
||||||
|
|
||||||
|
const response = await app
|
||||||
|
.set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`)
|
||||||
|
.get('/api/lock/reviews');
|
||||||
|
|
||||||
|
expect(response.status).toBe(200);
|
||||||
|
expect(response.body).toEqual({ reviewDocuments: testLocks });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Handle error while fetching list of all locked documents with pending review requests', async ()=>{
|
||||||
|
jest.spyOn(HomebrewModel, 'aggregate')
|
||||||
|
.mockImplementationOnce(()=>{
|
||||||
|
return Promise.reject();
|
||||||
|
});
|
||||||
|
|
||||||
|
const response = await app
|
||||||
|
.set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`)
|
||||||
|
.get('/api/lock/reviews');
|
||||||
|
|
||||||
|
expect(response.status).toBe(500);
|
||||||
|
expect(response.body).toEqual({
|
||||||
|
HBErrorCode : '68',
|
||||||
|
message : 'Unable to get review collection',
|
||||||
|
name : 'Can Not Get Reviews',
|
||||||
|
originalUrl : '/api/lock/reviews',
|
||||||
|
status : 500
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Lock', ()=>{
|
||||||
|
it('Lock a brew', async ()=>{
|
||||||
|
const testBrew = {
|
||||||
|
shareId : 'shareId',
|
||||||
|
title : 'title',
|
||||||
|
markModified : ()=>{ return true; },
|
||||||
|
save : ()=>{ return Promise.resolve(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
const testLock = {
|
||||||
|
code : 999,
|
||||||
|
editMessage : 'edit',
|
||||||
|
shareMessage : 'share'
|
||||||
|
};
|
||||||
|
|
||||||
|
jest.spyOn(HomebrewModel, 'findOne')
|
||||||
|
.mockImplementationOnce(()=>{
|
||||||
|
return Promise.resolve(testBrew);
|
||||||
|
});
|
||||||
|
|
||||||
|
const response = await app
|
||||||
|
.set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`)
|
||||||
|
.post(`/api/lock/${testBrew.shareId}`)
|
||||||
|
.send(testLock);
|
||||||
|
|
||||||
|
expect(response.status).toBe(200);
|
||||||
|
expect(response.body).toMatchObject({
|
||||||
|
applied : expect.any(String),
|
||||||
|
code : testLock.code,
|
||||||
|
editMessage : testLock.editMessage,
|
||||||
|
shareMessage : testLock.shareMessage,
|
||||||
|
name : 'LOCKED',
|
||||||
|
message : `Lock applied to brew ID ${testBrew.shareId} - ${testBrew.title}`
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Overwrite lock on a locked brew', async ()=>{
|
||||||
|
const testLock = {
|
||||||
|
code : 999,
|
||||||
|
editMessage : 'newEdit',
|
||||||
|
shareMessage : 'newShare',
|
||||||
|
overwrite : true
|
||||||
|
};
|
||||||
|
|
||||||
|
const testBrew = {
|
||||||
|
shareId : 'shareId',
|
||||||
|
title : 'title',
|
||||||
|
markModified : ()=>{ return true; },
|
||||||
|
save : ()=>{ return Promise.resolve(); },
|
||||||
|
lock : {
|
||||||
|
code : 1,
|
||||||
|
editMessage : 'oldEdit',
|
||||||
|
shareMessage : 'oldShare',
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
jest.spyOn(HomebrewModel, 'findOne')
|
||||||
|
.mockImplementationOnce(()=>{
|
||||||
|
return Promise.resolve(testBrew);
|
||||||
|
});
|
||||||
|
|
||||||
|
const response = await app
|
||||||
|
.set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`)
|
||||||
|
.post(`/api/lock/${testBrew.shareId}`)
|
||||||
|
.send(testLock);
|
||||||
|
|
||||||
|
expect(response.status).toBe(200);
|
||||||
|
expect(response.body).toMatchObject({
|
||||||
|
applied : expect.any(String),
|
||||||
|
code : testLock.code,
|
||||||
|
editMessage : testLock.editMessage,
|
||||||
|
shareMessage : testLock.shareMessage,
|
||||||
|
name : 'LOCKED',
|
||||||
|
message : `Lock applied to brew ID ${testBrew.shareId} - ${testBrew.title}`
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Error when locking a locked brew', async ()=>{
|
||||||
|
const testLock = {
|
||||||
|
code : 999,
|
||||||
|
editMessage : 'newEdit',
|
||||||
|
shareMessage : 'newShare'
|
||||||
|
};
|
||||||
|
|
||||||
|
const testBrew = {
|
||||||
|
shareId : 'shareId',
|
||||||
|
title : 'title',
|
||||||
|
markModified : ()=>{ return true; },
|
||||||
|
save : ()=>{ return Promise.resolve(); },
|
||||||
|
lock : {
|
||||||
|
code : 1,
|
||||||
|
editMessage : 'oldEdit',
|
||||||
|
shareMessage : 'oldShare',
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
jest.spyOn(HomebrewModel, 'findOne')
|
||||||
|
.mockImplementationOnce(()=>{
|
||||||
|
return Promise.resolve(testBrew);
|
||||||
|
});
|
||||||
|
|
||||||
|
const response = await app
|
||||||
|
.set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`)
|
||||||
|
.post(`/api/lock/${testBrew.shareId}`)
|
||||||
|
.send(testLock);
|
||||||
|
|
||||||
|
expect(response.status).toBe(500);
|
||||||
|
expect(response.body).toEqual({
|
||||||
|
HBErrorCode : '64',
|
||||||
|
message : 'Lock already exists on brew',
|
||||||
|
name : 'Already Locked',
|
||||||
|
originalUrl : `/api/lock/${testBrew.shareId}`,
|
||||||
|
shareId : testBrew.shareId,
|
||||||
|
status : 500,
|
||||||
|
title : 'title'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Handle save error while locking a brew', async ()=>{
|
||||||
|
const testBrew = {
|
||||||
|
shareId : 'shareId',
|
||||||
|
title : 'title',
|
||||||
|
markModified : ()=>{ return true; },
|
||||||
|
save : ()=>{ return Promise.reject(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
const testLock = {
|
||||||
|
code : 999,
|
||||||
|
editMessage : 'edit',
|
||||||
|
shareMessage : 'share'
|
||||||
|
};
|
||||||
|
|
||||||
|
jest.spyOn(HomebrewModel, 'findOne')
|
||||||
|
.mockImplementationOnce(()=>{
|
||||||
|
return Promise.resolve(testBrew);
|
||||||
|
});
|
||||||
|
|
||||||
|
const response = await app
|
||||||
|
.set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`)
|
||||||
|
.post(`/api/lock/${testBrew.shareId}`)
|
||||||
|
.send(testLock);
|
||||||
|
|
||||||
|
expect(response.status).toBe(500);
|
||||||
|
expect(response.body).toEqual({
|
||||||
|
HBErrorCode : '62',
|
||||||
|
message : 'Unable to set lock',
|
||||||
|
name : 'Lock Error',
|
||||||
|
originalUrl : `/api/lock/${testBrew.shareId}`,
|
||||||
|
shareId : testBrew.shareId,
|
||||||
|
status : 500
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Unlock', ()=>{
|
||||||
|
it('Unlock a brew', async ()=>{
|
||||||
|
const testLock = {
|
||||||
|
applied : 'YES',
|
||||||
|
code : 999,
|
||||||
|
editMessage : 'edit',
|
||||||
|
shareMessage : 'share'
|
||||||
|
};
|
||||||
|
|
||||||
|
const testBrew = {
|
||||||
|
shareId : 'shareId',
|
||||||
|
title : 'title',
|
||||||
|
markModified : ()=>{ return true; },
|
||||||
|
save : ()=>{ return Promise.resolve(); },
|
||||||
|
lock : testLock
|
||||||
|
};
|
||||||
|
|
||||||
|
jest.spyOn(HomebrewModel, 'findOne')
|
||||||
|
.mockImplementationOnce(()=>{
|
||||||
|
return Promise.resolve(testBrew);
|
||||||
|
});
|
||||||
|
|
||||||
|
const response = await app
|
||||||
|
.set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`)
|
||||||
|
.put(`/api/unlock/${testBrew.shareId}`);
|
||||||
|
|
||||||
|
expect(response.status).toBe(200);
|
||||||
|
expect(response.body).toEqual({
|
||||||
|
name : 'Unlocked',
|
||||||
|
message : `Lock removed from brew ID ${testBrew.shareId}`
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Error when unlocking a brew with no lock', async ()=>{
|
||||||
|
const testBrew = {
|
||||||
|
shareId : 'shareId',
|
||||||
|
title : 'title',
|
||||||
|
markModified : ()=>{ return true; },
|
||||||
|
save : ()=>{ return Promise.resolve(); },
|
||||||
|
};
|
||||||
|
|
||||||
|
jest.spyOn(HomebrewModel, 'findOne')
|
||||||
|
.mockImplementationOnce(()=>{
|
||||||
|
return Promise.resolve(testBrew);
|
||||||
|
});
|
||||||
|
|
||||||
|
const response = await app
|
||||||
|
.set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`)
|
||||||
|
.put(`/api/unlock/${testBrew.shareId}`);
|
||||||
|
|
||||||
|
expect(response.status).toBe(500);
|
||||||
|
expect(response.body).toEqual({
|
||||||
|
HBErrorCode : '67',
|
||||||
|
message : 'Cannot unlock as brew is not locked',
|
||||||
|
name : 'Not Locked',
|
||||||
|
originalUrl : `/api/unlock/${testBrew.shareId}`,
|
||||||
|
shareId : testBrew.shareId,
|
||||||
|
status : 500,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Handle error while unlocking a brew', async ()=>{
|
||||||
|
const testLock = {
|
||||||
|
applied : 'YES',
|
||||||
|
code : 999,
|
||||||
|
editMessage : 'edit',
|
||||||
|
shareMessage : 'share'
|
||||||
|
};
|
||||||
|
|
||||||
|
const testBrew = {
|
||||||
|
shareId : 'shareId',
|
||||||
|
title : 'title',
|
||||||
|
markModified : ()=>{ return true; },
|
||||||
|
save : ()=>{ return Promise.reject(); },
|
||||||
|
lock : testLock
|
||||||
|
};
|
||||||
|
|
||||||
|
jest.spyOn(HomebrewModel, 'findOne')
|
||||||
|
.mockImplementationOnce(()=>{
|
||||||
|
return Promise.resolve(testBrew);
|
||||||
|
});
|
||||||
|
|
||||||
|
const response = await app
|
||||||
|
.set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`)
|
||||||
|
.put(`/api/unlock/${testBrew.shareId}`);
|
||||||
|
|
||||||
|
expect(response.status).toBe(500);
|
||||||
|
expect(response.body).toEqual({
|
||||||
|
HBErrorCode : '65',
|
||||||
|
message : 'Unable to clear lock',
|
||||||
|
name : 'Cannot Unlock',
|
||||||
|
originalUrl : `/api/unlock/${testBrew.shareId}`,
|
||||||
|
shareId : testBrew.shareId,
|
||||||
|
status : 500
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Reviews', ()=>{
|
||||||
|
it('Add review request to a locked brew', async ()=>{
|
||||||
|
const testLock = {
|
||||||
|
applied : 'YES',
|
||||||
|
code : 999,
|
||||||
|
editMessage : 'edit',
|
||||||
|
shareMessage : 'share'
|
||||||
|
};
|
||||||
|
|
||||||
|
const testBrew = {
|
||||||
|
shareId : 'shareId',
|
||||||
|
title : 'title',
|
||||||
|
markModified : ()=>{ return true; },
|
||||||
|
save : ()=>{ return Promise.resolve(); },
|
||||||
|
lock : testLock
|
||||||
|
};
|
||||||
|
|
||||||
|
jest.spyOn(HomebrewModel, 'findOne')
|
||||||
|
.mockImplementationOnce(()=>{
|
||||||
|
return Promise.resolve(testBrew);
|
||||||
|
});
|
||||||
|
|
||||||
|
const response = await app
|
||||||
|
.put(`/api/lock/review/request/${testBrew.shareId}`);
|
||||||
|
|
||||||
|
expect(response.status).toBe(200);
|
||||||
|
expect(response.body).toEqual({
|
||||||
|
message : `Review requested on brew ID ${testBrew.shareId} - ${testBrew.title}`,
|
||||||
|
name : 'Review Requested',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Error when cannot find a locked brew', async ()=>{
|
||||||
|
const testBrew = {
|
||||||
|
shareId : 'shareId'
|
||||||
|
};
|
||||||
|
|
||||||
|
jest.spyOn(HomebrewModel, 'findOne')
|
||||||
|
.mockImplementationOnce(()=>{
|
||||||
|
return Promise.resolve(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
const response = await app
|
||||||
|
.put(`/api/lock/review/request/${testBrew.shareId}`)
|
||||||
|
.catch((err)=>{return err;});
|
||||||
|
|
||||||
|
expect(response.status).toBe(500);
|
||||||
|
expect(response.body).toEqual({
|
||||||
|
message : `Cannot find a locked brew with ID ${testBrew.shareId}`,
|
||||||
|
name : 'Brew Not Found',
|
||||||
|
HBErrorCode : '70',
|
||||||
|
code : 500,
|
||||||
|
originalUrl : `/api/lock/review/request/${testBrew.shareId}`
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Error when review is already requested', async ()=>{
|
||||||
|
const testLock = {
|
||||||
|
applied : 'YES',
|
||||||
|
code : 999,
|
||||||
|
editMessage : 'edit',
|
||||||
|
shareMessage : 'share',
|
||||||
|
reviewRequested : 'YES'
|
||||||
|
};
|
||||||
|
|
||||||
|
const testBrew = {
|
||||||
|
shareId : 'shareId',
|
||||||
|
title : 'title',
|
||||||
|
markModified : ()=>{ return true; },
|
||||||
|
save : ()=>{ return Promise.resolve(); },
|
||||||
|
lock : testLock
|
||||||
|
};
|
||||||
|
|
||||||
|
jest.spyOn(HomebrewModel, 'findOne')
|
||||||
|
.mockImplementationOnce(()=>{
|
||||||
|
return Promise.resolve(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
const response = await app
|
||||||
|
.put(`/api/lock/review/request/${testBrew.shareId}`)
|
||||||
|
.catch((err)=>{return err;});
|
||||||
|
|
||||||
|
expect(response.status).toBe(500);
|
||||||
|
expect(response.body).toEqual({
|
||||||
|
HBErrorCode : '70',
|
||||||
|
code : 500,
|
||||||
|
message : `Cannot find a locked brew with ID ${testBrew.shareId}`,
|
||||||
|
name : 'Brew Not Found',
|
||||||
|
originalUrl : `/api/lock/review/request/${testBrew.shareId}`
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Handle error while adding review request to a locked brew', async ()=>{
|
||||||
|
const testLock = {
|
||||||
|
applied : 'YES',
|
||||||
|
code : 999,
|
||||||
|
editMessage : 'edit',
|
||||||
|
shareMessage : 'share'
|
||||||
|
};
|
||||||
|
|
||||||
|
const testBrew = {
|
||||||
|
shareId : 'shareId',
|
||||||
|
title : 'title',
|
||||||
|
markModified : ()=>{ return true; },
|
||||||
|
save : ()=>{ return Promise.reject(); },
|
||||||
|
lock : testLock
|
||||||
|
};
|
||||||
|
|
||||||
|
jest.spyOn(HomebrewModel, 'findOne')
|
||||||
|
.mockImplementationOnce(()=>{
|
||||||
|
return Promise.resolve(testBrew);
|
||||||
|
});
|
||||||
|
|
||||||
|
const response = await app
|
||||||
|
.put(`/api/lock/review/request/${testBrew.shareId}`);
|
||||||
|
|
||||||
|
expect(response.status).toBe(500);
|
||||||
|
expect(response.body).toEqual({
|
||||||
|
HBErrorCode : '69',
|
||||||
|
code : 500,
|
||||||
|
message : `Unable to set request for review on brew ID ${testBrew.shareId}`,
|
||||||
|
name : 'Can Not Set Review Request',
|
||||||
|
originalUrl : `/api/lock/review/request/${testBrew.shareId}`
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Clear review request from a locked brew', async ()=>{
|
||||||
|
const testLock = {
|
||||||
|
applied : 'YES',
|
||||||
|
code : 999,
|
||||||
|
editMessage : 'edit',
|
||||||
|
shareMessage : 'share',
|
||||||
|
reviewRequested : 'YES'
|
||||||
|
};
|
||||||
|
|
||||||
|
const testBrew = {
|
||||||
|
shareId : 'shareId',
|
||||||
|
title : 'title',
|
||||||
|
markModified : ()=>{ return true; },
|
||||||
|
save : ()=>{ return Promise.resolve(); },
|
||||||
|
lock : testLock
|
||||||
|
};
|
||||||
|
|
||||||
|
jest.spyOn(HomebrewModel, 'findOne')
|
||||||
|
.mockImplementationOnce(()=>{
|
||||||
|
return Promise.resolve(testBrew);
|
||||||
|
});
|
||||||
|
|
||||||
|
const response = await app
|
||||||
|
.set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`)
|
||||||
|
.put(`/api/lock/review/remove/${testBrew.shareId}`);
|
||||||
|
|
||||||
|
expect(response.status).toBe(200);
|
||||||
|
expect(response.body).toEqual({
|
||||||
|
message : `Review request removed for brew ID ${testBrew.shareId} - ${testBrew.title}`,
|
||||||
|
name : 'Review Request Cleared'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Error when clearing review request from a brew with no review request', async ()=>{
|
||||||
|
const testBrew = {
|
||||||
|
shareId : 'shareId',
|
||||||
|
};
|
||||||
|
|
||||||
|
jest.spyOn(HomebrewModel, 'findOne')
|
||||||
|
.mockImplementationOnce(()=>{
|
||||||
|
return Promise.resolve(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
const response = await app
|
||||||
|
.set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`)
|
||||||
|
.put(`/api/lock/review/remove/${testBrew.shareId}`);
|
||||||
|
|
||||||
|
expect(response.status).toBe(500);
|
||||||
|
expect(response.body).toEqual({
|
||||||
|
HBErrorCode : '73',
|
||||||
|
message : `Brew ID ${testBrew.shareId} does not have a review pending!`,
|
||||||
|
name : 'Can Not Clear Review Request',
|
||||||
|
originalUrl : `/api/lock/review/remove/${testBrew.shareId}`
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Handle error while clearing review request from a locked brew', async ()=>{
|
||||||
|
const testLock = {
|
||||||
|
applied : 'YES',
|
||||||
|
code : 999,
|
||||||
|
editMessage : 'edit',
|
||||||
|
shareMessage : 'share',
|
||||||
|
reviewRequested : 'YES'
|
||||||
|
};
|
||||||
|
|
||||||
|
const testBrew = {
|
||||||
|
shareId : 'shareId',
|
||||||
|
title : 'title',
|
||||||
|
markModified : ()=>{ return true; },
|
||||||
|
save : ()=>{ return Promise.reject(); },
|
||||||
|
lock : testLock
|
||||||
|
};
|
||||||
|
|
||||||
|
jest.spyOn(HomebrewModel, 'findOne')
|
||||||
|
.mockImplementationOnce(()=>{
|
||||||
|
return Promise.resolve(testBrew);
|
||||||
|
});
|
||||||
|
|
||||||
|
const response = await app
|
||||||
|
.set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`)
|
||||||
|
.put(`/api/lock/review/remove/${testBrew.shareId}`);
|
||||||
|
|
||||||
|
expect(response.status).toBe(500);
|
||||||
|
expect(response.body).toEqual({
|
||||||
|
HBErrorCode : '72',
|
||||||
|
message : `Unable to remove request for review on brew ID ${testBrew.shareId}`,
|
||||||
|
name : 'Can Not Clear Review Request',
|
||||||
|
originalUrl : `/api/lock/review/remove/${testBrew.shareId}`
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
// Set working directory to project root
|
// Set working directory to project root
|
||||||
import { dirname } from 'path';
|
import { dirname } from 'path';
|
||||||
import { fileURLToPath } from 'url';
|
import { fileURLToPath } from 'url';
|
||||||
import packageJSON from './../package.json' with { type: 'json' };
|
import packageJSON from './../package.json' with { type: 'json' };
|
||||||
|
|
||||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||||
process.chdir(`${__dirname}/..`);
|
process.chdir(`${__dirname}/..`);
|
||||||
|
|||||||
@@ -8,9 +8,11 @@ import Markdown from '../shared/naturalcrit/markdown.js';
|
|||||||
import yaml from 'js-yaml';
|
import yaml from 'js-yaml';
|
||||||
import asyncHandler from 'express-async-handler';
|
import asyncHandler from 'express-async-handler';
|
||||||
import { nanoid } from 'nanoid';
|
import { nanoid } from 'nanoid';
|
||||||
import { splitTextStyleAndMetadata } from '../shared/helpers.js';
|
import { splitTextStyleAndMetadata,
|
||||||
|
brewSnippetsToJSON } from '../shared/helpers.js';
|
||||||
import checkClientVersion from './middleware/check-client-version.js';
|
import checkClientVersion from './middleware/check-client-version.js';
|
||||||
|
|
||||||
|
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
|
|
||||||
import { DEFAULT_BREW, DEFAULT_BREW_LOAD } from './brewDefaults.js';
|
import { DEFAULT_BREW, DEFAULT_BREW_LOAD } from './brewDefaults.js';
|
||||||
@@ -118,8 +120,8 @@ const api = {
|
|||||||
throw { ...accessError, message: 'User is not logged in', HBErrorCode: '04' };
|
throw { ...accessError, message: 'User is not logged in', HBErrorCode: '04' };
|
||||||
}
|
}
|
||||||
|
|
||||||
if(stub?.lock?.locked && accessType != 'edit') {
|
if(stub?.lock && accessType === 'share') {
|
||||||
throw { HBErrorCode: '51', code: stub?.lock.code, message: stub?.lock.shareMessage, brewId: stub?.shareId, brewTitle: stub?.title };
|
throw { HBErrorCode: '51', code: stub.lock.code, message: stub.lock.shareMessage, brewId: stub.shareId, brewTitle: stub.title, brewAuthors: stub.authors };
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there's a google id, get it if requesting the full brew or if no stub found yet
|
// If there's a google id, get it if requesting the full brew or if no stub found yet
|
||||||
@@ -175,6 +177,8 @@ const api = {
|
|||||||
`${text}`;
|
`${text}`;
|
||||||
}
|
}
|
||||||
const metadata = _.pick(brew, ['title', 'description', 'tags', 'systems', 'renderer', 'theme']);
|
const metadata = _.pick(brew, ['title', 'description', 'tags', 'systems', 'renderer', 'theme']);
|
||||||
|
const snippetsArray = brewSnippetsToJSON('brew_snippets', brew.snippets, null, false).snippets;
|
||||||
|
metadata.snippets = snippetsArray.length > 0 ? snippetsArray : undefined;
|
||||||
text = `\`\`\`metadata\n` +
|
text = `\`\`\`metadata\n` +
|
||||||
`${yaml.dump(metadata)}\n` +
|
`${yaml.dump(metadata)}\n` +
|
||||||
`\`\`\`\n\n` +
|
`\`\`\`\n\n` +
|
||||||
@@ -301,7 +305,7 @@ const api = {
|
|||||||
themeAuthor ??= currentTheme.authors?.[0];
|
themeAuthor ??= currentTheme.authors?.[0];
|
||||||
|
|
||||||
// If there is anything in the snippets or style members, append them to the appropriate array
|
// If there is anything in the snippets or style members, append them to the appropriate array
|
||||||
if(currentTheme?.snippets) completeSnippets.push(JSON.parse(currentTheme.snippets));
|
if(currentTheme?.snippets) completeSnippets.push({ name: currentTheme.title, snippets: currentTheme.snippets });
|
||||||
if(currentTheme?.style) completeStyles.push(`/* From Brew: ${req.protocol}://${req.get('host')}/share/${req.params.id} */\n\n${currentTheme.style}`);
|
if(currentTheme?.style) completeStyles.push(`/* From Brew: ${req.protocol}://${req.get('host')}/share/${req.params.id} */\n\n${currentTheme.style}`);
|
||||||
|
|
||||||
req.params.id = currentTheme.theme;
|
req.params.id = currentTheme.theme;
|
||||||
|
|||||||
@@ -302,7 +302,7 @@ describe('Tests for api', ()=>{
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('access is denied to a locked brew', async()=>{
|
it('access is denied to a locked brew', async()=>{
|
||||||
const lockBrew = { title: 'test brew', shareId: '1', lock: { locked: true, code: 404, shareMessage: 'brew locked' } };
|
const lockBrew = { title: 'test brew', shareId: '1', lock: { code: 404, shareMessage: 'brew locked' } };
|
||||||
model.get = jest.fn(()=>toBrewPromise(lockBrew));
|
model.get = jest.fn(()=>toBrewPromise(lockBrew));
|
||||||
api.getId = jest.fn(()=>({ id: '1', googleId: undefined }));
|
api.getId = jest.fn(()=>({ id: '1', googleId: undefined }));
|
||||||
|
|
||||||
@@ -939,7 +939,7 @@ brew`);
|
|||||||
});
|
});
|
||||||
describe('Get CSS', ()=>{
|
describe('Get CSS', ()=>{
|
||||||
it('should return brew style content as CSS text', async ()=>{
|
it('should return brew style content as CSS text', async ()=>{
|
||||||
const testBrew = { title: 'test brew', text: '```css\n\nI Have a style!\n````\n\n' };
|
const testBrew = { title: 'test brew', text: '```css\n\nI Have a style!\n```\n\n' };
|
||||||
|
|
||||||
const toBrewPromise = (brew)=>new Promise((res)=>res({ toObject: ()=>brew }));
|
const toBrewPromise = (brew)=>new Promise((res)=>res({ toObject: ()=>brew }));
|
||||||
api.getId = jest.fn(()=>({ id: '1', googleId: undefined }));
|
api.getId = jest.fn(()=>({ id: '1', googleId: undefined }));
|
||||||
@@ -1034,7 +1034,7 @@ brew`);
|
|||||||
expect(testBrew.theme).toEqual('5ePHB');
|
expect(testBrew.theme).toEqual('5ePHB');
|
||||||
expect(testBrew.lang).toEqual('en');
|
expect(testBrew.lang).toEqual('en');
|
||||||
// Style
|
// Style
|
||||||
expect(testBrew.style).toEqual('style\nstyle\nstyle');
|
expect(testBrew.style).toEqual('style\nstyle\nstyle\n');
|
||||||
// Text
|
// Text
|
||||||
expect(testBrew.text).toEqual('text\n');
|
expect(testBrew.text).toEqual('text\n');
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -27,7 +27,9 @@ const HomebrewSchema = mongoose.Schema({
|
|||||||
updatedAt : { type: Date, default: Date.now },
|
updatedAt : { type: Date, default: Date.now },
|
||||||
lastViewed : { type: Date, default: Date.now },
|
lastViewed : { type: Date, default: Date.now },
|
||||||
views : { type: Number, default: 0 },
|
views : { type: Number, default: 0 },
|
||||||
version : { type: Number, default: 1 }
|
version : { type: Number, default: 1 },
|
||||||
|
|
||||||
|
lock : { type: Object }
|
||||||
}, { versionKey: false });
|
}, { versionKey: false });
|
||||||
|
|
||||||
HomebrewSchema.statics.increaseView = async function(query) {
|
HomebrewSchema.statics.increaseView = async function(query) {
|
||||||
|
|||||||
@@ -2,24 +2,103 @@ import _ from 'lodash';
|
|||||||
import yaml from 'js-yaml';
|
import yaml from 'js-yaml';
|
||||||
import request from '../client/homebrew/utils/request-middleware.js';
|
import request from '../client/homebrew/utils/request-middleware.js';
|
||||||
|
|
||||||
|
// Convert the templates from a brew to a Snippets Structure.
|
||||||
|
const brewSnippetsToJSON = (menuTitle, userBrewSnippets, themeBundleSnippets=null, full=true)=>{
|
||||||
|
const textSplit = /^(\\snippet +.+\n)/gm;
|
||||||
|
const mpAsSnippets = [];
|
||||||
|
// Snippets from Themes first.
|
||||||
|
if(themeBundleSnippets) {
|
||||||
|
for (let themes of themeBundleSnippets) {
|
||||||
|
if(typeof themes !== 'string') {
|
||||||
|
const userSnippets = [];
|
||||||
|
const snipSplit = themes.snippets.trim().split(textSplit).slice(1);
|
||||||
|
for (let snips = 0; snips < snipSplit.length; snips+=2) {
|
||||||
|
if(!snipSplit[snips].startsWith('\\snippet ')) break;
|
||||||
|
const snippetName = snipSplit[snips].split(/\\snippet +/)[1].split('\n')[0].trim();
|
||||||
|
if(snippetName.length != 0) {
|
||||||
|
userSnippets.push({
|
||||||
|
name : snippetName,
|
||||||
|
icon : '',
|
||||||
|
gen : snipSplit[snips + 1],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(userSnippets.length > 0) {
|
||||||
|
mpAsSnippets.push({
|
||||||
|
name : themes.name,
|
||||||
|
icon : '',
|
||||||
|
gen : '',
|
||||||
|
subsnippets : userSnippets
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Local Snippets
|
||||||
|
if(userBrewSnippets) {
|
||||||
|
const userSnippets = [];
|
||||||
|
const snipSplit = userBrewSnippets.trim().split(textSplit).slice(1);
|
||||||
|
for (let snips = 0; snips < snipSplit.length; snips+=2) {
|
||||||
|
if(!snipSplit[snips].startsWith('\\snippet ')) break;
|
||||||
|
const snippetName = snipSplit[snips].split(/\\snippet +/)[1].split('\n')[0].trim();
|
||||||
|
if(snippetName.length != 0) {
|
||||||
|
const subSnip = {
|
||||||
|
name : snippetName,
|
||||||
|
gen : snipSplit[snips + 1],
|
||||||
|
};
|
||||||
|
// if(full) subSnip.icon = '';
|
||||||
|
userSnippets.push(subSnip);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(userSnippets.length) {
|
||||||
|
mpAsSnippets.push({
|
||||||
|
name : menuTitle,
|
||||||
|
// icon : '',
|
||||||
|
subsnippets : userSnippets
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const returnObj = {
|
||||||
|
snippets : mpAsSnippets
|
||||||
|
};
|
||||||
|
|
||||||
|
if(full) {
|
||||||
|
returnObj.groupName = 'Brew Snippets';
|
||||||
|
returnObj.icon = 'fas fa-th-list';
|
||||||
|
returnObj.view = 'text';
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnObj;
|
||||||
|
};
|
||||||
|
|
||||||
|
const yamlSnippetsToText = (yamlObj)=>{
|
||||||
|
if(typeof yamlObj == 'string') return yamlObj;
|
||||||
|
|
||||||
|
let snippetsText = '';
|
||||||
|
|
||||||
|
for (let snippet of yamlObj) {
|
||||||
|
for (let subSnippet of snippet.subsnippets) {
|
||||||
|
snippetsText = `${snippetsText}\\snippet ${subSnippet.name}\n${subSnippet.gen || ''}\n`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return snippetsText;
|
||||||
|
};
|
||||||
|
|
||||||
const splitTextStyleAndMetadata = (brew)=>{
|
const splitTextStyleAndMetadata = (brew)=>{
|
||||||
brew.text = brew.text.replaceAll('\r\n', '\n');
|
brew.text = brew.text.replaceAll('\r\n', '\n');
|
||||||
if(brew.text.startsWith('```metadata')) {
|
if(brew.text.startsWith('```metadata')) {
|
||||||
const index = brew.text.indexOf('```\n\n');
|
const index = brew.text.indexOf('\n```\n\n');
|
||||||
const metadataSection = brew.text.slice(12, index - 1);
|
const metadataSection = brew.text.slice(11, index + 1);
|
||||||
const metadata = yaml.load(metadataSection);
|
const metadata = yaml.load(metadataSection);
|
||||||
Object.assign(brew, _.pick(metadata, ['title', 'description', 'tags', 'systems', 'renderer', 'theme', 'lang']));
|
Object.assign(brew, _.pick(metadata, ['title', 'description', 'tags', 'systems', 'renderer', 'theme', 'lang']));
|
||||||
brew.text = brew.text.slice(index + 5);
|
brew.snippets = yamlSnippetsToText(_.pick(metadata, ['snippets']).snippets || '');
|
||||||
|
brew.text = brew.text.slice(index + 6);
|
||||||
}
|
}
|
||||||
if(brew.text.startsWith('```css')) {
|
if(brew.text.startsWith('```css')) {
|
||||||
const index = brew.text.indexOf('```\n\n');
|
const index = brew.text.indexOf('\n```\n\n');
|
||||||
brew.style = brew.text.slice(7, index - 1);
|
brew.style = brew.text.slice(7, index + 1);
|
||||||
brew.text = brew.text.slice(index + 5);
|
brew.text = brew.text.slice(index + 6);
|
||||||
}
|
|
||||||
if(brew.text.startsWith('```snippets')) {
|
|
||||||
const index = brew.text.indexOf('```\n\n');
|
|
||||||
brew.snippets = brew.text.slice(11, index - 1);
|
|
||||||
brew.text = brew.text.slice(index + 5);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle old brews that still have empty strings in the tags metadata
|
// Handle old brews that still have empty strings in the tags metadata
|
||||||
@@ -64,4 +143,5 @@ export {
|
|||||||
splitTextStyleAndMetadata,
|
splitTextStyleAndMetadata,
|
||||||
printCurrentBrew,
|
printCurrentBrew,
|
||||||
fetchThemeBundle,
|
fetchThemeBundle,
|
||||||
|
brewSnippetsToJSON
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user