← back to MagicMicky__chronicle

Function bodies 868 total

All specs Real LLM only Function bodies
createUIStore function · typescript · L65-L104 (40 LOC)
app/src/lib/stores/ui.ts
function createUIStore() {
  const initialState = loadState();
  const { subscribe, set, update } = writable<PaneState>(initialState);

  function updateAndPersist(updater: (state: PaneState) => PaneState) {
    update((state) => {
      const next = updater(state);
      persistState(next);
      return next;
    });
  }

  return {
    subscribe,
    setExplorerWidth: (width: number) =>
      updateAndPersist((state) => ({ ...state, explorerWidth: Math.max(150, Math.min(500, width)) })),
    setAIOutputWidth: (width: number) =>
      updateAndPersist((state) => ({ ...state, aiOutputWidth: Math.max(250, Math.min(600, width)) })),
    setTerminalHeight: (height: number) =>
      updateAndPersist((state) => ({ ...state, terminalHeight: Math.max(150, Math.min(500, height)) })),
    toggleCollapse: (pane: 'explorer' | 'aiOutput' | 'terminal') =>
      updateAndPersist((state) => ({
        ...state,
        collapsed: { ...state.collapsed, [pane]: !state.collapsed[pane] },
      })),
    
createUIStore function · typescript · L65-L104 (40 LOC)
app/src/lib/stores/ui.ts
function createUIStore() {
  const initialState = loadState();
  const { subscribe, set, update } = writable<PaneState>(initialState);

  function updateAndPersist(updater: (state: PaneState) => PaneState) {
    update((state) => {
      const next = updater(state);
      persistState(next);
      return next;
    });
  }

  return {
    subscribe,
    setExplorerWidth: (width: number) =>
      updateAndPersist((state) => ({ ...state, explorerWidth: Math.max(150, Math.min(500, width)) })),
    setAIOutputWidth: (width: number) =>
      updateAndPersist((state) => ({ ...state, aiOutputWidth: Math.max(250, Math.min(600, width)) })),
    setTerminalHeight: (height: number) =>
      updateAndPersist((state) => ({ ...state, terminalHeight: Math.max(150, Math.min(500, height)) })),
    toggleCollapse: (pane: 'explorer' | 'aiOutput' | 'terminal') =>
      updateAndPersist((state) => ({
        ...state,
        collapsed: { ...state.collapsed, [pane]: !state.collapsed[pane] },
      })),
    
createUIStore function · typescript · L65-L104 (40 LOC)
app/src/lib/stores/ui.ts
function createUIStore() {
  const initialState = loadState();
  const { subscribe, set, update } = writable<PaneState>(initialState);

  function updateAndPersist(updater: (state: PaneState) => PaneState) {
    update((state) => {
      const next = updater(state);
      persistState(next);
      return next;
    });
  }

  return {
    subscribe,
    setExplorerWidth: (width: number) =>
      updateAndPersist((state) => ({ ...state, explorerWidth: Math.max(150, Math.min(500, width)) })),
    setAIOutputWidth: (width: number) =>
      updateAndPersist((state) => ({ ...state, aiOutputWidth: Math.max(250, Math.min(600, width)) })),
    setTerminalHeight: (height: number) =>
      updateAndPersist((state) => ({ ...state, terminalHeight: Math.max(150, Math.min(500, height)) })),
    toggleCollapse: (pane: 'explorer' | 'aiOutput' | 'terminal') =>
      updateAndPersist((state) => ({
        ...state,
        collapsed: { ...state.collapsed, [pane]: !state.collapsed[pane] },
      })),
    
createUIStore function · typescript · L65-L104 (40 LOC)
app/src/lib/stores/ui.ts
function createUIStore() {
  const initialState = loadState();
  const { subscribe, set, update } = writable<PaneState>(initialState);

  function updateAndPersist(updater: (state: PaneState) => PaneState) {
    update((state) => {
      const next = updater(state);
      persistState(next);
      return next;
    });
  }

  return {
    subscribe,
    setExplorerWidth: (width: number) =>
      updateAndPersist((state) => ({ ...state, explorerWidth: Math.max(150, Math.min(500, width)) })),
    setAIOutputWidth: (width: number) =>
      updateAndPersist((state) => ({ ...state, aiOutputWidth: Math.max(250, Math.min(600, width)) })),
    setTerminalHeight: (height: number) =>
      updateAndPersist((state) => ({ ...state, terminalHeight: Math.max(150, Math.min(500, height)) })),
    toggleCollapse: (pane: 'explorer' | 'aiOutput' | 'terminal') =>
      updateAndPersist((state) => ({
        ...state,
        collapsed: { ...state.collapsed, [pane]: !state.collapsed[pane] },
      })),
    
updateAndPersist function · typescript · L69-L75 (7 LOC)
app/src/lib/stores/ui.ts
  function updateAndPersist(updater: (state: PaneState) => PaneState) {
    update((state) => {
      const next = updater(state);
      persistState(next);
      return next;
    });
  }
updateAndPersist function · typescript · L69-L75 (7 LOC)
app/src/lib/stores/ui.ts
  function updateAndPersist(updater: (state: PaneState) => PaneState) {
    update((state) => {
      const next = updater(state);
      persistState(next);
      return next;
    });
  }
updateAndPersist function · typescript · L69-L75 (7 LOC)
app/src/lib/stores/ui.ts
  function updateAndPersist(updater: (state: PaneState) => PaneState) {
    update((state) => {
      const next = updater(state);
      persistState(next);
      return next;
    });
  }
Methodology: Repobility · https://repobility.com/research/state-of-ai-code-2026/
updateAndPersist function · typescript · L69-L75 (7 LOC)
app/src/lib/stores/ui.ts
  function updateAndPersist(updater: (state: PaneState) => PaneState) {
    update((state) => {
      const next = updater(state);
      persistState(next);
      return next;
    });
  }
createWorkspaceStore function · typescript · L43-L103 (61 LOC)
app/src/lib/stores/workspace.ts
function createWorkspaceStore() {
  const { subscribe, set, update } = writable<WorkspaceState>(defaultState);

  return {
    subscribe,

    openWorkspace: async (path: string) => {
      update((s) => ({ ...s, isLoading: true, error: null }));
      try {
        const invoke = await getInvoke();
        const info = await invoke<WorkspaceInfo>('open_workspace', { path });
        const files = await invoke<FileNode[]>('list_workspace_files', { workspacePath: path });
        update((s) => ({
          ...s,
          currentWorkspace: info,
          files,
          isLoading: false,
        }));
        // Sync workspace path to backend for MCP server
        await syncAppState({ workspacePath: path });
        return info;
      } catch (e) {
        const error = e instanceof Error ? e.message : String(e);
        toast.error('Failed to open workspace');
        update((s) => ({ ...s, isLoading: false, error }));
        throw e;
      }
    },

    refreshFiles: async () => {
createWorkspaceStore function · typescript · L43-L103 (61 LOC)
app/src/lib/stores/workspace.ts
function createWorkspaceStore() {
  const { subscribe, set, update } = writable<WorkspaceState>(defaultState);

  return {
    subscribe,

    openWorkspace: async (path: string) => {
      update((s) => ({ ...s, isLoading: true, error: null }));
      try {
        const invoke = await getInvoke();
        const info = await invoke<WorkspaceInfo>('open_workspace', { path });
        const files = await invoke<FileNode[]>('list_workspace_files', { workspacePath: path });
        update((s) => ({
          ...s,
          currentWorkspace: info,
          files,
          isLoading: false,
        }));
        // Sync workspace path to backend for MCP server
        await syncAppState({ workspacePath: path });
        return info;
      } catch (e) {
        const error = e instanceof Error ? e.message : String(e);
        toast.error('Failed to open workspace');
        update((s) => ({ ...s, isLoading: false, error }));
        throw e;
      }
    },

    refreshFiles: async () => {
createWorkspaceStore function · typescript · L43-L103 (61 LOC)
app/src/lib/stores/workspace.ts
function createWorkspaceStore() {
  const { subscribe, set, update } = writable<WorkspaceState>(defaultState);

  return {
    subscribe,

    openWorkspace: async (path: string) => {
      update((s) => ({ ...s, isLoading: true, error: null }));
      try {
        const invoke = await getInvoke();
        const info = await invoke<WorkspaceInfo>('open_workspace', { path });
        const files = await invoke<FileNode[]>('list_workspace_files', { workspacePath: path });
        update((s) => ({
          ...s,
          currentWorkspace: info,
          files,
          isLoading: false,
        }));
        // Sync workspace path to backend for MCP server
        await syncAppState({ workspacePath: path });
        return info;
      } catch (e) {
        const error = e instanceof Error ? e.message : String(e);
        toast.error('Failed to open workspace');
        update((s) => ({ ...s, isLoading: false, error }));
        throw e;
      }
    },

    refreshFiles: async () => {
createWorkspaceStore function · typescript · L43-L103 (61 LOC)
app/src/lib/stores/workspace.ts
function createWorkspaceStore() {
  const { subscribe, set, update } = writable<WorkspaceState>(defaultState);

  return {
    subscribe,

    openWorkspace: async (path: string) => {
      update((s) => ({ ...s, isLoading: true, error: null }));
      try {
        const invoke = await getInvoke();
        const info = await invoke<WorkspaceInfo>('open_workspace', { path });
        const files = await invoke<FileNode[]>('list_workspace_files', { workspacePath: path });
        update((s) => ({
          ...s,
          currentWorkspace: info,
          files,
          isLoading: false,
        }));
        // Sync workspace path to backend for MCP server
        await syncAppState({ workspacePath: path });
        return info;
      } catch (e) {
        const error = e instanceof Error ? e.message : String(e);
        toast.error('Failed to open workspace');
        update((s) => ({ ...s, isLoading: false, error }));
        throw e;
      }
    },

    refreshFiles: async () => {
spawnPty function · typescript · L35-L44 (10 LOC)
app/src/lib/terminal/pty.ts
export async function spawnPty(options: PtyOptions): Promise<IPty> {
  const { command, args } = await getDefaultShell();

  return spawn(command, args, {
    name: 'xterm-256color', // Sets TERM environment variable for proper line editing
    cols: options.cols,
    rows: options.rows,
    cwd: options.cwd,
  });
}
spawnPty function · typescript · L35-L44 (10 LOC)
app/src/lib/terminal/pty.ts
export async function spawnPty(options: PtyOptions): Promise<IPty> {
  const { command, args } = await getDefaultShell();

  return spawn(command, args, {
    name: 'xterm-256color', // Sets TERM environment variable for proper line editing
    cols: options.cols,
    rows: options.rows,
    cwd: options.cwd,
  });
}
spawnPty function · typescript · L35-L44 (10 LOC)
app/src/lib/terminal/pty.ts
export async function spawnPty(options: PtyOptions): Promise<IPty> {
  const { command, args } = await getDefaultShell();

  return spawn(command, args, {
    name: 'xterm-256color', // Sets TERM environment variable for proper line editing
    cols: options.cols,
    rows: options.rows,
    cwd: options.cwd,
  });
}
All rows scored by the Repobility analyzer (https://repobility.com)
spawnPty function · typescript · L35-L44 (10 LOC)
app/src/lib/terminal/pty.ts
export async function spawnPty(options: PtyOptions): Promise<IPty> {
  const { command, args } = await getDefaultShell();

  return spawn(command, args, {
    name: 'xterm-256color', // Sets TERM environment variable for proper line editing
    cols: options.cols,
    rows: options.rows,
    cwd: options.cwd,
  });
}
pickFolder function · typescript · L7-L19 (13 LOC)
app/src/lib/utils/dialog.ts
export async function pickFolder(): Promise<string | null> {
  try {
    const selected = await open({
      directory: true,
      multiple: false,
      title: 'Select Workspace Folder',
    });
    return selected as string | null;
  } catch (e) {
    console.error('Folder picker failed:', e);
    return null;
  }
}
pickFolder function · typescript · L7-L19 (13 LOC)
app/src/lib/utils/dialog.ts
export async function pickFolder(): Promise<string | null> {
  try {
    const selected = await open({
      directory: true,
      multiple: false,
      title: 'Select Workspace Folder',
    });
    return selected as string | null;
  } catch (e) {
    console.error('Folder picker failed:', e);
    return null;
  }
}
pickFolder function · typescript · L7-L19 (13 LOC)
app/src/lib/utils/dialog.ts
export async function pickFolder(): Promise<string | null> {
  try {
    const selected = await open({
      directory: true,
      multiple: false,
      title: 'Select Workspace Folder',
    });
    return selected as string | null;
  } catch (e) {
    console.error('Folder picker failed:', e);
    return null;
  }
}
pickFolder function · typescript · L7-L19 (13 LOC)
app/src/lib/utils/dialog.ts
export async function pickFolder(): Promise<string | null> {
  try {
    const selected = await open({
      directory: true,
      multiple: false,
      title: 'Select Workspace Folder',
    });
    return selected as string | null;
  } catch (e) {
    console.error('Folder picker failed:', e);
    return null;
  }
}
hashString function · typescript · L26-L32 (7 LOC)
app/src/lib/utils/tagColors.ts
function hashString(str: string): number {
  let hash = 0;
  for (let i = 0; i < str.length; i++) {
    hash = ((hash << 5) - hash + str.charCodeAt(i)) | 0;
  }
  return Math.abs(hash);
}
hashString function · typescript · L26-L32 (7 LOC)
app/src/lib/utils/tagColors.ts
function hashString(str: string): number {
  let hash = 0;
  for (let i = 0; i < str.length; i++) {
    hash = ((hash << 5) - hash + str.charCodeAt(i)) | 0;
  }
  return Math.abs(hash);
}
hashString function · typescript · L26-L32 (7 LOC)
app/src/lib/utils/tagColors.ts
function hashString(str: string): number {
  let hash = 0;
  for (let i = 0; i < str.length; i++) {
    hash = ((hash << 5) - hash + str.charCodeAt(i)) | 0;
  }
  return Math.abs(hash);
}
Provenance: Repobility (https://repobility.com) — every score reproducible from /scan/
hashString function · typescript · L26-L32 (7 LOC)
app/src/lib/utils/tagColors.ts
function hashString(str: string): number {
  let hash = 0;
  for (let i = 0; i < str.length; i++) {
    hash = ((hash << 5) - hash + str.charCodeAt(i)) | 0;
  }
  return Math.abs(hash);
}
getTagColor function · typescript · L45-L53 (9 LOC)
app/src/lib/utils/tagColors.ts
export function getTagColor(tag: string, categories?: Record<string, TagCategory>): string {
  if (categories) {
    const { category } = parseTag(tag);
    if (category && categories[category]?.color) {
      return categories[category].color;
    }
  }
  return TAG_COLORS[hashString(tag) % TAG_COLORS.length];
}
getTagColor function · typescript · L45-L53 (9 LOC)
app/src/lib/utils/tagColors.ts
export function getTagColor(tag: string, categories?: Record<string, TagCategory>): string {
  if (categories) {
    const { category } = parseTag(tag);
    if (category && categories[category]?.color) {
      return categories[category].color;
    }
  }
  return TAG_COLORS[hashString(tag) % TAG_COLORS.length];
}
getTagColor function · typescript · L45-L53 (9 LOC)
app/src/lib/utils/tagColors.ts
export function getTagColor(tag: string, categories?: Record<string, TagCategory>): string {
  if (categories) {
    const { category } = parseTag(tag);
    if (category && categories[category]?.color) {
      return categories[category].color;
    }
  }
  return TAG_COLORS[hashString(tag) % TAG_COLORS.length];
}
getTagColor function · typescript · L45-L53 (9 LOC)
app/src/lib/utils/tagColors.ts
export function getTagColor(tag: string, categories?: Record<string, TagCategory>): string {
  if (categories) {
    const { category } = parseTag(tag);
    if (category && categories[category]?.color) {
      return categories[category].color;
    }
  }
  return TAG_COLORS[hashString(tag) % TAG_COLORS.length];
}
getTagBgColor function · typescript · L56-L62 (7 LOC)
app/src/lib/utils/tagColors.ts
export function getTagBgColor(tag: string, categories?: Record<string, TagCategory>): string {
  const color = getTagColor(tag, categories);
  const r = parseInt(color.slice(1, 3), 16);
  const g = parseInt(color.slice(3, 5), 16);
  const b = parseInt(color.slice(5, 7), 16);
  return `rgba(${r}, ${g}, ${b}, 0.13)`;
}
getTagBgColor function · typescript · L56-L62 (7 LOC)
app/src/lib/utils/tagColors.ts
export function getTagBgColor(tag: string, categories?: Record<string, TagCategory>): string {
  const color = getTagColor(tag, categories);
  const r = parseInt(color.slice(1, 3), 16);
  const g = parseInt(color.slice(3, 5), 16);
  const b = parseInt(color.slice(5, 7), 16);
  return `rgba(${r}, ${g}, ${b}, 0.13)`;
}
getTagBgColor function · typescript · L56-L62 (7 LOC)
app/src/lib/utils/tagColors.ts
export function getTagBgColor(tag: string, categories?: Record<string, TagCategory>): string {
  const color = getTagColor(tag, categories);
  const r = parseInt(color.slice(1, 3), 16);
  const g = parseInt(color.slice(3, 5), 16);
  const b = parseInt(color.slice(5, 7), 16);
  return `rgba(${r}, ${g}, ${b}, 0.13)`;
}
Generated by Repobility's multi-pass static-analysis pipeline (https://repobility.com)
getTagBgColor function · typescript · L56-L62 (7 LOC)
app/src/lib/utils/tagColors.ts
export function getTagBgColor(tag: string, categories?: Record<string, TagCategory>): string {
  const color = getTagColor(tag, categories);
  const r = parseInt(color.slice(1, 3), 16);
  const g = parseInt(color.slice(3, 5), 16);
  const b = parseInt(color.slice(5, 7), 16);
  return `rgba(${r}, ${g}, ${b}, 0.13)`;
}
isTauri function · typescript · L4-L6 (3 LOC)
app/src/lib/utils/tauri.ts
export function isTauri(): boolean {
  return typeof window !== 'undefined' && '__TAURI_INTERNALS__' in window;
}
isTauri function · typescript · L4-L6 (3 LOC)
app/src/lib/utils/tauri.ts
export function isTauri(): boolean {
  return typeof window !== 'undefined' && '__TAURI_INTERNALS__' in window;
}
isTauri function · typescript · L4-L6 (3 LOC)
app/src/lib/utils/tauri.ts
export function isTauri(): boolean {
  return typeof window !== 'undefined' && '__TAURI_INTERNALS__' in window;
}
isTauri function · typescript · L4-L6 (3 LOC)
app/src/lib/utils/tauri.ts
export function isTauri(): boolean {
  return typeof window !== 'undefined' && '__TAURI_INTERNALS__' in window;
}
getInvoke function · typescript · L12-L21 (10 LOC)
app/src/lib/utils/tauri.ts
export async function getInvoke() {
  if (!isTauri()) {
    // Return a stub that always rejects so callers' catch blocks fire gracefully
    return (async () => {
      throw new Error('Not running in Tauri');
    }) as unknown as typeof import('@tauri-apps/api/core').invoke;
  }
  const { invoke } = await import('@tauri-apps/api/core');
  return invoke;
}
getInvoke function · typescript · L12-L21 (10 LOC)
app/src/lib/utils/tauri.ts
export async function getInvoke() {
  if (!isTauri()) {
    // Return a stub that always rejects so callers' catch blocks fire gracefully
    return (async () => {
      throw new Error('Not running in Tauri');
    }) as unknown as typeof import('@tauri-apps/api/core').invoke;
  }
  const { invoke } = await import('@tauri-apps/api/core');
  return invoke;
}
getInvoke function · typescript · L12-L21 (10 LOC)
app/src/lib/utils/tauri.ts
export async function getInvoke() {
  if (!isTauri()) {
    // Return a stub that always rejects so callers' catch blocks fire gracefully
    return (async () => {
      throw new Error('Not running in Tauri');
    }) as unknown as typeof import('@tauri-apps/api/core').invoke;
  }
  const { invoke } = await import('@tauri-apps/api/core');
  return invoke;
}
Methodology: Repobility · https://repobility.com/research/state-of-ai-code-2026/
getInvoke function · typescript · L12-L21 (10 LOC)
app/src/lib/utils/tauri.ts
export async function getInvoke() {
  if (!isTauri()) {
    // Return a stub that always rejects so callers' catch blocks fire gracefully
    return (async () => {
      throw new Error('Not running in Tauri');
    }) as unknown as typeof import('@tauri-apps/api/core').invoke;
  }
  const { invoke } = await import('@tauri-apps/api/core');
  return invoke;
}
main function · rust · L1-L3 (3 LOC)
app/src-tauri/build.rs
fn main() {
    tauri_build::build()
}
main function · rust · L1-L3 (3 LOC)
app/src-tauri/build.rs
fn main() {
    tauri_build::build()
}
main function · rust · L1-L3 (3 LOC)
app/src-tauri/build.rs
fn main() {
    tauri_build::build()
}
main function · rust · L1-L3 (3 LOC)
app/src-tauri/build.rs
fn main() {
    tauri_build::build()
}
count_notes function · rust · L7-L23 (17 LOC)
app/src-tauri/src/commands/appstate.rs
fn count_notes(workspace_path: &str) -> usize {
    let path = Path::new(workspace_path);
    if !path.is_dir() {
        return 0;
    }
    walkdir::WalkDir::new(path)
        .into_iter()
        .filter_map(|e| e.ok())
        .filter(|e| {
            e.path().extension().is_some_and(|ext| ext == "md")
                && !e
                    .path()
                    .components()
                    .any(|c| c.as_os_str().to_string_lossy().starts_with('.'))
        })
        .count()
}
count_notes function · rust · L7-L23 (17 LOC)
app/src-tauri/src/commands/appstate.rs
fn count_notes(workspace_path: &str) -> usize {
    let path = Path::new(workspace_path);
    if !path.is_dir() {
        return 0;
    }
    walkdir::WalkDir::new(path)
        .into_iter()
        .filter_map(|e| e.ok())
        .filter(|e| {
            e.path().extension().is_some_and(|ext| ext == "md")
                && !e
                    .path()
                    .components()
                    .any(|c| c.as_os_str().to_string_lossy().starts_with('.'))
        })
        .count()
}
count_notes function · rust · L7-L23 (17 LOC)
app/src-tauri/src/commands/appstate.rs
fn count_notes(workspace_path: &str) -> usize {
    let path = Path::new(workspace_path);
    if !path.is_dir() {
        return 0;
    }
    walkdir::WalkDir::new(path)
        .into_iter()
        .filter_map(|e| e.ok())
        .filter(|e| {
            e.path().extension().is_some_and(|ext| ext == "md")
                && !e
                    .path()
                    .components()
                    .any(|c| c.as_os_str().to_string_lossy().starts_with('.'))
        })
        .count()
}
All rows scored by the Repobility analyzer (https://repobility.com)
count_notes function · rust · L7-L23 (17 LOC)
app/src-tauri/src/commands/appstate.rs
fn count_notes(workspace_path: &str) -> usize {
    let path = Path::new(workspace_path);
    if !path.is_dir() {
        return 0;
    }
    walkdir::WalkDir::new(path)
        .into_iter()
        .filter_map(|e| e.ok())
        .filter(|e| {
            e.path().extension().is_some_and(|ext| ext == "md")
                && !e
                    .path()
                    .components()
                    .any(|c| c.as_os_str().to_string_lossy().starts_with('.'))
        })
        .count()
}
write_state_json function · rust · L26-L42 (17 LOC)
app/src-tauri/src/commands/appstate.rs
fn write_state_json(workspace_path: &str, file_path: Option<&str>) {
    let state_path = Path::new(workspace_path).join(".chronicle/state.json");
    if !state_path.parent().is_some_and(|p| p.exists()) {
        return;
    }

    let state = json!({
        "workspacePath": workspace_path,
        "currentFile": file_path,
        "lastEdited": chrono::Utc::now().to_rfc3339(),
        "noteCount": count_notes(workspace_path),
    });

    if let Err(e) = std::fs::write(&state_path, serde_json::to_string_pretty(&state).unwrap_or_default()) {
        tracing::warn!("Failed to write state.json: {}", e);
    }
}
write_state_json function · rust · L26-L42 (17 LOC)
app/src-tauri/src/commands/appstate.rs
fn write_state_json(workspace_path: &str, file_path: Option<&str>) {
    let state_path = Path::new(workspace_path).join(".chronicle/state.json");
    if !state_path.parent().is_some_and(|p| p.exists()) {
        return;
    }

    let state = json!({
        "workspacePath": workspace_path,
        "currentFile": file_path,
        "lastEdited": chrono::Utc::now().to_rfc3339(),
        "noteCount": count_notes(workspace_path),
    });

    if let Err(e) = std::fs::write(&state_path, serde_json::to_string_pretty(&state).unwrap_or_default()) {
        tracing::warn!("Failed to write state.json: {}", e);
    }
}
‹ prevpage 5 / 18next ›