@kood/claude-code 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/dist/index.d.ts +2 -0
  2. package/dist/index.js +297 -0
  3. package/package.json +47 -0
  4. package/templates/hono/CLAUDE.md +376 -0
  5. package/templates/hono/docs/deployment/cloudflare.md +328 -0
  6. package/templates/hono/docs/deployment/index.md +291 -0
  7. package/templates/hono/docs/git/index.md +180 -0
  8. package/templates/hono/docs/library/hono/error-handling.md +400 -0
  9. package/templates/hono/docs/library/hono/index.md +241 -0
  10. package/templates/hono/docs/library/hono/middleware.md +334 -0
  11. package/templates/hono/docs/library/hono/rpc.md +454 -0
  12. package/templates/hono/docs/library/hono/validation.md +328 -0
  13. package/templates/hono/docs/library/prisma/index.md +427 -0
  14. package/templates/hono/docs/library/zod/index.md +413 -0
  15. package/templates/hono/docs/mcp/context7.md +106 -0
  16. package/templates/hono/docs/mcp/index.md +94 -0
  17. package/templates/hono/docs/mcp/sequential-thinking.md +101 -0
  18. package/templates/hono/docs/mcp/sgrep.md +105 -0
  19. package/templates/hono/docs/skills/gemini-review/SKILL.md +220 -0
  20. package/templates/hono/docs/skills/gemini-review/references/checklists.md +136 -0
  21. package/templates/hono/docs/skills/gemini-review/references/prompt-templates.md +303 -0
  22. package/templates/tanstack-start/CLAUDE.md +279 -0
  23. package/templates/tanstack-start/docs/architecture/architecture.md +547 -0
  24. package/templates/tanstack-start/docs/deployment/cloudflare.md +346 -0
  25. package/templates/tanstack-start/docs/deployment/index.md +102 -0
  26. package/templates/tanstack-start/docs/deployment/nitro.md +211 -0
  27. package/templates/tanstack-start/docs/deployment/railway.md +364 -0
  28. package/templates/tanstack-start/docs/deployment/vercel.md +287 -0
  29. package/templates/tanstack-start/docs/design/accessibility.md +433 -0
  30. package/templates/tanstack-start/docs/design/color.md +235 -0
  31. package/templates/tanstack-start/docs/design/components.md +409 -0
  32. package/templates/tanstack-start/docs/design/index.md +107 -0
  33. package/templates/tanstack-start/docs/design/safe-area.md +317 -0
  34. package/templates/tanstack-start/docs/design/spacing.md +341 -0
  35. package/templates/tanstack-start/docs/design/tailwind-setup.md +470 -0
  36. package/templates/tanstack-start/docs/design/typography.md +324 -0
  37. package/templates/tanstack-start/docs/git/index.md +203 -0
  38. package/templates/tanstack-start/docs/guides/best-practices.md +753 -0
  39. package/templates/tanstack-start/docs/guides/getting-started.md +304 -0
  40. package/templates/tanstack-start/docs/guides/husky-lint-staged.md +303 -0
  41. package/templates/tanstack-start/docs/guides/prettier.md +189 -0
  42. package/templates/tanstack-start/docs/guides/project-templates.md +710 -0
  43. package/templates/tanstack-start/docs/library/better-auth/2fa.md +136 -0
  44. package/templates/tanstack-start/docs/library/better-auth/advanced.md +138 -0
  45. package/templates/tanstack-start/docs/library/better-auth/index.md +83 -0
  46. package/templates/tanstack-start/docs/library/better-auth/plugins.md +111 -0
  47. package/templates/tanstack-start/docs/library/better-auth/session.md +127 -0
  48. package/templates/tanstack-start/docs/library/better-auth/setup.md +123 -0
  49. package/templates/tanstack-start/docs/library/prisma/crud.md +218 -0
  50. package/templates/tanstack-start/docs/library/prisma/index.md +165 -0
  51. package/templates/tanstack-start/docs/library/prisma/relations.md +191 -0
  52. package/templates/tanstack-start/docs/library/prisma/schema.md +177 -0
  53. package/templates/tanstack-start/docs/library/prisma/setup.md +156 -0
  54. package/templates/tanstack-start/docs/library/prisma/transactions.md +140 -0
  55. package/templates/tanstack-start/docs/library/tanstack-query/index.md +146 -0
  56. package/templates/tanstack-start/docs/library/tanstack-query/invalidation.md +146 -0
  57. package/templates/tanstack-start/docs/library/tanstack-query/optimistic-updates.md +196 -0
  58. package/templates/tanstack-start/docs/library/tanstack-query/setup.md +110 -0
  59. package/templates/tanstack-start/docs/library/tanstack-query/use-mutation.md +170 -0
  60. package/templates/tanstack-start/docs/library/tanstack-query/use-query.md +173 -0
  61. package/templates/tanstack-start/docs/library/tanstack-start/auth-patterns.md +171 -0
  62. package/templates/tanstack-start/docs/library/tanstack-start/index.md +114 -0
  63. package/templates/tanstack-start/docs/library/tanstack-start/middleware.md +142 -0
  64. package/templates/tanstack-start/docs/library/tanstack-start/routing.md +163 -0
  65. package/templates/tanstack-start/docs/library/tanstack-start/server-functions.md +128 -0
  66. package/templates/tanstack-start/docs/library/tanstack-start/setup.md +85 -0
  67. package/templates/tanstack-start/docs/library/zod/basic-types.md +186 -0
  68. package/templates/tanstack-start/docs/library/zod/complex-types.md +204 -0
  69. package/templates/tanstack-start/docs/library/zod/index.md +186 -0
  70. package/templates/tanstack-start/docs/library/zod/transforms.md +174 -0
  71. package/templates/tanstack-start/docs/library/zod/validation.md +208 -0
  72. package/templates/tanstack-start/docs/mcp/context7.md +204 -0
  73. package/templates/tanstack-start/docs/mcp/index.md +116 -0
  74. package/templates/tanstack-start/docs/mcp/sequential-thinking.md +180 -0
  75. package/templates/tanstack-start/docs/mcp/sgrep.md +174 -0
  76. package/templates/tanstack-start/docs/skills/gemini-review/SKILL.md +220 -0
  77. package/templates/tanstack-start/docs/skills/gemini-review/references/checklists.md +150 -0
  78. package/templates/tanstack-start/docs/skills/gemini-review/references/prompt-templates.md +293 -0
