[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6EMH2RTT8024MQPV55066FW":3,"skill-same:01M6EMH2RTT8024MQPV55066FW":77},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":23,"publishedAt":42,"linkOnly":43,"markdownContent":44,"markdownBody":45,"frontMatter":46,"refName":48,"commitSha":49,"skillDirectory":50,"forksCount":51,"repositoryHtmlUrl":52,"repositoryHomepageUrl":53,"ownerHtmlUrl":54,"ownerBlogUrl":6,"ownerDescription":55,"updatedAt":56,"install":57,"resources":70},"01M6EMH2RTT8024MQPV55066FW","code-patterns-practices",null,"React Native coding patterns, best practices, and common solutions for mobile development. Use when implementing features or refactoring code.","ComeOnOliver\u002Fskillshub","ComeOnOliver","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F43215937?v=4","01M6E5JNFECJAAVFE0W7SMWWD2","Haoran Shu","01M6E5JNNDQS7AJZDYFQ8TPZCK",66,"MIT","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fbabakbar\u002Fcode-patterns-practices\u002FSKILL.md",[18],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000030","开发工程师","PROFESSION","适用职业",[24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41],"code patterns practices","code","patterns","edit","native","coding patterns","mobile","mobile development","use","react native","react","write","read","common","coding","refactoring","best practices","development","2026-11-10 10:12:30",false,"---\nname: code-patterns-practices\ndescription: React Native coding patterns, best practices, and common solutions for mobile development. Use when implementing features or refactoring code.\nallowed-tools: Read, Write, Edit\n---\n\n# Code Patterns & Practices\n\nCommon patterns and best practices for React Native development.\n\n## When to Use\n\n- Implementing new features\n- Refactoring existing code\n- Choosing architecture patterns\n- Solving common problems\n- Improving code quality\n\n## Component Patterns\n\n### Custom Hooks\n\n```typescript\n\u002F\u002F Extract reusable logic\nfunction useToggle(initial = false) {\n  const [value, setValue] = useState(initial);\n  const toggle = useCallback(() => setValue(v => !v), []);\n  return [value, toggle] as const;\n}\n\n\u002F\u002F Usage\nconst [isOpen, toggleOpen] = useToggle();\n```\n\n### Compound Components\n\n```typescript\n\u002F\u002F Create flexible component APIs\ninterface TabsProps {\n  children: React.ReactNode;\n  defaultValue?: string;\n}\n\nfunction Tabs({ children, defaultValue }: TabsProps) {\n  const [active, setActive] = useState(defaultValue);\n\n  return (\n    \u003CTabsContext.Provider value={{ active, setActive }}>\n      {children}\n    \u003C\u002FTabsContext.Provider>\n  );\n}\n\nTabs.List = TabsList;\nTabs.Trigger = TabsTrigger;\nTabs.Content = TabsContent;\n\n\u002F\u002F Usage\n\u003CTabs defaultValue=\"home\">\n  \u003CTabs.List>\n    \u003CTabs.Trigger value=\"home\">Home\u003C\u002FTabs.Trigger>\n    \u003CTabs.Trigger value=\"profile\">Profile\u003C\u002FTabs.Trigger>\n  \u003C\u002FTabs.List>\n  \u003CTabs.Content value=\"home\">Home Content\u003C\u002FTabs.Content>\n  \u003CTabs.Content value=\"profile\">Profile Content\u003C\u002FTabs.Content>\n\u003C\u002FTabs>\n```\n\n### Render Props\n\n```typescript\n\u002F\u002F Share component logic\ninterface DataLoaderProps\u003CT> {\n  loadData: () => Promise\u003CT>;\n  children: (data: T | null, loading: boolean, error: Error | null) => React.ReactNode;\n}\n\nfunction DataLoader\u003CT>({ loadData, children }: DataLoaderProps\u003CT>) {\n  const [data, setData] = useState\u003CT | null>(null);\n  const [loading, setLoading] = useState(true);\n  const [error, setError] = useState\u003CError | null>(null);\n\n  useEffect(() => {\n    loadData()\n      .then(setData)\n      .catch(setError)\n      .finally(() => setLoading(false));\n  }, [loadData]);\n\n  return \u003C>{children(data, loading, error)}\u003C\u002F>;\n}\n\n\u002F\u002F Usage\n\u003CDataLoader loadData={fetchUser}>\n  {(user, loading, error) => {\n    if (loading) return \u003CLoading \u002F>;\n    if (error) return \u003CError error={error} \u002F>;\n    return \u003CUserProfile user={user} \u002F>;\n  }}\n\u003C\u002FDataLoader>\n```\n\n## State Management Patterns\n\n### Local State\n\n```typescript\n\u002F\u002F Keep it simple when possible\nfunction Counter() {\n  const [count, setCount] = useState(0);\n  return \u003CButton onPress={() => setCount(c => c + 1)}>Count: {count}\u003C\u002FButton>;\n}\n```\n\n### Shared State (Context)\n\n```typescript\n\u002F\u002F For cross-cutting concerns\nconst ThemeContext = createContext\u003CThemeContextValue>(null!);\n\nexport function ThemeProvider({ children }: { children: React.ReactNode }) {\n  const [theme, setTheme] = useState\u003C'light' | 'dark'>('light');\n\n  return (\n    \u003CThemeContext.Provider value={{ theme, setTheme }}>\n      {children}\n    \u003C\u002FThemeContext.Provider>\n  );\n}\n\nexport function useTheme() {\n  const context = useContext(ThemeContext);\n  if (!context) throw new Error('useTheme must be used within ThemeProvider');\n  return context;\n}\n```\n\n### Global State (Zustand)\n\n```typescript\n\u002F\u002F For app-wide state\nimport { create } from 'zustand';\n\ninterface UserState {\n  user: User | null;\n  setUser: (user: User) => void;\n  logout: () => void;\n}\n\nexport const useUserStore = create\u003CUserState>((set) => ({\n  user: null,\n  setUser: (user) => set({ user }),\n  logout: () => set({ user: null }),\n}));\n```\n\n## Data Fetching Patterns\n\n### With Async\u002FAwait\n\n```typescript\nfunction useUserData(userId: string) {\n  const [data, setData] = useState(null);\n  const [loading, setLoading] = useState(true);\n  const [error, setError] = useState(null);\n\n  useEffect(() => {\n    let cancelled = false;\n\n    async function fetchData() {\n      try {\n        const response = await fetch(`\u002Fapi\u002Fusers\u002F${userId}`);\n        const result = await response.json();\n        if (!cancelled) {\n          setData(result);\n        }\n      } catch (err) {\n        if (!cancelled) {\n          setError(err);\n        }\n      } finally {\n        if (!cancelled) {\n          setLoading(false);\n        }\n      }\n    }\n\n    fetchData();\n\n    return () => {\n      cancelled = true;\n    };\n  }, [userId]);\n\n  return { data, loading, error };\n}\n```\n\n## Performance Patterns\n\n### Memoization\n\n```typescript\n\u002F\u002F Expensive calculations\nconst expensiveValue = useMemo(() => {\n  return calculateExpensiveValue(data);\n}, [data]);\n\n\u002F\u002F Stable callbacks\nconst handlePress = useCallback(() => {\n  doSomething(value);\n}, [value]);\n\n\u002F\u002F Component memoization\nconst MemoizedChild = memo(function Child({ data }: ChildProps) {\n  return \u003CView>{data}\u003C\u002FView>;\n});\n```\n\n### Lazy Loading\n\n```typescript\nimport { lazy, Suspense } from 'react';\n\nconst HeavyComponent = lazy(() => import('.\u002FHeavyComponent'));\n\nfunction App() {\n  return (\n    \u003CSuspense fallback={\u003CLoading \u002F>}>\n      \u003CHeavyComponent \u002F>\n    \u003C\u002FSuspense>\n  );\n}\n```\n\n## Error Handling Patterns\n\n### Error Boundaries\n\n```typescript\nclass ErrorBoundary extends React.Component\u003C\n  { children: React.ReactNode },\n  { hasError: boolean; error: Error | null }\n> {\n  state = { hasError: false, error: null };\n\n  static getDerivedStateFromError(error: Error) {\n    return { hasError: true, error };\n  }\n\n  componentDidCatch(error: Error, info: React.ErrorInfo) {\n    console.error('Error caught:', error, info);\n  }\n\n  render() {\n    if (this.state.hasError) {\n      return \u003CErrorScreen error={this.state.error} \u002F>;\n    }\n    return this.props.children;\n  }\n}\n```\n\n### Try-Catch Pattern\n\n```typescript\nasync function saveData() {\n  try {\n    await api.save(data);\n    showSuccess('Saved!');\n  } catch (error) {\n    if (error instanceof NetworkError) {\n      showError('Network error. Check connection.');\n    } else if (error instanceof ValidationError) {\n      showError(error.message);\n    } else {\n      showError('Something went wrong.');\n    }\n  }\n}\n```\n\n## Mobile-Specific Patterns\n\n### Safe Area Handling\n\n```typescript\nimport { useSafeAreaInsets } from 'react-native-safe-area-context';\n\nfunction Screen() {\n  const insets = useSafeAreaInsets();\n\n  return (\n    \u003CView style={{ paddingTop: insets.top, paddingBottom: insets.bottom }}>\n      {\u002F* Content *\u002F}\n    \u003C\u002FView>\n  );\n}\n```\n\n### Keyboard Avoiding\n\n```typescript\nimport { KeyboardAvoidingView, Platform } from 'react-native';\n\n\u003CKeyboardAvoidingView\n  behavior={Platform.OS === 'ios' ? 'padding' : 'height'}\n  style={{ flex: 1 }}\n>\n  {\u002F* Input form *\u002F}\n\u003C\u002FKeyboardAvoidingView>\n```\n\n## Best Practices\n\n1. **Keep Components Small**: Single responsibility, easy to test\n2. **Extract Custom Hooks**: Reuse logic across components\n3. **Use TypeScript**: Catch errors early\n4. **Handle Loading & Error States**: Better user experience\n5. **Clean Up Side Effects**: Prevent memory leaks\n6. **Optimize Wisely**: Profile before optimizing\n7. **Test Behavior**: Focus on user interactions\n\n## Anti-Patterns to Avoid\n\n- ❌ Massive components (>300 lines)\n- ❌ Prop drilling (use context\u002Fstore instead)\n- ❌ Missing cleanup in useEffect\n- ❌ Inline function definitions in render\n- ❌ Mutating state directly\n- ❌ Over-optimization without measuring\n\n## Resources\n\n- [React Patterns](https:\u002F\u002Freactpatterns.com\u002F)\n- [React Native Best Practices](https:\u002F\u002Freactnative.dev\u002Fdocs\u002Fperformance)\n","# Code Patterns & Practices\n\nCommon patterns and best practices for React Native development.\n\n## When to Use\n\n- Implementing new features\n- Refactoring existing code\n- Choosing architecture patterns\n- Solving common problems\n- Improving code quality\n\n## Component Patterns\n\n### Custom Hooks\n\n```typescript\n\u002F\u002F Extract reusable logic\nfunction useToggle(initial = false) {\n  const [value, setValue] = useState(initial);\n  const toggle = useCallback(() => setValue(v => !v), []);\n  return [value, toggle] as const;\n}\n\n\u002F\u002F Usage\nconst [isOpen, toggleOpen] = useToggle();\n```\n\n### Compound Components\n\n```typescript\n\u002F\u002F Create flexible component APIs\ninterface TabsProps {\n  children: React.ReactNode;\n  defaultValue?: string;\n}\n\nfunction Tabs({ children, defaultValue }: TabsProps) {\n  const [active, setActive] = useState(defaultValue);\n\n  return (\n    \u003CTabsContext.Provider value={{ active, setActive }}>\n      {children}\n    \u003C\u002FTabsContext.Provider>\n  );\n}\n\nTabs.List = TabsList;\nTabs.Trigger = TabsTrigger;\nTabs.Content = TabsContent;\n\n\u002F\u002F Usage\n\u003CTabs defaultValue=\"home\">\n  \u003CTabs.List>\n    \u003CTabs.Trigger value=\"home\">Home\u003C\u002FTabs.Trigger>\n    \u003CTabs.Trigger value=\"profile\">Profile\u003C\u002FTabs.Trigger>\n  \u003C\u002FTabs.List>\n  \u003CTabs.Content value=\"home\">Home Content\u003C\u002FTabs.Content>\n  \u003CTabs.Content value=\"profile\">Profile Content\u003C\u002FTabs.Content>\n\u003C\u002FTabs>\n```\n\n### Render Props\n\n```typescript\n\u002F\u002F Share component logic\ninterface DataLoaderProps\u003CT> {\n  loadData: () => Promise\u003CT>;\n  children: (data: T | null, loading: boolean, error: Error | null) => React.ReactNode;\n}\n\nfunction DataLoader\u003CT>({ loadData, children }: DataLoaderProps\u003CT>) {\n  const [data, setData] = useState\u003CT | null>(null);\n  const [loading, setLoading] = useState(true);\n  const [error, setError] = useState\u003CError | null>(null);\n\n  useEffect(() => {\n    loadData()\n      .then(setData)\n      .catch(setError)\n      .finally(() => setLoading(false));\n  }, [loadData]);\n\n  return \u003C>{children(data, loading, error)}\u003C\u002F>;\n}\n\n\u002F\u002F Usage\n\u003CDataLoader loadData={fetchUser}>\n  {(user, loading, error) => {\n    if (loading) return \u003CLoading \u002F>;\n    if (error) return \u003CError error={error} \u002F>;\n    return \u003CUserProfile user={user} \u002F>;\n  }}\n\u003C\u002FDataLoader>\n```\n\n## State Management Patterns\n\n### Local State\n\n```typescript\n\u002F\u002F Keep it simple when possible\nfunction Counter() {\n  const [count, setCount] = useState(0);\n  return \u003CButton onPress={() => setCount(c => c + 1)}>Count: {count}\u003C\u002FButton>;\n}\n```\n\n### Shared State (Context)\n\n```typescript\n\u002F\u002F For cross-cutting concerns\nconst ThemeContext = createContext\u003CThemeContextValue>(null!);\n\nexport function ThemeProvider({ children }: { children: React.ReactNode }) {\n  const [theme, setTheme] = useState\u003C'light' | 'dark'>('light');\n\n  return (\n    \u003CThemeContext.Provider value={{ theme, setTheme }}>\n      {children}\n    \u003C\u002FThemeContext.Provider>\n  );\n}\n\nexport function useTheme() {\n  const context = useContext(ThemeContext);\n  if (!context) throw new Error('useTheme must be used within ThemeProvider');\n  return context;\n}\n```\n\n### Global State (Zustand)\n\n```typescript\n\u002F\u002F For app-wide state\nimport { create } from 'zustand';\n\ninterface UserState {\n  user: User | null;\n  setUser: (user: User) => void;\n  logout: () => void;\n}\n\nexport const useUserStore = create\u003CUserState>((set) => ({\n  user: null,\n  setUser: (user) => set({ user }),\n  logout: () => set({ user: null }),\n}));\n```\n\n## Data Fetching Patterns\n\n### With Async\u002FAwait\n\n```typescript\nfunction useUserData(userId: string) {\n  const [data, setData] = useState(null);\n  const [loading, setLoading] = useState(true);\n  const [error, setError] = useState(null);\n\n  useEffect(() => {\n    let cancelled = false;\n\n    async function fetchData() {\n      try {\n        const response = await fetch(`\u002Fapi\u002Fusers\u002F${userId}`);\n        const result = await response.json();\n        if (!cancelled) {\n          setData(result);\n        }\n      } catch (err) {\n        if (!cancelled) {\n          setError(err);\n        }\n      } finally {\n        if (!cancelled) {\n          setLoading(false);\n        }\n      }\n    }\n\n    fetchData();\n\n    return () => {\n      cancelled = true;\n    };\n  }, [userId]);\n\n  return { data, loading, error };\n}\n```\n\n## Performance Patterns\n\n### Memoization\n\n```typescript\n\u002F\u002F Expensive calculations\nconst expensiveValue = useMemo(() => {\n  return calculateExpensiveValue(data);\n}, [data]);\n\n\u002F\u002F Stable callbacks\nconst handlePress = useCallback(() => {\n  doSomething(value);\n}, [value]);\n\n\u002F\u002F Component memoization\nconst MemoizedChild = memo(function Child({ data }: ChildProps) {\n  return \u003CView>{data}\u003C\u002FView>;\n});\n```\n\n### Lazy Loading\n\n```typescript\nimport { lazy, Suspense } from 'react';\n\nconst HeavyComponent = lazy(() => import('.\u002FHeavyComponent'));\n\nfunction App() {\n  return (\n    \u003CSuspense fallback={\u003CLoading \u002F>}>\n      \u003CHeavyComponent \u002F>\n    \u003C\u002FSuspense>\n  );\n}\n```\n\n## Error Handling Patterns\n\n### Error Boundaries\n\n```typescript\nclass ErrorBoundary extends React.Component\u003C\n  { children: React.ReactNode },\n  { hasError: boolean; error: Error | null }\n> {\n  state = { hasError: false, error: null };\n\n  static getDerivedStateFromError(error: Error) {\n    return { hasError: true, error };\n  }\n\n  componentDidCatch(error: Error, info: React.ErrorInfo) {\n    console.error('Error caught:', error, info);\n  }\n\n  render() {\n    if (this.state.hasError) {\n      return \u003CErrorScreen error={this.state.error} \u002F>;\n    }\n    return this.props.children;\n  }\n}\n```\n\n### Try-Catch Pattern\n\n```typescript\nasync function saveData() {\n  try {\n    await api.save(data);\n    showSuccess('Saved!');\n  } catch (error) {\n    if (error instanceof NetworkError) {\n      showError('Network error. Check connection.');\n    } else if (error instanceof ValidationError) {\n      showError(error.message);\n    } else {\n      showError('Something went wrong.');\n    }\n  }\n}\n```\n\n## Mobile-Specific Patterns\n\n### Safe Area Handling\n\n```typescript\nimport { useSafeAreaInsets } from 'react-native-safe-area-context';\n\nfunction Screen() {\n  const insets = useSafeAreaInsets();\n\n  return (\n    \u003CView style={{ paddingTop: insets.top, paddingBottom: insets.bottom }}>\n      {\u002F* Content *\u002F}\n    \u003C\u002FView>\n  );\n}\n```\n\n### Keyboard Avoiding\n\n```typescript\nimport { KeyboardAvoidingView, Platform } from 'react-native';\n\n\u003CKeyboardAvoidingView\n  behavior={Platform.OS === 'ios' ? 'padding' : 'height'}\n  style={{ flex: 1 }}\n>\n  {\u002F* Input form *\u002F}\n\u003C\u002FKeyboardAvoidingView>\n```\n\n## Best Practices\n\n1. **Keep Components Small**: Single responsibility, easy to test\n2. **Extract Custom Hooks**: Reuse logic across components\n3. **Use TypeScript**: Catch errors early\n4. **Handle Loading & Error States**: Better user experience\n5. **Clean Up Side Effects**: Prevent memory leaks\n6. **Optimize Wisely**: Profile before optimizing\n7. **Test Behavior**: Focus on user interactions\n\n## Anti-Patterns to Avoid\n\n- ❌ Massive components (>300 lines)\n- ❌ Prop drilling (use context\u002Fstore instead)\n- ❌ Missing cleanup in useEffect\n- ❌ Inline function definitions in render\n- ❌ Mutating state directly\n- ❌ Over-optimization without measuring\n\n## Resources\n\n- [React Patterns](https:\u002F\u002Freactpatterns.com\u002F)\n- [React Native Best Practices](https:\u002F\u002Freactnative.dev\u002Fdocs\u002Fperformance)\n",{"name":5,"description":7,"allowed-tools":47},"Read, Write, Edit","main","def8531e65114c0fca8fb8551c1871ee0eed705c","skills\u002Faiskillstore\u002Fmarketplace\u002Fbabakbar\u002Fcode-patterns-practices",24,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub","https:\u002F\u002Fskillshub.wtf","https:\u002F\u002Fgithub.com\u002FComeOnOliver","AI & Blockchain Engineer\r\n","2026-06-24 22:07:19",{"source":8,"skillName":5,"commands":58,"prompt":68,"zipAvailable":69},[59,62,65],{"tool":60,"command":61},"npx","npx skills add ComeOnOliver\u002Fskillshub --skill code-patterns-practices",{"tool":63,"command":64},"bunx","bunx skills add ComeOnOliver\u002Fskillshub --skill code-patterns-practices",{"tool":66,"command":67},"pnpm","pnpm dlx skills add ComeOnOliver\u002Fskillshub --skill code-patterns-practices","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fbabakbar\u002Fcode-patterns-practices\u002FSKILL.md",true,[71],{"path":72,"resourceType":73,"resourceTypeDesc":74,"sizeBytes":75,"sourceHtmlUrl":76},"skill-report.json","REFERENCE","参考文档",12318,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fbabakbar\u002Fcode-patterns-practices\u002Fskill-report.json",[78,92,102,111,117,124],{"skillNo":79,"name":80,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":81,"categories":82,"keywords":88,"publishedAt":42},"01M6FKJN13GMG4KY57J3QD8GY5","model-hierarchy-skill","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzscole\u002Fmodel-hierarchy-skill\u002Fmodel-hierarchy-skill\u002FSKILL.md",[83],{"categoryNo":84,"categoryName":85,"taxonomyType":86,"taxonomyTypeDesc":87},"01JBSEEDCAT000000000000023","Skill与智能体开发","SCENARIO","使用场景",[89,90,91],"model","model hierarchy","model hierarchy skill",{"skillNo":93,"name":94,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":95,"categories":96,"keywords":98,"publishedAt":42},"01M6FKJJJ6GCAMR4PPPRD12M5X","zoom-mcp","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fzoom-mcp\u002FSKILL.md",[97],{"categoryNo":84,"categoryName":85,"taxonomyType":86,"taxonomyTypeDesc":87},[99,100,101],"MCP","zoom","zoom mcp",{"skillNo":103,"name":104,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":105,"categories":106,"keywords":107,"publishedAt":42},"01M6FKJE3KYT3KPEZMEEHYKA6K","zoom-apps-sdk","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fzoom-apps-sdk\u002FSKILL.md",[],[108,109,110,100],"sdk","zoom apps sdk","apps",{"skillNo":112,"name":113,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":114,"categories":115,"keywords":116,"publishedAt":42},"01M6FKJ9EDH9Q5VWDF8HAJRSP0","windows","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwindows\u002FSKILL.md",[],[113],{"skillNo":118,"name":119,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":120,"categories":121,"keywords":123,"publishedAt":42},"01M6FKJ666BEEFC3AE9GJ72Q93","whiteboard","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwhiteboard\u002FSKILL.md",[122],{"categoryNo":84,"categoryName":85,"taxonomyType":86,"taxonomyTypeDesc":87},[119],{"skillNo":125,"name":126,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":127,"categories":128,"keywords":129,"publishedAt":42},"01M6FKJ21WFCDGTJQ2Q91T9DVW","websockets","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwebsockets\u002FSKILL.md",[],[126]]