{"id":49146426,"url":"https://github.com/rodielm/poke-memory-game","last_synced_at":"2026-04-22T04:04:54.211Z","repository":{"id":337247021,"uuid":"1152800059","full_name":"Rodielm/poke-memory-game","owner":"Rodielm","description":null,"archived":false,"fork":false,"pushed_at":"2026-02-08T14:23:32.000Z","size":126,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-02-08T20:49:59.321Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Rodielm.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-02-08T13:06:49.000Z","updated_at":"2026-02-08T14:23:35.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/Rodielm/poke-memory-game","commit_stats":null,"previous_names":["rodielm/poke-memory-game"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/Rodielm/poke-memory-game","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Rodielm%2Fpoke-memory-game","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Rodielm%2Fpoke-memory-game/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Rodielm%2Fpoke-memory-game/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Rodielm%2Fpoke-memory-game/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Rodielm","download_url":"https://codeload.github.com/Rodielm/poke-memory-game/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Rodielm%2Fpoke-memory-game/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32120408,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-22T00:31:26.853Z","status":"online","status_checked_at":"2026-04-22T02:00:05.693Z","response_time":58,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-04-22T04:04:28.936Z","updated_at":"2026-04-22T04:04:54.203Z","avatar_url":"https://github.com/Rodielm.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Poke Memory Game\n\nJuego de memoria con cartas de Pokemon construido con **React + Vite + Tailwind CSS**.\n\n\u003e Este README es una guia paso a paso para aprender a crear la app desde cero.\n\n## Demo\n\n[Jugar online](https://rodielm.github.io/poke-memory-game/)\n\n## Que vas a aprender\n\n- Crear un proyecto con Vite + React\n- Manejar estado con `useState`\n- Ejecutar efectos con `useEffect`\n- Renderizado condicional y listas con `.map()`\n- Animaciones CSS 3D (efecto flip de cartas)\n- Estilos con Tailwind CSS\n- Deploy a GitHub Pages\n\n## Requisitos previos\n\n- Node.js (v18+) o Docker\n- Conocimientos basicos de HTML, CSS y JavaScript\n\n---\n\n## Paso 1: Crear el proyecto\n\n```bash\nnpm create vite@latest poke-memory-game -- --template react\ncd poke-memory-game\nnpm install\n```\n\nEsto genera la estructura base:\n\n```\npoke-memory-game/\n├── public/          # Archivos estaticos (favicon, imagenes)\n├── src/\n│   ├── App.jsx      # Componente principal\n│   ├── main.jsx     # Punto de entrada (monta React en el DOM)\n│   └── index.css    # Estilos globales\n├── index.html       # HTML base (Vite inyecta los scripts aqui)\n├── vite.config.js   # Configuracion de Vite\n└── package.json     # Dependencias y scripts\n```\n\n## Paso 2: Instalar dependencias\n\n```bash\nnpm install lucide-react\nnpm install -D tailwindcss @tailwindcss/vite\n```\n\n| Paquete | Para que sirve |\n|---------|---------------|\n| `lucide-react` | Iconos como el boton de reinicio |\n| `tailwindcss` | Framework CSS basado en clases utilitarias |\n| `@tailwindcss/vite` | Plugin para integrar Tailwind con Vite |\n\n## Paso 3: Configurar Tailwind y Vite\n\n**`vite.config.js`** - Agregar el plugin de Tailwind:\n\n```js\nimport { defineConfig } from 'vite'\nimport react from '@vitejs/plugin-react'\nimport tailwindcss from '@tailwindcss/vite'\n\nexport default defineConfig({\n  plugins: [react(), tailwindcss()],\n})\n```\n\n**`src/index.css`** - Importar Tailwind:\n\n```css\n@import \"tailwindcss\";\n```\n\nCon esto ya puedes usar clases como `bg-blue-500`, `p-4`, `flex`, etc.\n\n## Paso 4: Definir los datos de los Pokemon\n\nEn `src/App.jsx`, definimos un array con los Pokemon que usara el juego:\n\n```jsx\nconst POKEMON_DATA = [\n  { id: 1, name: 'Bulbasaur', image: 'https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/1.png' },\n  { id: 4, name: 'Charmander', image: '...' },\n  // ... 8 Pokemon en total\n];\n```\n\nUsamos sprites directos de GitHub (PokeAPI) en vez de una API para evitar latencia y limites de peticiones.\n\n## Paso 5: Crear el estado del juego\n\nReact usa **hooks** para manejar datos que cambian. Cada `useState` crea una variable reactiva:\n\n```jsx\nconst PokemonMemoryGame = () =\u003e {\n  const [cards, setCards] = useState([]);       // Las 16 cartas en el tablero\n  const [flipped, setFlipped] = useState([]);   // Cartas volteadas (max 2)\n  const [matched, setMatched] = useState([]);   // Cartas ya emparejadas\n  const [moves, setMoves] = useState(0);        // Contador de movimientos\n  const [loading, setLoading] = useState(true); // Estado de carga\n};\n```\n\nCuando llamas a `setCards(nuevasCartas)`, React re-renderiza el componente con los nuevos datos.\n\n## Paso 6: Inicializar el juego\n\n```jsx\nuseEffect(() =\u003e {\n  initGame();\n}, []); // [] = ejecutar solo al montar el componente\n\nconst initGame = () =\u003e {\n  // 1. Duplicar los pokemon para crear pares\n  const gameCards = [...POKEMON_DATA, ...POKEMON_DATA].map((pokemon, index) =\u003e ({\n    ...pokemon,\n    uniqueId: index,    // ID unico por carta (0-15)\n    pairId: pokemon.id  // ID para emparejar (ej: ambas Pikachu = 25)\n  }));\n\n  // 2. Mezclar y resetear estado\n  setCards(shuffleArray(gameCards));\n  setFlipped([]);\n  setMatched([]);\n  setMoves(0);\n};\n```\n\n**Conceptos clave:**\n- `useEffect` con `[]` se ejecuta una sola vez al cargar\n- Spread operator `[...array]` crea una copia del array\n- `.map()` transforma cada elemento del array\n\n## Paso 7: Algoritmo de mezcla (Fisher-Yates)\n\n```jsx\nconst shuffleArray = (array) =\u003e {\n  const newArray = [...array];\n  for (let i = newArray.length - 1; i \u003e 0; i--) {\n    const j = Math.floor(Math.random() * (i + 1));\n    [newArray[i], newArray[j]] = [newArray[j], newArray[i]];\n  }\n  return newArray;\n};\n```\n\nEs el algoritmo estandar para mezclar arrays. Recorre de atras hacia adelante e intercambia cada posicion con una aleatoria.\n\n## Paso 8: Logica de click en cartas\n\nEsta es la logica central del juego:\n\n```jsx\nconst handleCardClick = (uniqueId) =\u003e {\n  // Ignorar si: ya hay 2 volteadas, ya esta volteada, o ya fue emparejada\n  if (flipped.length === 2 || flipped.includes(uniqueId) || matched.includes(uniqueId)) {\n    return;\n  }\n\n  const newFlipped = [...flipped, uniqueId];\n  setFlipped(newFlipped);\n\n  if (newFlipped.length === 2) {\n    setMoves(moves + 1);\n    const firstCard = cards.find(c =\u003e c.uniqueId === newFlipped[0]);\n    const secondCard = cards.find(c =\u003e c.uniqueId === newFlipped[1]);\n\n    if (firstCard.pairId === secondCard.pairId) {\n      // Son pareja: guardar en matched despues de 600ms\n      setTimeout(() =\u003e {\n        setMatched([...matched, newFlipped[0], newFlipped[1]]);\n        setFlipped([]);\n      }, 600);\n    } else {\n      // No son pareja: voltear de regreso despues de 1s\n      setTimeout(() =\u003e setFlipped([]), 1000);\n    }\n  }\n};\n```\n\n**Flujo:**\n1. Click en carta 1 -\u003e se voltea\n2. Click en carta 2 -\u003e se voltea + comparar\n3. Si son iguales -\u003e quedan volteadas (matched)\n4. Si no -\u003e se voltean de regreso despues de 1 segundo\n\n## Paso 9: Animacion flip con CSS 3D\n\nEl efecto de voltear cartas usa transformaciones CSS 3D:\n\n```jsx\n{/* Contenedor con perspectiva (habilita el 3D) */}\n\u003cdiv style={{ perspective: '1000px' }}\u003e\n\n  {/* Carta que rota */}\n  \u003cdiv style={{\n    transformStyle: 'preserve-3d',                              // Hijos con profundidad\n    transform: isFlipped ? 'rotateY(180deg)' : 'rotateY(0deg)' // Girar o no\n  }}\u003e\n\n    {/* Cara trasera (Pokeball) */}\n    \u003cdiv style={{ backfaceVisibility: 'hidden' }}\u003e\n      ...\n    \u003c/div\u003e\n\n    {/* Cara frontal (Pokemon) - pre-rotada 180deg */}\n    \u003cdiv style={{ backfaceVisibility: 'hidden', transform: 'rotateY(180deg)' }}\u003e\n      ...\n    \u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\n```\n\n**Como funciona:**\n- Ambas caras se superponen con `position: absolute`\n- `backfaceVisibility: hidden` oculta cada cara cuando esta de espaldas\n- La cara frontal empieza rotada 180deg, asi cuando el contenedor rota 180deg, queda al frente\n\n## Paso 10: Deploy a GitHub Pages\n\n### 1. Configurar `base` en Vite\n\n```js\n// vite.config.js\nexport default defineConfig({\n  base: '/poke-memory-game/',  // Nombre de tu repositorio\n  plugins: [react(), tailwindcss()],\n})\n```\n\nEsto es necesario porque GitHub Pages sirve desde `https://usuario.github.io/repo/`, no desde la raiz `/`.\n\n### 2. Instalar gh-pages\n\n```bash\nnpm install -D gh-pages\n```\n\n### 3. Agregar scripts en package.json\n\n```json\n{\n  \"scripts\": {\n    \"predeploy\": \"npm run build\",\n    \"deploy\": \"gh-pages -d dist\"\n  }\n}\n```\n\n### 4. Desplegar\n\n```bash\nnpm run deploy\n```\n\nEsto hace build, crea la rama `gh-pages` y sube los archivos. Tu app estara en:\n`https://tu-usuario.github.io/poke-memory-game/`\n\n### 5. Configurar en GitHub\n\nVe a **Settings \u003e Pages** del repositorio y selecciona:\n- Source: **Deploy from a branch**\n- Branch: **gh-pages** / **(root)**\n\n---\n\n## Ejecutar localmente\n\n### Opcion 1: Node.js\n\n```bash\nnpm install\nnpm run dev\n```\n\n### Opcion 2: Docker\n\n```bash\ndocker compose up\n```\n\nLa app estara en `http://localhost:5173` con hot-reload.\n\n## Tecnologias\n\n| Tecnologia | Version | Uso |\n|-----------|---------|-----|\n| React | 19 | UI con componentes |\n| Vite | 7 | Bundler y dev server |\n| Tailwind CSS | 4 | Estilos utilitarios |\n| Lucide React | - | Iconos SVG |\n| gh-pages | - | Deploy a GitHub Pages |\n\n---\n\n## Glosario: Conceptos clave\n\nReferencia rapida de cada tecnologia y concepto utilizado en este proyecto.\n\n### React\n\nReact es una **libreria de JavaScript para construir interfaces de usuario**. En vez de manipular el HTML directamente (como con `document.getElementById`), React te permite crear **componentes** — piezas reutilizables de UI que manejan su propio estado.\n\n```jsx\n// Sin React (vanilla JS)\ndocument.getElementById('counter').innerText = count;\n\n// Con React - declaras QUE quieres ver, React se encarga del COMO\nconst [count, setCount] = useState(0);\nreturn \u003cp\u003e{count}\u003c/p\u003e; // React actualiza el DOM automaticamente\n```\n\n**Conceptos de React usados en este proyecto:**\n\n| Concepto | Que es | Donde se usa |\n|----------|--------|-------------|\n| **Componente** | Funcion que retorna JSX (HTML-like). Pieza reutilizable de UI | `PokemonMemoryGame` es el componente principal |\n| **JSX** | Sintaxis que parece HTML pero es JavaScript. Se compila a `React.createElement()` | Todo lo que esta dentro de `return (...)` |\n| **useState** | Hook que crea una variable reactiva. Cuando cambia, React re-renderiza | `cards`, `flipped`, `matched`, `moves`, `loading` |\n| **useEffect** | Hook que ejecuta codigo cuando el componente se monta o cuando cambian sus dependencias | Inicializar el juego al cargar |\n| **Props** | Datos que un componente padre pasa a un hijo | No se usan aqui (es un solo componente) |\n| **Renderizado condicional** | Mostrar u ocultar JSX segun una condicion | `{isGameComplete \u0026\u0026 \u003cdiv\u003e...\u003c/div\u003e}` |\n| **Listas con .map()** | Renderizar multiples elementos a partir de un array | `{cards.map((card) =\u003e \u003cdiv\u003e...\u003c/div\u003e)}` |\n| **key** | Identificador unico en listas para que React sepa que elemento cambio | `key={card.uniqueId}` |\n\n### Vite\n\nVite es un **bundler y servidor de desarrollo** para aplicaciones web modernas. Es el reemplazo moderno de herramientas como Webpack o Create React App.\n\n**Que hace Vite:**\n- **En desarrollo:** Levanta un servidor local con **Hot Module Replacement (HMR)** — cuando guardas un archivo, el cambio se refleja instantaneamente en el navegador sin recargar la pagina\n- **En produccion (`npm run build`):** Empaqueta todo tu codigo en archivos optimizados (minificados, con hashes) listos para subir a un servidor\n\n**Por que Vite y no Create React App:**\n- Vite es mucho mas rapido (usa ESModules nativos del navegador)\n- Create React App fue deprecado oficialmente\n- Configuracion minima — un solo archivo `vite.config.js`\n\n```\nnpm run dev     → Servidor local con HMR (desarrollo)\nnpm run build   → Genera carpeta dist/ con archivos optimizados (produccion)\nnpm run preview → Sirve la carpeta dist/ localmente para probar el build\n```\n\n### Tailwind CSS\n\nTailwind es un **framework CSS basado en clases utilitarias**. En vez de escribir CSS en archivos separados, aplicas estilos directamente en el HTML con clases predefinidas.\n\n```jsx\n// CSS tradicional:\n// .boton { background: blue; padding: 12px 24px; border-radius: 9999px; }\n// \u003cbutton class=\"boton\"\u003eClick\u003c/button\u003e\n\n// Tailwind - estilos directamente en la clase:\n\u003cbutton className=\"bg-blue-500 py-3 px-6 rounded-full\"\u003eClick\u003c/button\u003e\n```\n\n**Clases usadas en este proyecto:**\n\n| Clase | CSS equivalente | Categoria |\n|-------|----------------|-----------|\n| `min-h-screen` | `min-height: 100vh` | Tamaño |\n| `p-4` | `padding: 1rem` | Espaciado |\n| `bg-blue-500` | `background-color: #3b82f6` | Color |\n| `text-white` | `color: white` | Texto |\n| `flex` | `display: flex` | Layout |\n| `grid grid-cols-4` | `display: grid; grid-template-columns: repeat(4, 1fr)` | Grid |\n| `rounded-xl` | `border-radius: 0.75rem` | Bordes |\n| `shadow-lg` | `box-shadow: ...` | Sombras |\n| `hover:scale-105` | `:hover { transform: scale(1.05) }` | Interactivo |\n| `sm:p-8` | `@media (min-width: 640px) { padding: 2rem }` | Responsive |\n| `animate-pulse` | Animacion de opacidad pulsante | Animacion |\n| `transition-all` | `transition: all` | Transicion |\n| `bg-white/90` | `background: rgba(255,255,255,0.9)` | Opacidad |\n| `backdrop-blur-sm` | `backdrop-filter: blur(4px)` | Filtros |\n\n**Ventajas:** No cambias entre archivos HTML y CSS, los estilos son predecibles, y el build final solo incluye las clases que usaste.\n\n### npm (Node Package Manager)\n\nnpm es el **gestor de paquetes de Node.js**. Permite instalar y administrar librerias externas.\n\n**Archivos clave:**\n\n| Archivo | Que hace |\n|---------|----------|\n| `package.json` | Lista las dependencias y scripts del proyecto |\n| `package-lock.json` | Fija las versiones exactas de cada dependencia (no editar manualmente) |\n| `node_modules/` | Carpeta donde se instalan las dependencias (no se sube a git) |\n\n**Comandos usados:**\n\n```bash\nnpm install              # Instala todas las dependencias de package.json\nnpm install lucide-react # Agrega una dependencia de produccion\nnpm install -D gh-pages  # Agrega una dependencia de desarrollo (-D = devDependency)\nnpm run dev              # Ejecuta el script \"dev\" definido en package.json\nnpm run build            # Ejecuta el script \"build\"\nnpm run deploy           # Ejecuta \"predeploy\" automaticamente, luego \"deploy\"\n```\n\n**dependencies vs devDependencies:**\n- `dependencies`: Se necesitan para que la app funcione (React, Lucide)\n- `devDependencies`: Solo se necesitan durante el desarrollo (Vite, Tailwind, ESLint, gh-pages)\n\n### Docker\n\nDocker permite **empaquetar una aplicacion con todo lo que necesita** (sistema operativo, runtime, dependencias) en un **contenedor**. Esto garantiza que la app funcione igual en cualquier maquina.\n\n**Analogia:** Un contenedor es como una caja que incluye la app + todas sus herramientas. No importa en que computadora la abras, siempre funciona igual.\n\n**Dockerfile** — La \"receta\" para construir la imagen:\n\n```dockerfile\nFROM node:22-bookworm-slim          # 1. Partir de una imagen base con Node.js\n\nRUN apt-get update \u0026\u0026 apt-get install -y \\\n    git curl \\                       # 2. Instalar herramientas del sistema\n    \u0026\u0026 rm -rf /var/lib/apt/lists/*\n\nWORKDIR /workspace                   # 3. Definir directorio de trabajo\n\nCOPY package.json package-lock.json ./ # 4. Copiar archivos de dependencias\nRUN npm install                      # 5. Instalar dependencias (se cachea si no cambian)\n\nCOPY . .                             # 6. Copiar el resto del codigo\n\nEXPOSE 5173                          # 7. Documentar que puerto usa la app\n\nCMD [\"npm\", \"run\", \"dev\", \"--\", \"--host\"] # 8. Comando por defecto al iniciar\n```\n\n**Conceptos clave de Docker:**\n\n| Concepto | Que es |\n|----------|--------|\n| **Imagen** | Plantilla de solo lectura con el SO + app + dependencias. Se crea con `docker build` |\n| **Contenedor** | Instancia en ejecucion de una imagen. Se crea con `docker run` |\n| **Dockerfile** | Archivo con instrucciones para construir una imagen |\n| **WORKDIR** | Directorio de trabajo dentro del contenedor |\n| **COPY** | Copia archivos del host al contenedor |\n| **EXPOSE** | Documenta que puerto usa la app (no lo abre, solo informativo) |\n| **CMD** | Comando que se ejecuta al iniciar el contenedor |\n\n### Docker Compose\n\nDocker Compose es una herramienta para **definir y ejecutar aplicaciones multi-contenedor** con un solo archivo YAML. Aunque aqui usamos un solo servicio, simplifica mucho la configuracion.\n\n```yaml\nservices:\n  app:\n    build: .                    # Construir imagen desde el Dockerfile actual\n    ports:\n      - \"5173:5173\"             # Mapear puerto: host:contenedor\n    volumes:\n      - .:/workspace            # Montar codigo local en el contenedor (hot-reload)\n      - node_modules:/workspace/node_modules  # Volumen persistente para node_modules\n    command: npm run dev -- --host\n\nvolumes:\n  node_modules:                 # Volumen nombrado (persiste entre reinicios)\n```\n\n**Por que usamos volumes:**\n- `.:/workspace` — Monta tu codigo local dentro del contenedor. Cuando editas un archivo en tu editor, el cambio se ve dentro del contenedor inmediatamente (asi funciona el hot-reload con Vite)\n- `node_modules:/workspace/node_modules` — Volumen separado para que los `node_modules` del contenedor (Linux) no se mezclen con los de tu maquina (puede ser Mac/Windows)\n\n**Comandos:**\n\n```bash\ndocker compose up          # Construir imagen (si no existe) + levantar contenedor\ndocker compose up --build  # Forzar reconstruccion de la imagen\ndocker compose down        # Detener y eliminar contenedores\ndocker compose exec app sh # Abrir terminal dentro del contenedor\n```\n\n### GitHub Pages\n\nGitHub Pages es un **servicio gratuito de hosting para sitios estaticos** (HTML, CSS, JS) directamente desde un repositorio de GitHub.\n\n**Como funciona en este proyecto:**\n1. `npm run build` genera la carpeta `dist/` con archivos estaticos optimizados\n2. `gh-pages -d dist` sube el contenido de `dist/` a la rama `gh-pages`\n3. GitHub detecta la rama y sirve los archivos en `https://usuario.github.io/repo/`\n\n**Importante:** Como la app se sirve desde un subdirectorio (`/poke-memory-game/` y no `/`), hay que configurar `base` en Vite para que las rutas de los assets sean correctas.\n\n### ESLint\n\nESLint es un **linter** — una herramienta que analiza tu codigo JavaScript/JSX y detecta errores o malas practicas **sin ejecutarlo**.\n\n```bash\nnpm run lint  # Ejecutar ESLint en el proyecto\n```\n\nEjemplo de lo que detecta: variables sin usar, imports duplicados, hooks de React usados incorrectamente.\n\n### Lucide React\n\nLucide es una libreria de **iconos SVG** optimizados para React. Cada icono es un componente que puedes importar individualmente (tree-shakeable — solo se incluye lo que usas en el build final).\n\n```jsx\nimport { RotateCcw } from 'lucide-react';\n\n\u003cRotateCcw size={20} /\u003e  // Renderiza un icono SVG de 20x20px\n```\n\n## Autor\n\nRodiel - [GitHub](https://github.com/Rodielm)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frodielm%2Fpoke-memory-game","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frodielm%2Fpoke-memory-game","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frodielm%2Fpoke-memory-game/lists"}