@@ -0,0 +1,163 @@
1
+ # TanStack Start - Routing
2
+
3
+ > **상위 문서**: [TanStack Start](./index.md)
4
+
5
+ TanStack Start는 파일 기반 라우팅을 지원합니다.
6
+
7
+ ## 기본 라우트
8
+
9
+ ```tsx
10
+ // routes/about.tsx
11
+ import { createFileRoute } from '@tanstack/react-router'
12
+
13
+ export const Route = createFileRoute('/about')({
14
+ component: AboutPage,
15
+ })
16
+
17
+ function AboutPage() {
18
+ return <h1>About</h1>
19
+ }
20
+ ```
21
+
22
+ ## Loader를 사용한 데이터 로딩
23
+
24
+ ```tsx
25
+ // routes/index.tsx
26
+ import { createFileRoute } from '@tanstack/react-router'
27
+
28
+ export const Route = createFileRoute('/')({
29
+ component: Page,
30
+ loader: async () => {
31
+ const res = await fetch('https://api.example.com/posts')
32
+ return res.json()
33
+ },
34
+ })
35
+
36
+ function Page() {
37
+ const posts = Route.useLoaderData()
38
+ return (
39
+ <ul>
40
+ {posts.map((post) => (
41
+ <li key={post.id}>{post.title}</li>
42
+ ))}
43
+ </ul>
44
+ )
45
+ }
46
+ ```
47
+
48
+ ## 동적 라우트
49
+
50
+ ```tsx
51
+ // routes/users/$id.tsx
52
+ import { createFileRoute } from '@tanstack/react-router'
53
+
54
+ export const Route = createFileRoute('/users/$id')({
55
+ loader: async ({ params }) => {
56
+ const user = await getUserById(params.id)
57
+ return { user }
58
+ },
59
+ component: UserDetailPage,
60
+ })
61
+
62
+ function UserDetailPage() {
63
+ const { user } = Route.useLoaderData()
64
+ return <h1>{user.name}</h1>
65
+ }
66
+ ```
67
+
68
+ ## SSR 설정
69
+
70
+ ```tsx
71
+ // routes/posts/$postId.tsx
72
+ export const Route = createFileRoute('/posts/$postId')({
73
+ ssr: true, // SSR 활성화
74
+ beforeLoad: () => {
75
+ console.log('서버에서 초기 요청 시 실행')
76
+ },
77
+ loader: () => {
78
+ console.log('서버에서 초기 요청 시 실행')
79
+ },
80
+ component: () => <div>서버에서 렌더링됨</div>,
81
+ })
82
+ ```
83
+
84
+ ### SSR 옵션
85
+
86
+ ```typescript
87
+ // ssr: true - 전체 SSR (기본값)
88
+ // ssr: false - 클라이언트 사이드만
89
+ // ssr: 'data-only' - 데이터만 서버에서 로드, 렌더링은 클라이언트
90
+ ```
91
+
92
+ ## Server Routes (API)
93
+
94
+ ### 기본 API 라우트
95
+
96
+ ```typescript
97
+ // routes/api/hello.ts
98
+ import { createFileRoute } from '@tanstack/react-router'
99
+
100
+ export const Route = createFileRoute('/api/hello')({
101
+ server: {
102
+ handlers: {
103
+ GET: async ({ request }) => {
104
+ return new Response('Hello, World!')
105
+ },
106
+ POST: async ({ request }) => {
107
+ const body = await request.json()
108
+ return new Response(`Hello, ${body.name}!`)
109
+ },
110
+ },
111
+ },
112
+ })
113
+ ```
114
+
115
+ ### JSON 응답
116
+
117
+ ```typescript
118
+ import { createFileRoute } from '@tanstack/react-router'
119
+ import { json } from '@tanstack/react-start'
120
+
121
+ export const Route = createFileRoute('/api/users')({
122
+ server: {
123
+ handlers: {
124
+ GET: async ({ request }) => {
125
+ const users = await getUsers()
126
+ return json({ users })
127
+ },
128
+ },
129
+ },
130
+ })
131
+ ```
132
+
133
+ ## 라우트 파일 구조
134
+
135
+ ```
136
+ routes/
137
+ ├── __root.tsx → Root layout
138
+ ├── index.tsx → /
139
+ ├── about.tsx → /about
140
+ ├── users/
141
+ │ ├── index.tsx → /users
142
+ │ └── $id.tsx → /users/:id
143
+ ├── posts/
144
+ │ ├── index.tsx → /posts
145
+ │ ├── $postId.tsx → /posts/:postId
146
+ │ └── new.tsx → /posts/new
147
+ └── api/
148
+ ├── hello.ts → /api/hello
149
+ └── users.ts → /api/users
150
+ ```
151
+
152
+ ## Catch-All 라우트
153
+
154
+ ```tsx
155
+ // routes/$.tsx - 모든 매칭되지 않는 경로 처리
156
+ export const Route = createFileRoute('/$')({
157
+ component: NotFoundPage,
158
+ })
159
+
160
+ function NotFoundPage() {
161
+ return <h1>404 - Page Not Found</h1>
162
+ }
163
+ ```
@@ -0,0 +1,128 @@
1
+ # TanStack Start - Server Functions
2
+
3
+ > **상위 문서**: [TanStack Start](./index.md)
4
+
5
+ Server Functions는 서버에서만 실행되는 타입 안전한 함수입니다.
6
+
7
+ ## 기본 Server Function
8
+
9
+ ```typescript
10
+ import { createServerFn } from '@tanstack/react-start'
11
+
12
+ // GET 요청 (데이터 조회)
13
+ export const getUsers = createServerFn({ method: 'GET' })
14
+ .handler(async () => {
15
+ return prisma.user.findMany()
16
+ })
17
+
18
+ // POST 요청 (데이터 생성/수정)
19
+ export const createUser = createServerFn({ method: 'POST' })
20
+ .handler(async () => {
21
+ return { success: true }
22
+ })
23
+ ```
24
+
25
+ ## Input Validation
26
+
27
+ ### 기본 Validator
28
+
29
+ ```typescript
30
+ import { createServerFn } from '@tanstack/react-start'
31
+
32
+ export const createUser = createServerFn({ method: 'POST' })
33
+ .inputValidator((data: { email: string; name: string }) => data)
34
+ .handler(async ({ data }) => {
35
+ // data는 타입 안전함
36
+ return prisma.user.create({ data })
37
+ })
38
+ ```
39
+
40
+ ### Zod Validation 사용
41
+
42
+ ```typescript
43
+ import { createServerFn } from '@tanstack/react-start'
44
+ import { zodValidator } from '@tanstack/react-start/validators'
45
+ import { z } from 'zod'
46
+
47
+ const createUserSchema = z.object({
48
+ email: z.string().email(),
49
+ name: z.string().min(1).max(100),
50
+ bio: z.string().max(500).optional(),
51
+ })
52
+
53
+ export const createUser = createServerFn({ method: 'POST' })
54
+ .inputValidator(zodValidator(createUserSchema))
55
+ .handler(async ({ data }) => {
56
+ return prisma.user.create({ data })
57
+ })
58
+ ```
59
+
60
+ ## FormData 처리
61
+
62
+ ```typescript
63
+ import { createServerFn } from '@tanstack/react-start'
64
+
65
+ export const submitForm = createServerFn({ method: 'POST' })
66
+ .inputValidator((formData: FormData) => {
67
+ const name = formData.get('name') as string
68
+ const email = formData.get('email') as string
69
+ return { name, email }
70
+ })
71
+ .handler(async ({ data }) => {
72
+ return prisma.user.create({ data })
73
+ })
74
+ ```
75
+
76
+ ## 컴포넌트에서 호출
77
+
78
+ ### useServerFn 사용
79
+
80
+ ```tsx
81
+ import { useServerFn } from '@tanstack/react-start'
82
+ import { useQuery } from '@tanstack/react-query'
83
+ import { getServerPosts } from '~/lib/server-functions'
84
+
85
+ function PostList() {
86
+ const getPosts = useServerFn(getServerPosts)
87
+
88
+ const { data, isLoading, error } = useQuery({
89
+ queryKey: ['posts'],
90
+ queryFn: () => getPosts(),
91
+ })
92
+
93
+ if (isLoading) return <div>Loading...</div>
94
+ if (error) return <div>Error: {error.message}</div>
95
+
96
+ return (
97
+ <ul>
98
+ {data?.map((post) => (
99
+ <li key={post.id}>{post.title}</li>
100
+ ))}
101
+ </ul>
102
+ )
103
+ }
104
+ ```
105
+
106
+ ## 보안 패턴
107
+
108
+ ### 서버 전용 데이터 보호
109
+
110
+ ```tsx
111
+ // ❌ 잘못된 방법 - 클라이언트에 노출됨
112
+ export const Route = createFileRoute('/users')({
113
+ loader: () => {
114
+ const secret = process.env.SECRET // 클라이언트에 노출!
115
+ return fetch(`/api/users?key=${secret}`)
116
+ },
117
+ })
118
+
119
+ // ✅ 올바른 방법 - 서버 함수 사용
120
+ const getUsersSecurely = createServerFn().handler(() => {
121
+ const secret = process.env.SECRET // 서버에서만 접근
122
+ return fetch(`/api/users?key=${secret}`)
123
+ })
124
+
125
+ export const Route = createFileRoute('/users')({
126
+ loader: () => getUsersSecurely(),
127
+ })
128
+ ```
@@ -0,0 +1,85 @@
1
+ # TanStack Start - 설치 및 설정
2
+
3
+ > **상위 문서**: [TanStack Start](./index.md)
4
+
5
+ ## 패키지 설치
6
+
7
+ ```bash
8
+ yarn add @tanstack/react-start @tanstack/react-router vinxi
9
+ yarn add -D vite @vitejs/plugin-react vite-tsconfig-paths
10
+ ```
11
+
12
+ ## Vite 설정
13
+
14
+ ```typescript
15
+ // vite.config.ts
16
+ import { defineConfig } from 'vite'
17
+ import tsConfigPaths from 'vite-tsconfig-paths'
18
+ import { tanstackStart } from '@tanstack/react-start/plugin/vite'
19
+ import viteReact from '@vitejs/plugin-react'
20
+
21
+ export default defineConfig({
22
+ server: {
23
+ port: 3000,
24
+ },
25
+ plugins: [
26
+ tsConfigPaths(),
27
+ tanstackStart(),
28
+ viteReact(),
29
+ ],
30
+ })
31
+ ```
32
+
33
+ ## TypeScript 설정
34
+
35
+ ```json
36
+ // tsconfig.json
37
+ {
38
+ "compilerOptions": {
39
+ "target": "ES2022",
40
+ "module": "ESNext",
41
+ "moduleResolution": "bundler",
42
+ "strict": true,
43
+ "esModuleInterop": true,
44
+ "skipLibCheck": true,
45
+ "jsx": "react-jsx",
46
+ "baseUrl": ".",
47
+ "paths": {
48
+ "~/*": ["./src/*"]
49
+ }
50
+ },
51
+ "include": ["src/**/*"]
52
+ }
53
+ ```
54
+
55
+ ## 프로젝트 구조
56
+
57
+ ```
58
+ project/
59
+ ├── src/
60
+ │ ├── routes/
61
+ │ │ ├── __root.tsx
62
+ │ │ ├── index.tsx
63
+ │ │ └── about.tsx
64
+ │ ├── lib/
65
+ │ │ └── server-functions.ts
66
+ │ └── start.ts
67
+ ├── vite.config.ts
68
+ ├── tsconfig.json
69
+ └── package.json
70
+ ```
71
+
72
+ ## 환경 변수 검증
73
+
74
+ ```typescript
75
+ // lib/env.ts
76
+ import { z } from 'zod'
77
+
78
+ const envSchema = z.object({
79
+ NODE_ENV: z.enum(['development', 'production', 'test']),
80
+ DATABASE_URL: z.string().url(),
81
+ API_SECRET: z.string().min(32),
82
+ })
83
+
84
+ export const env = envSchema.parse(process.env)
85
+ ```
@@ -0,0 +1,186 @@
1
+ # Zod - 기본 타입
2
+
3
+ > **상위 문서**: [Zod](./index.md)
4
+
5
+ ## 문자열
6
+
7
+ ```typescript
8
+ z.string()
9
+ z.string().min(1) // 최소 길이
10
+ z.string().max(100) // 최대 길이
11
+ z.string().length(5) // 정확한 길이
12
+ z.string().regex(/^\d+$/) // 정규식
13
+ z.string().trim() // 공백 제거
14
+ z.string().toLowerCase() // 소문자 변환
15
+ z.string().toUpperCase() // 대문자 변환
16
+ ```
17
+
18
+ ### v4 새로운 최상위 문자열 포맷 API
19
+
20
+ ```typescript
21
+ // 더 나은 tree-shaking을 위해 최상위 API 사용 권장
22
+ z.email() // 이메일 형식
23
+ z.url() // URL 형식
24
+ z.uuid() // UUID 형식
25
+ z.base64() // Base64 형식
26
+ z.base64url() // Base64 URL 형식
27
+ z.nanoid() // NanoID 형식
28
+ z.cuid() // CUID 형식
29
+ z.cuid2() // CUID2 형식
30
+ z.ulid() // ULID 형식
31
+ z.emoji() // 이모지 (단일 문자)
32
+ z.ipv4() // IPv4 주소
33
+ z.ipv6() // IPv6 주소
34
+ z.cidrv4() // IPv4 범위
35
+ z.cidrv6() // IPv6 범위
36
+
37
+ // ISO 날짜/시간 형식
38
+ z.iso.date() // ISO 날짜 (2024-01-15)
39
+ z.iso.time() // ISO 시간 (14:30:00)
40
+ z.iso.datetime() // ISO 날짜시간
41
+ z.iso.duration() // ISO 기간 (P1D, PT1H)
42
+ ```
43
+
44
+ ### 템플릿 리터럴 타입 (v4 신규)
45
+
46
+ ```typescript
47
+ const hello = z.templateLiteral(["hello, ", z.string()])
48
+ // `hello, ${string}`
49
+
50
+ const cssUnits = z.enum(["px", "em", "rem", "%"])
51
+ const css = z.templateLiteral([z.number(), cssUnits])
52
+ // `${number}px` | `${number}em` | `${number}rem` | `${number}%`
53
+
54
+ const email = z.templateLiteral([
55
+ z.string().min(1),
56
+ "@",
57
+ z.string().max(64),
58
+ ])
59
+ // `${string}@${string}` (min/max refinements도 적용됨!)
60
+ ```
61
+
62
+ ## 숫자
63
+
64
+ ```typescript
65
+ z.number()
66
+ z.number().min(0) // 최솟값
67
+ z.number().max(100) // 최댓값
68
+ z.number().int() // 정수만
69
+ z.number().positive() // 양수만
70
+ z.number().negative() // 음수만
71
+ z.number().nonnegative() // 0 이상
72
+ z.number().nonpositive() // 0 이하
73
+ z.number().finite() // 유한 숫자
74
+ z.number().safe() // 안전한 정수 범위
75
+ ```
76
+
77
+ ## 불리언
78
+
79
+ ```typescript
80
+ z.boolean()
81
+ ```
82
+
83
+ ### 문자열 불리언 (v4 신규)
84
+
85
+ 환경변수 스타일 불리언 변환:
86
+
87
+ ```typescript
88
+ const strbool = z.stringbool()
89
+
90
+ strbool.parse("true") // => true
91
+ strbool.parse("1") // => true
92
+ strbool.parse("yes") // => true
93
+ strbool.parse("on") // => true
94
+ strbool.parse("enabled") // => true
95
+
96
+ strbool.parse("false") // => false
97
+ strbool.parse("0") // => false
98
+ strbool.parse("no") // => false
99
+ strbool.parse("off") // => false
100
+ strbool.parse("disabled") // => false
101
+
102
+ // 커스텀 truthy/falsy 값
103
+ z.stringbool({
104
+ truthy: ["yes", "true"],
105
+ falsy: ["no", "false"]
106
+ })
107
+ ```
108
+
109
+ ## 날짜
110
+
111
+ ```typescript
112
+ z.date()
113
+ z.date().min(new Date('2020-01-01'))
114
+ z.date().max(new Date('2030-12-31'))
115
+ ```
116
+
117
+ ## BigInt
118
+
119
+ ```typescript
120
+ z.bigint()
121
+ z.bigint().positive()
122
+ z.bigint().negative()
123
+ ```
124
+
125
+ ## 리터럴
126
+
127
+ ```typescript
128
+ z.literal('hello') // 정확히 'hello'만
129
+ z.literal(42) // 정확히 42만
130
+ z.literal(true) // 정확히 true만
131
+ ```
132
+
133
+ ## Null, Undefined, Void
134
+
135
+ ```typescript
136
+ z.null() // null만 허용
137
+ z.undefined() // undefined만 허용
138
+ z.void() // undefined 허용 (반환 타입용)
139
+ ```
140
+
141
+ ## Any, Unknown, Never
142
+
143
+ ```typescript
144
+ z.any() // 모든 타입 허용
145
+ z.unknown() // unknown 타입
146
+ z.never() // 값 없음 (유니온에서 사용)
147
+ ```
148
+
149
+ > **v4 변경**: `z.any()`와 `z.unknown()`은 더 이상 객체에서 선택적 키로 추론되지 않습니다.
150
+ > ```typescript
151
+ > const mySchema = z.object({ a: z.any(), b: z.unknown() })
152
+ > // v3: { a?: any; b?: unknown }
153
+ > // v4: { a: any; b: unknown }
154
+ > ```
155
+
156
+ ## Optional & Nullable
157
+
158
+ ```typescript
159
+ z.string().optional() // string | undefined
160
+ z.string().nullable() // string | null
161
+ z.string().nullish() // string | null | undefined
162
+ ```
163
+
164
+ ## Default 값
165
+
166
+ ```typescript
167
+ const Schema = z.object({
168
+ name: z.string().default('Anonymous'),
169
+ role: z.enum(['admin', 'user']).default('user'),
170
+ })
171
+
172
+ Schema.parse({}) // { name: 'Anonymous', role: 'user' }
173
+ ```
174
+
175
+ ## 타입 추론
176
+
177
+ ```typescript
178
+ const stringSchema = z.string()
179
+ type StringType = z.infer<typeof stringSchema> // string
180
+
181
+ const numberSchema = z.number().optional()
182
+ type NumberType = z.infer<typeof numberSchema> // number | undefined
183
+
184
+ const dateSchema = z.date().nullable()
185
+ type DateType = z.infer<typeof dateSchema> // Date | null
186
+ ```