You've already forked joplin
mirror of
https://github.com/laurent22/joplin.git
synced 2025-07-16 00:14:34 +02:00
Doc: Add Joplin Cloud feature descriptions to Plans page
This commit is contained in:
@ -667,6 +667,30 @@ footer .bottom-links-row p {
|
|||||||
color: #0557ba;
|
color: #0557ba;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.joplin-cloud-feature-list .feature-description {
|
||||||
|
max-width: 600px;
|
||||||
|
font-size: .8em;
|
||||||
|
color: #555555;
|
||||||
|
margin-top: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.joplin-cloud-feature-list .feature-title {
|
||||||
|
text-decoration: none;
|
||||||
|
color: #000000;
|
||||||
|
margin-left: 10px;
|
||||||
|
border: 2px solid black;
|
||||||
|
display: inline-block;
|
||||||
|
width: 20px;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
border-radius: 100px;
|
||||||
|
height: 20px;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 0.8em;
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
/*****************************************************************
|
/*****************************************************************
|
||||||
WHAT'S NEW PAGE
|
WHAT'S NEW PAGE
|
||||||
*****************************************************************/
|
*****************************************************************/
|
||||||
|
@ -86,11 +86,7 @@ https://github.com/laurent22/joplin/blob/dev/{{{sourceMarkdownFile}}}
|
|||||||
{{> footer}}
|
{{> footer}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script
|
<script src="{{jsBaseUrl}}/bootstrap5.0.2.bundle.min.js" rel="preload" as="script"></script>
|
||||||
src="{{jsBaseUrl}}/bootstrap5.0.2.bundle.min.js"
|
|
||||||
rel="preload"
|
|
||||||
as="script"
|
|
||||||
></script>
|
|
||||||
<script src="{{{assetUrls.js.script}}}"></script>
|
<script src="{{{assetUrls.js.script}}}"></script>
|
||||||
|
|
||||||
{{> analytics}}
|
{{> analytics}}
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{#featureLabelsOn}}
|
{{#featureLabelsOn}}
|
||||||
<p><i class="fas fa-check feature feature-on"></i>{{.}}</p>
|
<p><i class="fas fa-check feature feature-on"></i>{{title}}</p>
|
||||||
{{/featureLabelsOn}}
|
{{/featureLabelsOn}}
|
||||||
|
|
||||||
{{#featureLabelsOff}}
|
{{#featureLabelsOff}}
|
||||||
|
@ -5,6 +5,9 @@
|
|||||||
<h1 translate class="text-center">
|
<h1 translate class="text-center">
|
||||||
Joplin Cloud <span class="frame-bg frame-bg-yellow">plans</span>
|
Joplin Cloud <span class="frame-bg frame-bg-yellow">plans</span>
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
|
<button id="myButton">My button</button>
|
||||||
|
|
||||||
<p translate class="text-center sub-title">
|
<p translate class="text-center sub-title">
|
||||||
<a href="https://joplincloud.com">Joplin Cloud</a> allows you to synchronise your notes across devices. It also lets you publish notes, and collaborate on notebooks with your friends, family or colleagues.
|
<a href="https://joplincloud.com">Joplin Cloud</a> allows you to synchronise your notes across devices. It also lets you publish notes, and collaborate on notebooks with your friends, family or colleagues.
|
||||||
</p>
|
</p>
|
||||||
@ -138,6 +141,14 @@
|
|||||||
} else {
|
} else {
|
||||||
applyPeriod('yearly');
|
applyPeriod('yearly');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$('.feature-description').hide();
|
||||||
|
|
||||||
|
$('.feature-title').click((event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
const featureId = event.currentTarget.getAttribute('data-id');
|
||||||
|
$('.feature-description-' + featureId).show();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</div>
|
</div>
|
||||||
|
@ -19,6 +19,7 @@ export interface MarkdownTableHeader {
|
|||||||
// eslint-disable-next-line @typescript-eslint/ban-types -- Old code before rule was applied
|
// eslint-disable-next-line @typescript-eslint/ban-types -- Old code before rule was applied
|
||||||
filter?: Function;
|
filter?: Function;
|
||||||
disableEscape?: boolean;
|
disableEscape?: boolean;
|
||||||
|
disableHtmlEscape?: boolean;
|
||||||
justify?: MarkdownTableJustify;
|
justify?: MarkdownTableJustify;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,10 +40,12 @@ const markdownUtils = {
|
|||||||
return url;
|
return url;
|
||||||
},
|
},
|
||||||
|
|
||||||
escapeTableCell(text: string) {
|
escapeTableCell(text: string, escapeHtml = true) {
|
||||||
// Disable HTML code
|
// Disable HTML code
|
||||||
text = text.replace(/</g, '<');
|
if (escapeHtml) {
|
||||||
text = text.replace(/>/g, '>');
|
text = text.replace(/</g, '<');
|
||||||
|
text = text.replace(/>/g, '>');
|
||||||
|
}
|
||||||
// Table cells can't contain new lines so replace with <br/>
|
// Table cells can't contain new lines so replace with <br/>
|
||||||
text = text.replace(/\n/g, '<br/>');
|
text = text.replace(/\n/g, '<br/>');
|
||||||
// "|" is a reserved characters that should be escaped
|
// "|" is a reserved characters that should be escaped
|
||||||
@ -173,7 +176,7 @@ const markdownUtils = {
|
|||||||
for (let j = 0; j < headers.length; j++) {
|
for (let j = 0; j < headers.length; j++) {
|
||||||
const h = headers[j];
|
const h = headers[j];
|
||||||
const value = (h.filter ? h.filter(row[h.name]) : row[h.name]) || '';
|
const value = (h.filter ? h.filter(row[h.name]) : row[h.name]) || '';
|
||||||
const valueMd = h.disableEscape ? value : markdownUtils.escapeTableCell(value);
|
const valueMd = h.disableEscape ? value : markdownUtils.escapeTableCell(value, !h.disableHtmlEscape);
|
||||||
rowMd.push(stringPadding(valueMd, minCellWidth, ' ', stringPadding.RIGHT));
|
rowMd.push(stringPadding(valueMd, minCellWidth, ' ', stringPadding.RIGHT));
|
||||||
}
|
}
|
||||||
output.push(`| ${rowMd.join(' | ')} |`);
|
output.push(`| ${rowMd.join(' | ')} |`);
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import * as fs from 'fs-extra';
|
import * as fs from 'fs-extra';
|
||||||
import markdownUtils, { MarkdownTableHeader, MarkdownTableRow } from '../markdownUtils';
|
import markdownUtils, { MarkdownTableHeader, MarkdownTableRow } from '../markdownUtils';
|
||||||
import { _ } from '../locale';
|
import { _ } from '../locale';
|
||||||
|
import { htmlentities } from '@joplin/utils/html';
|
||||||
|
|
||||||
type FeatureId = string;
|
type FeatureId = string;
|
||||||
|
|
||||||
@ -12,6 +13,7 @@ export enum PlanName {
|
|||||||
|
|
||||||
interface PlanFeature {
|
interface PlanFeature {
|
||||||
title: string;
|
title: string;
|
||||||
|
description?: string;
|
||||||
basic: boolean;
|
basic: boolean;
|
||||||
pro: boolean;
|
pro: boolean;
|
||||||
teams: boolean;
|
teams: boolean;
|
||||||
@ -32,7 +34,7 @@ export interface Plan {
|
|||||||
iconName: string;
|
iconName: string;
|
||||||
featuresOn: FeatureId[];
|
featuresOn: FeatureId[];
|
||||||
featuresOff: FeatureId[];
|
featuresOff: FeatureId[];
|
||||||
featureLabelsOn: string[];
|
featureLabelsOn: any[];
|
||||||
featureLabelsOff: string[];
|
featureLabelsOff: string[];
|
||||||
cfaLabel: string;
|
cfaLabel: string;
|
||||||
cfaUrl: string;
|
cfaUrl: string;
|
||||||
@ -112,6 +114,8 @@ export function findPrice(prices: StripePublicConfigPrice[], query: FindPriceQue
|
|||||||
}
|
}
|
||||||
|
|
||||||
const features = (): Record<FeatureId, PlanFeature> => {
|
const features = (): Record<FeatureId, PlanFeature> => {
|
||||||
|
const shareNotebookTitle = _('Share a notebook with others');
|
||||||
|
|
||||||
return {
|
return {
|
||||||
maxItemSize: {
|
maxItemSize: {
|
||||||
title: _('Max note or attachment size'),
|
title: _('Max note or attachment size'),
|
||||||
@ -139,6 +143,7 @@ const features = (): Record<FeatureId, PlanFeature> => {
|
|||||||
},
|
},
|
||||||
publishNote: {
|
publishNote: {
|
||||||
title: _('Publish notes to the internet'),
|
title: _('Publish notes to the internet'),
|
||||||
|
description: 'You can publish a note from the Joplin app. You will get a link that you can share with other users, who can then view the note in their browser.',
|
||||||
basic: true,
|
basic: true,
|
||||||
pro: true,
|
pro: true,
|
||||||
teams: true,
|
teams: true,
|
||||||
@ -157,18 +162,21 @@ const features = (): Record<FeatureId, PlanFeature> => {
|
|||||||
},
|
},
|
||||||
collaborate: {
|
collaborate: {
|
||||||
title: _('Collaborate on a notebook with others'),
|
title: _('Collaborate on a notebook with others'),
|
||||||
|
description: _('This allows another user to share a notebook with you, and you can then both collaborate on it. It does not however allow you to share a notebook with someone else, unless you have the feature "%s".', shareNotebookTitle),
|
||||||
basic: true,
|
basic: true,
|
||||||
pro: true,
|
pro: true,
|
||||||
teams: true,
|
teams: true,
|
||||||
},
|
},
|
||||||
share: {
|
share: {
|
||||||
title: _('Share a notebook with others'),
|
title: shareNotebookTitle,
|
||||||
|
description: 'You can share a notebook with other Joplin Cloud users, who can then view the notes and edit them.',
|
||||||
basic: false,
|
basic: false,
|
||||||
pro: true,
|
pro: true,
|
||||||
teams: true,
|
teams: true,
|
||||||
},
|
},
|
||||||
emailToNote: {
|
emailToNote: {
|
||||||
title: _('Email to Note'),
|
title: _('Email to Note'),
|
||||||
|
description: 'You can save your emails in Joplin Cloud by forwarding your emails to a special email address. The subject of the email will become the note title, and the email body will become the note content.',
|
||||||
basic: false,
|
basic: false,
|
||||||
pro: true,
|
pro: true,
|
||||||
teams: true,
|
teams: true,
|
||||||
@ -185,8 +193,15 @@ const features = (): Record<FeatureId, PlanFeature> => {
|
|||||||
pro: false,
|
pro: false,
|
||||||
teams: true,
|
teams: true,
|
||||||
},
|
},
|
||||||
sharingAccessControl: {
|
// sharingAccessControl: {
|
||||||
title: _('Sharing access control'),
|
// title: _('Sharing access control'),
|
||||||
|
// basic: false,
|
||||||
|
// pro: false,
|
||||||
|
// teams: true,
|
||||||
|
// },
|
||||||
|
sharePermissions: {
|
||||||
|
title: _('Share permissions'),
|
||||||
|
description: 'With this feature you can define whether a notebook you share with someone can be edited or is read-only. It can be useful for example to share documentation that you do not want to be modified.',
|
||||||
basic: false,
|
basic: false,
|
||||||
pro: false,
|
pro: false,
|
||||||
teams: true,
|
teams: true,
|
||||||
@ -235,7 +250,7 @@ export const getFeatureById = (featureId: FeatureId): PlanFeature => {
|
|||||||
export const getFeaturesByPlan = (planName: PlanName, featureOn: boolean): PlanFeature[] => {
|
export const getFeaturesByPlan = (planName: PlanName, featureOn: boolean): PlanFeature[] => {
|
||||||
const output: PlanFeature[] = [];
|
const output: PlanFeature[] = [];
|
||||||
|
|
||||||
for (const [, v] of Object.entries(features)) {
|
for (const [, v] of Object.entries(features())) {
|
||||||
if (v[planName] === featureOn) {
|
if (v[planName] === featureOn) {
|
||||||
output.push(v);
|
output.push(v);
|
||||||
}
|
}
|
||||||
@ -261,6 +276,7 @@ export const createFeatureTableMd = () => {
|
|||||||
{
|
{
|
||||||
name: 'featureLabel',
|
name: 'featureLabel',
|
||||||
label: 'Feature',
|
label: 'Feature',
|
||||||
|
disableHtmlEscape: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'basic',
|
name: 'basic',
|
||||||
@ -285,9 +301,20 @@ export const createFeatureTableMd = () => {
|
|||||||
return '✔️';
|
return '✔️';
|
||||||
};
|
};
|
||||||
|
|
||||||
for (const [, feature] of Object.entries(features())) {
|
const makeFeatureLabel = (featureId: string, feature: PlanFeature) => {
|
||||||
|
const output: string[] = [
|
||||||
|
`${htmlentities(feature.title)}`,
|
||||||
|
];
|
||||||
|
if (feature.description) {
|
||||||
|
output.push(`<a data-id=${htmlentities(featureId)} class="feature-title" name="feature-${htmlentities(featureId)}" href="#feature-${htmlentities(featureId)}">i</a>`);
|
||||||
|
output.push(`<div class="feature-description feature-description-${htmlentities(featureId)}">${htmlentities(feature.description)}</div>`);
|
||||||
|
}
|
||||||
|
return output.join('');
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const [id, feature] of Object.entries(features())) {
|
||||||
const row: MarkdownTableRow = {
|
const row: MarkdownTableRow = {
|
||||||
featureLabel: feature.title,
|
featureLabel: makeFeatureLabel(id, feature),
|
||||||
basic: getCellInfo(PlanName.Basic, feature),
|
basic: getCellInfo(PlanName.Basic, feature),
|
||||||
pro: getCellInfo(PlanName.Pro, feature),
|
pro: getCellInfo(PlanName.Pro, feature),
|
||||||
teams: getCellInfo(PlanName.Teams, feature),
|
teams: getCellInfo(PlanName.Teams, feature),
|
||||||
@ -316,7 +343,7 @@ export function getPlans(stripeConfig: StripePublicConfig): Record<PlanName, Pla
|
|||||||
iconName: 'basic-icon',
|
iconName: 'basic-icon',
|
||||||
featuresOn: getFeatureIdsByPlan(PlanName.Basic, true),
|
featuresOn: getFeatureIdsByPlan(PlanName.Basic, true),
|
||||||
featuresOff: getFeatureIdsByPlan(PlanName.Basic, false),
|
featuresOff: getFeatureIdsByPlan(PlanName.Basic, false),
|
||||||
featureLabelsOn: getFeatureLabelsByPlan(PlanName.Basic, true),
|
featureLabelsOn: getFeaturesByPlan(PlanName.Basic, true),
|
||||||
featureLabelsOff: getFeatureLabelsByPlan(PlanName.Basic, false),
|
featureLabelsOff: getFeatureLabelsByPlan(PlanName.Basic, false),
|
||||||
cfaLabel: _('Try it now'),
|
cfaLabel: _('Try it now'),
|
||||||
cfaUrl: '',
|
cfaUrl: '',
|
||||||
@ -338,7 +365,7 @@ export function getPlans(stripeConfig: StripePublicConfig): Record<PlanName, Pla
|
|||||||
iconName: 'pro-icon',
|
iconName: 'pro-icon',
|
||||||
featuresOn: getFeatureIdsByPlan(PlanName.Pro, true),
|
featuresOn: getFeatureIdsByPlan(PlanName.Pro, true),
|
||||||
featuresOff: getFeatureIdsByPlan(PlanName.Pro, false),
|
featuresOff: getFeatureIdsByPlan(PlanName.Pro, false),
|
||||||
featureLabelsOn: getFeatureLabelsByPlan(PlanName.Pro, true),
|
featureLabelsOn: getFeaturesByPlan(PlanName.Pro, true),
|
||||||
featureLabelsOff: getFeatureLabelsByPlan(PlanName.Pro, false),
|
featureLabelsOff: getFeatureLabelsByPlan(PlanName.Pro, false),
|
||||||
cfaLabel: _('Try it now'),
|
cfaLabel: _('Try it now'),
|
||||||
cfaUrl: '',
|
cfaUrl: '',
|
||||||
@ -360,7 +387,7 @@ export function getPlans(stripeConfig: StripePublicConfig): Record<PlanName, Pla
|
|||||||
iconName: 'business-icon',
|
iconName: 'business-icon',
|
||||||
featuresOn: getFeatureIdsByPlan(PlanName.Teams, true),
|
featuresOn: getFeatureIdsByPlan(PlanName.Teams, true),
|
||||||
featuresOff: getFeatureIdsByPlan(PlanName.Teams, false),
|
featuresOff: getFeatureIdsByPlan(PlanName.Teams, false),
|
||||||
featureLabelsOn: getFeatureLabelsByPlan(PlanName.Teams, true),
|
featureLabelsOn: getFeaturesByPlan(PlanName.Teams, true),
|
||||||
featureLabelsOff: getFeatureLabelsByPlan(PlanName.Teams, false),
|
featureLabelsOff: getFeatureLabelsByPlan(PlanName.Teams, false),
|
||||||
cfaLabel: _('Try it now'),
|
cfaLabel: _('Try it now'),
|
||||||
cfaUrl: '',
|
cfaUrl: '',
|
||||||
|
@ -46,6 +46,7 @@
|
|||||||
"@rmp135/sql-ts": "1.18.0",
|
"@rmp135/sql-ts": "1.18.0",
|
||||||
"@types/fs-extra": "11.0.1",
|
"@types/fs-extra": "11.0.1",
|
||||||
"@types/jest": "29.5.4",
|
"@types/jest": "29.5.4",
|
||||||
|
"@types/markdown-it": "13.0.1",
|
||||||
"@types/mustache": "4.2.2",
|
"@types/mustache": "4.2.2",
|
||||||
"@types/node": "18.17.14",
|
"@types/node": "18.17.14",
|
||||||
"@types/node-fetch": "2.6.4",
|
"@types/node-fetch": "2.6.4",
|
||||||
|
@ -15,6 +15,7 @@ import { setLocale } from '@joplin/lib/locale';
|
|||||||
import applyTranslations from './utils/applyTranslations';
|
import applyTranslations from './utils/applyTranslations';
|
||||||
import { loadSponsors } from '../utils/loadSponsors';
|
import { loadSponsors } from '../utils/loadSponsors';
|
||||||
import convertLinksToLocale from './utils/convertLinksToLocale';
|
import convertLinksToLocale from './utils/convertLinksToLocale';
|
||||||
|
import { copyFile } from 'fs/promises';
|
||||||
|
|
||||||
interface BuildConfig {
|
interface BuildConfig {
|
||||||
env: Env;
|
env: Env;
|
||||||
@ -89,6 +90,38 @@ const jsBasePath = `${websiteAssetDir}/js`;
|
|||||||
const jsBaseUrl = `${baseUrl}/js`;
|
const jsBaseUrl = `${baseUrl}/js`;
|
||||||
|
|
||||||
async function getAssetUrls(): Promise<AssetUrls> {
|
async function getAssetUrls(): Promise<AssetUrls> {
|
||||||
|
const scriptsToImport: any[] = [
|
||||||
|
// {
|
||||||
|
// id: 'tippy',
|
||||||
|
// sourcePath: rootDir + '/packages/tools/node_modules/tippy.js/dist/tippy-bundle.umd.min.js',
|
||||||
|
// md5: '',
|
||||||
|
// filename: '',
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// id: 'popper',
|
||||||
|
// sourcePath: rootDir + '/packages/tools/node_modules/@popperjs/core/dist/umd/popper.min.js',
|
||||||
|
// md5: '',
|
||||||
|
// filename: '',
|
||||||
|
// },
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const s of scriptsToImport) {
|
||||||
|
const filename = basename(s.sourcePath);
|
||||||
|
const sourceMd5 = await md5File(s.sourcePath);
|
||||||
|
const targetPath = `${websiteAssetDir}/js/${filename}`;
|
||||||
|
const targetMd5 = await md5File(targetPath);
|
||||||
|
s.md5 = sourceMd5;
|
||||||
|
s.filename = filename;
|
||||||
|
|
||||||
|
// We check the MD5, otherwise it makes nodemon goes into an infinite building loop
|
||||||
|
if (sourceMd5 !== targetMd5) await copyFile(s.sourcePath, targetPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
const importedJs: Record<string, string> = {};
|
||||||
|
for (const s of scriptsToImport) {
|
||||||
|
importedJs[s.id] = `${jsBaseUrl}/${s.filename}?h=${await md5File(`${websiteAssetDir}/js/${s.filename}`)}`;
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
css: {
|
css: {
|
||||||
fontawesome: `${cssBaseUrl}/fontawesome-all.min.css?h=${await md5File(`${cssBasePath}/fontawesome-all.min.css`)}`,
|
fontawesome: `${cssBaseUrl}/fontawesome-all.min.css?h=${await md5File(`${cssBasePath}/fontawesome-all.min.css`)}`,
|
||||||
@ -96,6 +129,7 @@ async function getAssetUrls(): Promise<AssetUrls> {
|
|||||||
},
|
},
|
||||||
js: {
|
js: {
|
||||||
script: `${jsBaseUrl}/script.js?h=${await md5File(`${jsBasePath}/script.js`)}`,
|
script: `${jsBaseUrl}/script.js?h=${await md5File(`${jsBasePath}/script.js`)}`,
|
||||||
|
...importedJs,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ import { filename } from '@joplin/lib/path-utils';
|
|||||||
import * as fs from 'fs-extra';
|
import * as fs from 'fs-extra';
|
||||||
import { Partials, TemplateParams } from './types';
|
import { Partials, TemplateParams } from './types';
|
||||||
import { headerAnchor } from '@joplin/renderer';
|
import { headerAnchor } from '@joplin/renderer';
|
||||||
const MarkdownIt = require('markdown-it');
|
import * as MarkdownIt from 'markdown-it';
|
||||||
|
|
||||||
export async function loadMustachePartials(partialDir: string) {
|
export async function loadMustachePartials(partialDir: string) {
|
||||||
const output: Partials = {};
|
const output: Partials = {};
|
||||||
|
11
yarn.lock
11
yarn.lock
@ -5178,6 +5178,7 @@ __metadata:
|
|||||||
"@rmp135/sql-ts": 1.18.0
|
"@rmp135/sql-ts": 1.18.0
|
||||||
"@types/fs-extra": 11.0.1
|
"@types/fs-extra": 11.0.1
|
||||||
"@types/jest": 29.5.4
|
"@types/jest": 29.5.4
|
||||||
|
"@types/markdown-it": 13.0.1
|
||||||
"@types/mustache": 4.2.2
|
"@types/mustache": 4.2.2
|
||||||
"@types/node": 18.17.14
|
"@types/node": 18.17.14
|
||||||
"@types/node-fetch": 2.6.4
|
"@types/node-fetch": 2.6.4
|
||||||
@ -8094,6 +8095,16 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@types/markdown-it@npm:13.0.1":
|
||||||
|
version: 13.0.1
|
||||||
|
resolution: "@types/markdown-it@npm:13.0.1"
|
||||||
|
dependencies:
|
||||||
|
"@types/linkify-it": "*"
|
||||||
|
"@types/mdurl": "*"
|
||||||
|
checksum: 184d383ac21903a9e6be1639cde2b0cc082d0366b423fd8a69d0f37d9d1d36338f66611226ba4ef1da6148f370a62e08f688e8147ead43d429d6ff213c38c062
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@types/mdast@npm:^3.0.0":
|
"@types/mdast@npm:^3.0.0":
|
||||||
version: 3.0.12
|
version: 3.0.12
|
||||||
resolution: "@types/mdast@npm:3.0.12"
|
resolution: "@types/mdast@npm:3.0.12"
|
||||||
|
Reference in New Issue
Block a user