sugar-sliderpuzzle-activity-5.orig/0000755000175000017500000000000010755626243016322 5ustar janijanisugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/0000755000175000017500000000000010755626243022611 5ustar janijanisugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/po/0000755000175000017500000000000010755626243023227 5ustar janijanisugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/po/es.po0000644000175000017500000000557610716617376024217 0ustar janijani# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2007-09-10 10:34+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" #: activity/activity.info:2 msgid "Slider Puzzle" msgstr "" #: SliderPuzzleUI.py:700 msgid "Solve" msgstr "Solucionar" #: SliderPuzzleUI.py:704 msgid "Shuffle" msgstr "Revoltijo" #: SliderPuzzleUI.py:708 msgid "My Picture" msgstr "Mi cuadro" #: SliderPuzzleUI.py:751 msgid "Time: " msgstr "Tiempo: " #: SliderPuzzleUI.py:756 SliderPuzzleUI.py:1043 msgid "Lesson Plans" msgstr "Planes de la lección" #: SliderPuzzleUI.py:776 msgid "Waiting for remote game..." msgstr "" #: SliderPuzzleUI.py:830 msgid "Select image to share..." msgstr "" #: SliderPuzzleUI.py:834 msgid "Waiting for game image..." msgstr "" #: SliderPuzzleUI.py:836 SliderPuzzleUI.py:846 msgid "Buddies" msgstr "" #: SliderPuzzleUI.py:844 msgid "Game Started!" msgstr "" #: SliderPuzzleUI.py:864 msgid "Give Up" msgstr "" #: SliderPuzzleUI.py:866 msgid "Start Game" msgstr "" #: SliderPuzzleUI.py:876 msgid "Slider Puzzle Activity" msgstr "" #: SliderPuzzleUI.py:976 msgid "Choose a Subject" msgstr "Elegir un tema" #: SliderPuzzleUI.py:1004 msgid "Image Files" msgstr "" #: SliderPuzzleUI.py:1006 msgid "Select Image File" msgstr "" #: SliderPuzzleUI.py:1022 msgid "Not a valid image file" msgstr "" #: SliderPuzzleUI.py:1046 msgid "Close Lesson" msgstr "Cerrar lección" #: i18n_misc_strings.py:1 msgid "Sea Life" msgstr "Vida del mar" #: i18n_misc_strings.py:2 msgid "Animals" msgstr "Animales" #: i18n_misc_strings.py:3 msgid "Birds" msgstr "Pájaros" #: i18n_misc_strings.py:4 msgid "XO" msgstr "" #: i18n_misc_strings.py:5 msgid "Sequencing Puzzles" msgstr "Rompecabezas con Secuencias" #: i18n_misc_strings.py:6 msgid "Sports" msgstr "Deportes" #: i18n_misc_strings.py:7 msgid "Insects" msgstr "Insectos" #: i18n_misc_strings.py:8 msgid "Music" msgstr "Música" #: i18n_misc_strings.py:9 msgid "Space" msgstr "Espacio" #: i18n_misc_strings.py:10 msgid "Lesson 5" msgstr "Lección 5" #: i18n_misc_strings.py:11 msgid "Lesson 4" msgstr "Lección 4" #: i18n_misc_strings.py:12 msgid "Overview" msgstr "" #: i18n_misc_strings.py:13 msgid "Lesson 3" msgstr "Lección 3" #: i18n_misc_strings.py:14 msgid "Lesson 7" msgstr "Lección 7" #: i18n_misc_strings.py:15 msgid "Lesson 6" msgstr "Lección 6" #: i18n_misc_strings.py:16 msgid "Lesson 1" msgstr "Lección 1" #: i18n_misc_strings.py:17 msgid "Lesson 2" msgstr "Lección 2" #~ msgid "My Pictures" #~ msgstr "Mi cuadros" sugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/po/ko.po0000644000175000017500000001054110716617376024205 0ustar janijani# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2007-09-10 10:34+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" #: activity/activity.info:2 #, fuzzy msgid "Slider Puzzle" msgstr "슬라이더 퍼즐 액티비티" #: SliderPuzzleUI.py:700 msgid "Solve" msgstr "풀기" #: SliderPuzzleUI.py:704 msgid "Shuffle" msgstr "" #: SliderPuzzleUI.py:708 msgid "My Picture" msgstr "내 모습" #: SliderPuzzleUI.py:751 msgid "Time: " msgstr "타임" #: SliderPuzzleUI.py:756 SliderPuzzleUI.py:1043 msgid "Lesson Plans" msgstr "레슨 플랜" #: SliderPuzzleUI.py:776 msgid "Waiting for remote game..." msgstr "먼 게임을 기다리는 중..." #: SliderPuzzleUI.py:830 msgid "Select image to share..." msgstr "함께할 이미지를 선택하세요" #: SliderPuzzleUI.py:834 msgid "Waiting for game image..." msgstr "게임 이미지를 기다리는 중..." #: SliderPuzzleUI.py:836 SliderPuzzleUI.py:846 #, fuzzy msgid "Buddies" msgstr "버디" #: SliderPuzzleUI.py:844 msgid "Game Started!" msgstr "" #: SliderPuzzleUI.py:864 msgid "Give Up" msgstr "" #: SliderPuzzleUI.py:866 msgid "Start Game" msgstr "" #: SliderPuzzleUI.py:876 #, fuzzy msgid "Slider Puzzle Activity" msgstr "슬라이더 퍼즐 액티비티" #: SliderPuzzleUI.py:976 msgid "Choose a Subject" msgstr "주제를 선택하세요" #: SliderPuzzleUI.py:1004 msgid "Image Files" msgstr "이미지 파일" #: SliderPuzzleUI.py:1006 msgid "Select Image File" msgstr "이미지 파일을 선택하세요" #: SliderPuzzleUI.py:1022 msgid "Not a valid image file" msgstr "이미지 파일이 아님" #: SliderPuzzleUI.py:1046 msgid "Close Lesson" msgstr "레슨 닫기" #: i18n_misc_strings.py:1 msgid "Sea Life" msgstr "바다 생물" #: i18n_misc_strings.py:2 msgid "Animals" msgstr "동물" #: i18n_misc_strings.py:3 msgid "Birds" msgstr "새" #: i18n_misc_strings.py:4 msgid "XO" msgstr "XO" #: i18n_misc_strings.py:5 msgid "Sequencing Puzzles" msgstr "퍼즐 정렬하기" #: i18n_misc_strings.py:6 msgid "Sports" msgstr "스포츠" #: i18n_misc_strings.py:7 msgid "Insects" msgstr "곤충" #: i18n_misc_strings.py:8 msgid "Music" msgstr "뮤직" #: i18n_misc_strings.py:9 msgid "Space" msgstr "공간" #: i18n_misc_strings.py:10 msgid "Lesson 5" msgstr "레슨 5" #: i18n_misc_strings.py:11 msgid "Lesson 4" msgstr "레슨 4" #: i18n_misc_strings.py:12 msgid "Overview" msgstr "개관" #: i18n_misc_strings.py:13 msgid "Lesson 3" msgstr "레슨 3" #: i18n_misc_strings.py:14 msgid "Lesson 7" msgstr "레슨 7" #: i18n_misc_strings.py:15 msgid "Lesson 6" msgstr "레슨 6" #: i18n_misc_strings.py:16 msgid "Lesson 1" msgstr "레슨 1" #: i18n_misc_strings.py:17 msgid "Lesson 2" msgstr "레슨 2" #~ msgid "My Pictures" #~ msgstr "내 모습" #~ msgid "Status" #~ msgstr "상태" #~ msgid "Play Time" #~ msgstr "플레이 타임" #~ msgid "Chinese (simplified)" #~ msgstr "중국어 (간자)" #~ msgid "Chinese (traditional)" #~ msgstr "중국어 (번자)" #~ msgid "Czech" #~ msgstr "체코어" #~ msgid "Danish" #~ msgstr "덴마크어" #~ msgid "Dutch" #~ msgstr "네덜란드어" #~ msgid "English" #~ msgstr "영어" #~ msgid "English - Great Britain" #~ msgstr "영어-영국식" #~ msgid "English - U.S." #~ msgstr "영어-미국식" #~ msgid "Finnish" #~ msgstr "핀란드어" #~ msgid "French" #~ msgstr "프랑스어" #~ msgid "German" #~ msgstr "독일어" #~ msgid "Hungarian" #~ msgstr "헝가리어" #~ msgid "Italian" #~ msgstr "이태리어" #~ msgid "Japanese" #~ msgstr "일본어" #~ msgid "Korean" #~ msgstr "한국어" #~ msgid "Norwegian" #~ msgstr "노르웨이어" #~ msgid "Polish" #~ msgstr "폴란드어" #~ msgid "Portuguese" #~ msgstr "포르투칼어" #~ msgid "Portuguese - Brazilian" #~ msgstr "포르투칼어-브라질" #~ msgid "Russian" #~ msgstr "러시아어" #~ msgid "Slovak" #~ msgstr "슬로바키아어" #~ msgid "Spanish" #~ msgstr "스페인어" #~ msgid "Swedish" #~ msgstr "스웨덴어" #~ msgid "Turkish" #~ msgstr "터키어" sugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/po/pt.po0000644000175000017500000001110210716617376024211 0ustar janijani# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2007-09-10 10:34+0100\n" "PO-Revision-Date: 2007-05-23 10:48+0100\n" "Last-Translator: Carlos Neves \n" "Language-Team: Portuguese \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" #: activity/activity.info:2 #, fuzzy msgid "Slider Puzzle" msgstr "Actividade Slider Puzzle" #: SliderPuzzleUI.py:700 msgid "Solve" msgstr "Resolver" #: SliderPuzzleUI.py:704 msgid "Shuffle" msgstr "Baralhar" #: SliderPuzzleUI.py:708 msgid "My Picture" msgstr "Minha Imagem" #: SliderPuzzleUI.py:751 msgid "Time: " msgstr "Tempo: " #: SliderPuzzleUI.py:756 SliderPuzzleUI.py:1043 msgid "Lesson Plans" msgstr "Planos de Ensino" #: SliderPuzzleUI.py:776 msgid "Waiting for remote game..." msgstr "Esperando por jogo remoto..." #: SliderPuzzleUI.py:830 msgid "Select image to share..." msgstr "Seleccione imagem para partilhar..." #: SliderPuzzleUI.py:834 msgid "Waiting for game image..." msgstr "Esperando pela imagem para jogar..." #: SliderPuzzleUI.py:836 SliderPuzzleUI.py:846 msgid "Buddies" msgstr "" #: SliderPuzzleUI.py:844 msgid "Game Started!" msgstr "O Jogo Comecou!" #: SliderPuzzleUI.py:864 msgid "Give Up" msgstr "Desistir" #: SliderPuzzleUI.py:866 msgid "Start Game" msgstr "Iniciar Jogo" #: SliderPuzzleUI.py:876 #, fuzzy msgid "Slider Puzzle Activity" msgstr "Actividade Slider Puzzle" #: SliderPuzzleUI.py:976 msgid "Choose a Subject" msgstr "Escolha um Assunto" #: SliderPuzzleUI.py:1004 msgid "Image Files" msgstr "Imagens" #: SliderPuzzleUI.py:1006 msgid "Select Image File" msgstr "Seleccione uma Imagen" #: SliderPuzzleUI.py:1022 msgid "Not a valid image file" msgstr "Imagem inválida" #: SliderPuzzleUI.py:1046 msgid "Close Lesson" msgstr "Fechar Plano" #: i18n_misc_strings.py:1 msgid "Sea Life" msgstr "Vida Marinha" #: i18n_misc_strings.py:2 msgid "Animals" msgstr "Animais" #: i18n_misc_strings.py:3 msgid "Birds" msgstr "Pássaros" #: i18n_misc_strings.py:4 msgid "XO" msgstr "" #: i18n_misc_strings.py:5 msgid "Sequencing Puzzles" msgstr "Sequências" #: i18n_misc_strings.py:6 msgid "Sports" msgstr "Desporto" #: i18n_misc_strings.py:7 msgid "Insects" msgstr "Insetos" #: i18n_misc_strings.py:8 msgid "Music" msgstr "Música" #: i18n_misc_strings.py:9 msgid "Space" msgstr "Espaço" #: i18n_misc_strings.py:10 msgid "Lesson 5" msgstr "Lição 5" #: i18n_misc_strings.py:11 msgid "Lesson 4" msgstr "Lição 4" #: i18n_misc_strings.py:12 msgid "Overview" msgstr "Resumo" #: i18n_misc_strings.py:13 msgid "Lesson 3" msgstr "Lição 3" #: i18n_misc_strings.py:14 msgid "Lesson 7" msgstr "Lição 7" #: i18n_misc_strings.py:15 msgid "Lesson 6" msgstr "Lição 6" #: i18n_misc_strings.py:16 msgid "Lesson 1" msgstr "Lição 1" #: i18n_misc_strings.py:17 msgid "Lesson 2" msgstr "Lição 2" #~ msgid "My Pictures" #~ msgstr "Minhas Imagens" #~ msgid "Status" #~ msgstr "Estado" #~ msgid "Play Time" #~ msgstr "Tempo de Jogo" #~ msgid "Chinese (simplified)" #~ msgstr "Chinês (simplificado)" #~ msgid "Chinese (traditional)" #~ msgstr "Chinês (tradicional)" #~ msgid "Czech" #~ msgstr "Checo" #~ msgid "Danish" #~ msgstr "Dinamarquês" #~ msgid "Dutch" #~ msgstr "Holandês" #~ msgid "English" #~ msgstr "Inglês" #~ msgid "English - Great Britain" #~ msgstr "Inglês - Reino Unido" #~ msgid "English - U.S." #~ msgstr "Inglês - E.U.A." #~ msgid "Finnish" #~ msgstr "Filandês" #~ msgid "French" #~ msgstr "Francês" #~ msgid "German" #~ msgstr "Alemão" #~ msgid "Hungarian" #~ msgstr "Hungaro" #~ msgid "Italian" #~ msgstr "Italiano" #~ msgid "Japanese" #~ msgstr "Japonês" #~ msgid "Korean" #~ msgstr "Coreano" #~ msgid "Norwegian" #~ msgstr "Norueguês" #~ msgid "Polish" #~ msgstr "Polaco" #~ msgid "Portuguese" #~ msgstr "Português" #~ msgid "Portuguese - Brazilian" #~ msgstr "Portugês - Brasil" #~ msgid "Russian" #~ msgstr "Russo" #~ msgid "Slovak" #~ msgstr "Eslovaco" #~ msgid "Spanish" #~ msgstr "Espanhol" #~ msgid "Swedish" #~ msgstr "Sueco" #~ msgid "Turkish" #~ msgstr "Turco" #~ msgid "synchronizing" #~ msgstr "sincronizando" #~ msgid "Playing" #~ msgstr "Jogando" #~ msgid "Paused" #~ msgstr "Em Pausa" #~ msgid "Finished" #~ msgstr "Terminado" #~ msgid "Gave up" #~ msgstr "Desistiu" #~ msgid "Unknown" #~ msgstr "Desconhecido" #~ msgid "%i minutes" #~ msgstr "%i minutos" sugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/po/SliderPuzzle.pot0000644000175000017500000001205210743343012026372 0ustar janijani# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2008-01-14 16:38+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" #: activity/activity.info:2 msgid "Slider Puzzle" msgstr "" #: SliderPuzzleActivity.py:157 #, python-format msgid "Buddy '%s' changed status: %s" msgstr "" #: SliderPuzzleActivity.py:170 msgid "Waiting for Puzzle image to be transferred..." msgstr "" #: SliderPuzzleActivity.py:339 #, python-format msgid "Buddy '%s' joined the game!" msgstr "" #: SliderPuzzleActivity.py:343 #, python-format msgid "Buddy '%s' left the game!" msgstr "" #: SliderPuzzleUI.py:214 msgid "Solve" msgstr "" #: SliderPuzzleUI.py:218 msgid "Shuffle" msgstr "" #: SliderPuzzleUI.py:222 msgid "My Picture" msgstr "" #: SliderPuzzleUI.py:259 msgid "Time: " msgstr "" #: SliderPuzzleUI.py:268 SliderPuzzleUI.py:566 msgid "Lesson Plans" msgstr "" #: SliderPuzzleUI.py:285 msgid "Waiting for remote game..." msgstr "" #: SliderPuzzleUI.py:329 msgid "Select image and press Start Game..." msgstr "" #: SliderPuzzleUI.py:333 msgid "Waiting for Puzzle image to be chosen..." msgstr "" #: SliderPuzzleUI.py:335 SliderPuzzleUI.py:344 msgid "Buddies" msgstr "" #: SliderPuzzleUI.py:362 msgid "Give Up" msgstr "" #: SliderPuzzleUI.py:364 msgid "Start Game" msgstr "" #: SliderPuzzleUI.py:374 msgid "Slider Puzzle Activity" msgstr "" #: SliderPuzzleUI.py:456 msgid "Puzzle Solved!" msgstr "" #: SliderPuzzleUI.py:459 msgid "Gave Up" msgstr "" #: SliderPuzzleUI.py:487 msgid "Choose a Subject" msgstr "" #: SliderPuzzleUI.py:569 msgid "Close Lesson" msgstr "" #: SliderPuzzleUI.py:633 msgid "Game Started!" msgstr "" #: i18n_misc_strings.py:1 msgid "Sea Life" msgstr "" #: i18n_misc_strings.py:2 msgid "Animals" msgstr "" #: i18n_misc_strings.py:3 msgid "Birds" msgstr "" #: i18n_misc_strings.py:4 msgid "XO" msgstr "" #: i18n_misc_strings.py:5 msgid "Sequencing Puzzles" msgstr "" #: i18n_misc_strings.py:6 msgid "Sports" msgstr "" #: i18n_misc_strings.py:7 msgid "Insects" msgstr "" #: i18n_misc_strings.py:8 msgid "Music" msgstr "" #: i18n_misc_strings.py:9 msgid "Space" msgstr "" #: i18n_misc_strings.py:10 msgid "Lesson 5" msgstr "" #: i18n_misc_strings.py:11 msgid "Lesson 4" msgstr "" #: i18n_misc_strings.py:12 msgid "Overview" msgstr "" #: i18n_misc_strings.py:13 msgid "Lesson 3" msgstr "" #: i18n_misc_strings.py:14 msgid "Lesson 7" msgstr "" #: i18n_misc_strings.py:15 msgid "Lesson 6" msgstr "" #: i18n_misc_strings.py:16 msgid "Lesson 1" msgstr "" #: i18n_misc_strings.py:17 msgid "Lesson 2" msgstr "" #: mmm_modules/buddy_panel.py:49 msgid "Buddy" msgstr "" #: mmm_modules/buddy_panel.py:55 msgid "Status" msgstr "" #: mmm_modules/buddy_panel.py:62 msgid "Play Time" msgstr "" #: mmm_modules/buddy_panel.py:69 msgid "Joined at" msgstr "" #: mmm_modules/buddy_panel.py:101 msgid "synchronizing" msgstr "" #: mmm_modules/buddy_panel.py:115 msgid "Playing" msgstr "" #: mmm_modules/buddy_panel.py:115 msgid "Paused" msgstr "" #: mmm_modules/buddy_panel.py:117 msgid "Finished" msgstr "" #: mmm_modules/buddy_panel.py:119 msgid "Gave up" msgstr "" #: mmm_modules/buddy_panel.py:121 msgid "Unknown" msgstr "" #: mmm_modules/buddy_panel.py:123 #, python-format msgid "%i minutes" msgstr "" #: mmm_modules/i18n.py:36 msgid "Chinese (simplified)" msgstr "" #: mmm_modules/i18n.py:37 msgid "Chinese (traditional)" msgstr "" #: mmm_modules/i18n.py:38 msgid "Czech" msgstr "" #: mmm_modules/i18n.py:39 msgid "Danish" msgstr "" #: mmm_modules/i18n.py:40 msgid "Dutch" msgstr "" #: mmm_modules/i18n.py:41 msgid "English" msgstr "" #: mmm_modules/i18n.py:42 msgid "English - Great Britain" msgstr "" #: mmm_modules/i18n.py:43 msgid "English - U.S." msgstr "" #: mmm_modules/i18n.py:44 msgid "Finnish" msgstr "" #: mmm_modules/i18n.py:45 msgid "French" msgstr "" #: mmm_modules/i18n.py:46 msgid "German" msgstr "" #: mmm_modules/i18n.py:47 msgid "Hungarian" msgstr "" #: mmm_modules/i18n.py:48 msgid "Italian" msgstr "" #: mmm_modules/i18n.py:49 msgid "Japanese" msgstr "" #: mmm_modules/i18n.py:50 msgid "Korean" msgstr "" #: mmm_modules/i18n.py:51 msgid "Norwegian" msgstr "" #: mmm_modules/i18n.py:52 msgid "Polish" msgstr "" #: mmm_modules/i18n.py:53 msgid "Portuguese" msgstr "" #: mmm_modules/i18n.py:54 msgid "Portuguese - Brazilian" msgstr "" #: mmm_modules/i18n.py:55 msgid "Russian" msgstr "" #: mmm_modules/i18n.py:56 msgid "Slovak" msgstr "" #: mmm_modules/i18n.py:57 msgid "Spanish" msgstr "" #: mmm_modules/i18n.py:58 msgid "Swedish" msgstr "" #: mmm_modules/i18n.py:59 msgid "Turkish" msgstr "" #: mmm_modules/image_category.py:215 msgid "Choose image" msgstr "" #: mmm_modules/image_category.py:226 msgid "Not a valid image file" msgstr "" sugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/NEWS0000644000175000017500000000122310743343012023271 0ustar janijani5 * Updated copyright information * Added AUTHORS file 4 * Updated lesson plans. * Changed the way NotebookReader uses abiword Canvas, making open document look consistent when opened multiple times. * Updated tube handling helper to match the new Presence API and removed local tubeconn.py. * Removed a little kungfu with soft links. This adds some files redundantly across our activities, but makes activities self contained. 3 * Better UI (fullscreen). * Runtime dependency on MaMaMediaMenu (Creative Center) removed. * New icon. * Many bugfixes. 2 * Mesh contest support * Journal integration * Sequencing puzzles * My own image (from journal) sugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/icons/0000755000175000017500000000000010755626243023724 5ustar janijanisugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/icons/logo.png0000644000175000017500000003603110716617376025401 0ustar janijaniPNG  IHDRHZo pHYsnu>tIME ;wU IDATxw|dWy7hԥ]J )&8 H>I C w4~yxVjOfn9{aYeY.P7 Xnb[dWZ-2rI]n} hiRSa#OmjvZe!Bi]`$wƿ}g&ƠpV)B9]ZvExX?oG$:pU][X].]^r3kD\^el3wYj 3`@fv4x80* c1N J9PZ4^;rl؝4".^pzJp%Pm \>%S扺ֲ`]9 3Lj "nKvgl(8&+*.Z]sA;S[ӝF&zM초yb+NɲKH- `Q"[rq*IcV`$:cA-/䲼¼ag:*ۼ4(fVDa*pO 2NF"xtbub):mӳ 02EZV_Mc֌E]UEI &V7j]12 ;wR7hS`O3tU쬢T&R sz~?]P~r0JoطzW4YvA֌=r;J+*}G\U$Ox1@6}(_rL69`6%P({e.Qh"#YSZRfyݳ:Zƅ27b2.W~MsljٖII?9ouwvʻkuM'TH\9sIک؏m0KBY*) C$}cWx"@&En jҦF$ESŲ3=i Ó\Y7rj]E?Z#HY9x֧\^o>nz|2'VӜG~qoC,ȣ<<{Sp]ǿ?<}d 1$?fd0"I(`5" %'xh>a,omv}/sM&зOO~K1m@X6z@V+rªLoW_wlOw𯆧`[c_?*iSvHG9 JXM&.̀g@yqMUs(44! C: &ef9FDQ @L%bq4elE,z.z`fS^2Єfoï>]gqf3.uG,_?;;oO3kIK,;à$WZHO,}tܿR5m>Lzoy)WSx'uk6u ZF/ G>4ߕf 2M6{LBTlvuJV[k?^TZ80ic/p$E^{ (I_?z΢Utt,;&'oD苽vE7\_wXt{g2XbO]K$gllޗyYQ*]91Ҟh!LE L`r70d0IB,6. M䇮ܟ27oa&C_ڽaΙcݎSln;oPo±v̿%w,T6)ArT=Yf[t2h߆=J5 K0x gCTʣ"{88tzQ BK\x\2EM,; "YժQKV7_ 9 `$r;fbĨG9f^+Soeg:;mW{;ݮid1J.`9l&h22qcc{亭j:2pr0{A*nޓP0E3a aXhZnuFWPEe9"_쒨4y[EӜ|XwEe\^x4a Ҩ y_oM.{u¦0Ô|zsG::~`^/A@Q4 ,*Ύz4f_Gc>4A:P)@Qjgrm(5g]@-tնmaW{Ô*C;ӈrNgΆ6F%|x ^GLJFUm}|:wNQ%jw{*j} BPU!r}(v=7O_[h(ʊ'%^]=k<:V*@e) 0 R5lŔH4]Z?ohx8%*}雤0L\v*c|7Zf"gݜf{L%_N`,jALG=I"gm&SўQ}K:mSk97Jؓ \JYDGp[苬v0k+@i~} E\ڝMl6ʭ #Z6t-()4m;ϦVGk~NhT1!|"׷:&at^% F_r8xa#,VL4*Ix>OUAxs׻WhvM?؄C.Oٙ3[Z4)Ϧ7.Ω¸>Z%|gW 5äxu9[R1H!S)X=RW7/YY(XO\E]xQ \nE4aX6'Sn9ByȩUR|9ckFIrzep>ZƕºlV-2s:*Ji+*3̢ĉOdMPU Oa7&Tu#75\mT<{(чh$@t[龱#wĕ6+phϦz0"vԅiJ]۩Z4O0ia M$}&NӃ35/\Bd2c˱Jyb2)蠇ܸ؏06!S8pf\+Jըjfz9`=ܽÝs]-]no?r- 81Q$mYMy!Ey%K`6HD|;:faY M[QŽ| }rrtOGF!--٫i*:<X,4E|9vjݺyLO{DOF"ܼhT4lH䎍H LDѥ%޲Ҷ}EIhi~,Ő]y2qHd_MSDdLWu}W\5IiDg5n Y+rAR5:U }?O~[ZZ]^v*;4g(,epk|M[*,xf󴭥Rpsi?t.=mX6dƚ\G\HT4?v3a՝:Ŝ.c|f`ལH4]6Ӽcr}}zsOM'4uc n;0abG[]T1h)4L|/pq]UmhtYVˉ|4dvcܵ#Bf뮻X,nޝ;5Q:Ok}jp1+MCUx:^Yw<%`E']\"&5AZ; CCC._>ߍU׉*3nI_/r. y\lcltw>@^|*ݮ*snxx*MgG| ZZN\n]S)}x{FFVTh0OMu9z$Q|bbHD',DPhׂ9L}By:),v]5 sɚMhXшVCswWaEYmv闞;񣅣C0@\Q3 P@ABLuiXVpyhnl!g xnh|SG :v-mRBVw: 3pY)&U9Vڪɣi5:-Kldsִ0ۋ s62g/O&y<'綐/rnTj!_uw? M)kV ι5amzR|i΂5k _+Wga -{^cW9)/oUe6;_:Pg`LWǣ/Q=:ٜ2IG|1 hXp/"y|ߏm҇WG<5̦D9cy@܂ib  !A7m!yJx湀^sK09n]O|Sp x iӤbɾ<Fjn<8˕ףt8R+OXU]o.gAW-j=`pk1(ْN[1ؖTT*:X y3ʡZY^hq./I3l <ޫY/e7+o=b7?у5~[o;Lo;3yŊ ﭩ %wJ8ml,9"벍g,bB,("r89S&V/g<^ 8Н1{6m2tZh %wK݁gAʗY(}.!O> -:a*>ح3ghB>voK$Re!siլ 5568s.=(5:#+vIs-N;Cc1(vGMNQGffK!YgSFsbs@o6vm:U>01vV~P״gcܿ:ܑOo`kw؂ !!gݻ>Ry/\.ShC;H4w,`B0ƪ I*NӆMsq(Q_4u\"EYlIn MWJ;@̍sRI0bO. INðx0*~ ,sU& ֯Ê3X2U5!v$s`M^ 4-E b,烊6  b\36à 194Mmͧ6CK٩ƞ<*'Ms㾳jd. ,2G:H\?3 sb5UG*|(bW'm\Bv1;2Cwe8]ϝ!5MTP*drtGHS UҊrs&qzK{T$I:BV 93E^b~XS2&q `,;u#1D$ɣiŢE]4}\V}&ϲY,ws,\a蚳,P/ N=i\ kD+'OVèśfs96]F~3bF,$]ܺ=WItZWh/J,DhWe)7n"B06M˲,q$Nl͖$I=Cw7RgJLKگm6ijWf˴rqyH=\%7šs% lL~L8eYTG7u͜oYa1{4L9wH6e~[^?7W_{DrG^ 9U,Vͱ=svU{ 鉟=/B}Ø(c7TQcv\2r-@)|\;=9 7skT9 Cq 0 ϫ{QG+ghg 69 4Ek<2#+aEf a61 @ i-f׶ֹ|sӚjL*:66^R Rbt"ЀәUteA{<> ْz5}<icc%EǣR\7;[il9O>IS XIdβUāPbXb%J^R=#PRUᢐU(TJEʕ\_H3Ls3=X#@Lwsh]=W([2g3FT|餰sUsvݾ pg "?1NW,& \.RGQx7&w9 6őLO;Ec-[[Ŏh2bÅt2Mp'Z^;Mwg˼A"b+nᰲ5O@*7YhŢø'l9i"kq++1ѳs8n鴺tzϣ4\fqKJRTl<[lR[e5#CHŏ ZY.9G 3\j^Ō6Pؠiʦuz ,[sd,ؼlbS\.'KXRP[rq&&=,k5n M_o-JOŠ8UK3q,muO9Y K s*v>Ս&Bzտ> ZWs 9kc9)QZ迺KKyfw ֪\ܘ-1̉v}BUc1CqfX즙ff.K&VUB ۣi7/<‰^꺐0*;Rk%SVf[SpqS8S[6u}sk7w qf%)Vўݮ;YCdR9';}M79͠tL$DiL Ð$)HC#Tռ "Pc2'vXLpmϑɩL%ĺDFO' n(gso+6f2960Tb"n*`pw 浉DganGh%T]HXnDe-1LDQ>:4ty*5/Le iګibqs&c![K 40,y8=r9ux|EfU\.OIQ6lb ѝOl9ućFF*hISe<)ekIDAT(2t_k'φB[e"C|XB0yFGﻺb8p9ҵ0>7^ɬd`pA}>+8 )1~ dx<Ɂ(9kPTe1BVTϝ#lK$%:EzU6(]]:|-V9t(&<Ɓ*u4ZmoѣΉ?ijN!mI[M<]08؝g{npl6(`F_U)`pUkqMHiQu7\N[I!H$qN'^]'b{-./j~}Pբ NnX5,76{T.km _XVLl@Yg5BjP Ka}jw) 0ؔdѐkjuu6W7裏~K>}hwWJޖ d9ˏ\]61*zY]zv4/n\ Gol^p}D2^~ CTvac!OEFW1!<(B`mr޳L`lz=h'W]^~_ςmsSǖ{>ey]'nUazz֏1 oq\ɏQ,"aTf(D# :1)2KW^v͚O>/&8knbcI=.NSs,˛ 9ʞɡw|#ґK>.%NGC;l^dufy@]EZ0C EL( 4FjVS#XCK7 SÇ#Gq(on}}j\JEžZ~ Ȳِi WYvM/k7tڋMRBNT4b'_8D~w)FvbMm!,Ea)iX/zǎ<]*,r`[Zo/ S*8 -RQ2 є9t˞=wV-jㅙ)$ )qIe$ 3iB^L Ys.>w]g KPoӻ_^73&=O۳?$9U{`C؜g W􌸬FڹPM >kM68&{&\A|J&.eHPk0oȽ]W\8i$ѾUqp'p`}g 3_wFұ`~OD|$>eACu:b}H=ѪN-Uzz5uʨ:, Dzx_FӾiw5#Z4K+O" Oj0ӭ>9-rN]邝m6lQMwMT,}zdnM}6hgBqi* ظĂw/$=Ďz/E>Zt$Z{cTTF|ۮv|iw;:kOek UA6Vkgv)գmx)˂I(+lw<"Rd5 @ ,26{sumC-A"mdX%&o/7U`ұSfYJt~eʹ38%Mꔳ20!ZDOĎe\@bq}QlC7u3[[cW2ѹf!`G_61 (c rBaud THJN<uԹ憕m-@"˘hNLDϔ畻DZL #+z2ʚ}>Hu#x86)guN9)d%FOA{sڷt,ze g(2S<>P}([{::_(hdv6}rX T^BXfx͢b{>,,=o^@Y vnI7+R>U?#sic_DF!fC[[y(07fS»;׶ ψ D63BURl $nPLa" &S7R{ggAߢWr -1go"cJrRl/zy J^ 9oi|Yb&9oj@<ػsN\֛6"y}S'j8i le4]˙Ğ.qDmk̐I1CiM r1+A->~_D*[-dY*F{KrjUѕm[{;zfgeMԄ~S&E[s+G]8=Ro EC#5-45Z[iW1L:'n =niiܳ˧'՝iWQVhjoҠ7YSe /"ZnP+SE|+ɒΆڻO:zh7RO fdv6DrUArkٝ dzd&2sn\Ty*ln/vR}ih!cf4H g(xeWuhm`klb%l-ͻ[۲vï#$xc^:ԕzrjᰟ>;[*|tu'ZA'MPg2V0КT/Wr@t,Xv,d/ ݠ'P].4tv2 kTDXҠwQ|y-S&Ed3Gphn?4#)H׮ODq~/x\'al.5~dg5)9nC{$ }3>ŹBP܀0̪?*=s#xiyjLF]'Ǿ|S֕9_xw.^TDO=,ڞ6*_rdmZM :m `3(B`i&x>- ֽw,${BMEjn/¯^MOOиEFClQ/G[NLj#/5KP!!,ew6~~XG +3\yEHuLr.ZQ=m e|&mXxL(L`Q Ս=IE"yc:{DjadZǺ -pr艷]>OvJ^=ͺi$B r ͫC&!ZdU9bʯPܬ_ΑX,7Enza5@:Ipf0}B%7xD%ݹ\qlKɱhhy|4T~O1X5ʡqwڳM_3O0S<FKFu~2<ՃaPfNERNw@lӇwkWPcbH{W''KZaLS@7[ 5Jy'KvZ>$3v똁[Sf=Uy#ZԫZٝ Ҡl*&E:wl<^]#5~U-mttPn10a|_~NyMZ`Ȅϱ?_ば!:՛ $<4, 4ՙ*VVO n]·Ѳܝ)3/Fq*޸6]p:hMt"G`061'&;n0% d4d" X EA<<PAcS`)J2v7gPD |llXsy孄17Dxځe ErkjDUPdL'14H硡&Hl.m"Ѡ(!R ȰUytR?I"@@Ht#wM.-/`*.aD wƖJg#I hjpjsu'7+nɖ٤kSf.B ^~粼uи&gb0@7qGvp89NϿGP@ 4 չ2(3A%&Ni&Pe<0_hM@E*6eS޲,o!8KjvK :k2T*C5'ctGf!f0P.2==6~6'SqNӱvO: |]X^eyk !RΦ,gPEf QeawqkPAGX:5Ddt"$E. ]IWzY2q Y/98gDS"BNQ#EfcH*$24adJ`h\9KhR.N\ٶz0 wIENDB`sugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/mamamedia_modules.py0000644000175000017500000000325510743343012026616 0ustar janijani# Copyright 2007 World Wide Workshop Foundation # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # # If you find this activity useful or end up using parts of it in one of your # own creations we would love to hear from you at info@WorldWideWorkshop.org ! # import os import sys cwd = os.path.split(__file__)[0] import gtk theme = gtk.icon_theme_get_default() if os.path.exists(os.path.join(cwd, 'mmm_modules')): # We are self contained theme.append_search_path(os.path.join(cwd, 'mamamedia_icons')) pass else: # Working with shared code on MaMaMediaMenu propfile = os.path.expanduser("~/.sugar/default/org.worldwideworkshop.olpc.MMMPath") if os.path.exists(propfile): mmmpath = file(propfile, 'rb').read() else: mmmpath=os.path.normpath(os.path.join(cwd, '..', 'MaMaMediaMenu.activity')) #print ("MMMPath", mmmpath) sys.path.append(mmmpath) theme.append_search_path(os.path.join(mmmpath, 'icons')) from mmm_modules import * if __name__ == '__main__': gather_other_translations() sugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/lessons/0000755000175000017500000000000010755626243024277 5ustar janijanisugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/lessons/Lesson 1/0000755000175000017500000000000010755626243025663 5ustar janijanisugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/lessons/Lesson 1/default.abw0000644000175000017500000003725610716617376030023 0ustar janijani application/x-abiword AbiWord

Slider Puzzle Lesson 1: Strategic thinking with Slider Puzzle

From the Home screen of your XO, click on the Slider Puzzle icon. You can also open the Slider Puzzle activity from the MaMaMedia Activity Center.

Click on and explore the puzzle image subject list on the right, then click to choose one image to solve.

Explore how the puzzle works. Click on a tile with the mouse to move it into the vacant square. Note that you can move the tiles up, down, right and left, but you cannot lift them off the board.

Change the number of squares from 9 to 12 to 16. Observe how the game becomes more challenging when you select more squares.

Click on “Shuffle” to mix the tiles up in a new way. Click on Solve to see the picture in its complete state.

Work in pairs or independently to solve a 9-tile puzzle. If you solve your puzzle quickly, try solving one with 12 or 16 tiles. Walk around and help other students who are still solving their puzzles.

After playing with the puzzle for a while, write down some of your problem-solving strategies or questions.

Discuss each person’s strategies and questions as a group. Identify what strategies worked and what didn’t work. Discuss the things you found difficult or frustrating.

Create charts with shared experiences, differences and similarities. One student can record all the students’ ideas on the XO Laptop.

sugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/lessons/Lesson 1/_es.abw0000644000175000017500000003504510716617376027137 0ustar janijani application/x-abiword AbiWord

Slider Puzzle Lección Nº1: Pensamiento estratégico con Rompecabezas Deslizantes

Partiendo de la vista del Hogar de la XO, haga clic en el icono de Slider Puzzle.

Haga clic y explore las imágenes de los rompecabezas que se muestran a la derecha, escoja una imagen para resolver.

Explore como funciona el rompecabezas. Haga clic con el ratón sobre una pieza para deslizarla al espacio vacío. Las piezas se pueden deslizar hacia arriba, abajo, derecha o izquierda; pero no pueden ser 'levantadas' del tablero.

Se puede cambiar la cantidad de cuadrados de 9 a 12 a 16. El juego se hace más desafiante a medida que hay más cuadrados.

Haga clic en «Mezclar» para desordenar las piezas. Haga clic en «Solución» para ver la imagen resuelta.

Trabaje en pares o solo para resolver un rompecabezas de 9 piezas. Si es resuelto rápidamente, se puede intentar resolver con 12 o 16 piezas. Da una vuelta y ayude a otros compañeros que todavía se encuentran resolviendo sus rompecabezas.

Despues de jugar un tiempo con el rompecabezas, anote algunas de las estrategias utilizadas o preguntas.

Discuta las estrategias de cada persona y sus preguntas en grupo. Identifique que estrategias funcionaron y cuales no. Discuta las cosas que fueron difíciles o frustrantes.

Arme un gráfico con las experiencias comunes, diferencias y similitudes. Un alumno puede anotar todas las ideas en su laptop XO.

sugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/lessons/Lesson 1/_pt.abw0000644000175000017500000004041210716617376027145 0ustar janijani application/x-abiword AbiWord

Slider Puzzle, Lição 1: Pensamento estratégico com Quebra-Cabeças Deslizante

A partir da tela inicial do XO, clique no ícone Slider Puzzle.

Clique e explore as imagens dos quebra-cabeças mostrados à direita, e clique para escolher uma imagem a resolver.

Explore como funciona o quebra-cabeças. Clique numa peça para deslizá-la para um espaço vazio. Note que se pode mover as peças para cima, para baixo, para a direita e para a esquerda, mas não se pode levantá-las do tabuleiro.

Mude a quantidade de quadrados de 9 para 12 e para 16. Observe como o jogo se torna mais desafiador quando se escolhe um número maior de quadrados.

Clique em «Embaralhar» para misturar as peças. Clique em «Solução» para ver a imagem em seu estado completo, resolvido.

Trabalhe em pares ou independentemente para resolver um quebra-cabecas de 9 peças. Se for resolvido rapidamente, tente resolver um com 12 ou 16 peças. Dê uma volta e ajude outros colegas que ainda estão resolvendo seus quebra-cabeças.

Depois de ter jogado com o quebra-cabeças por um tempo, escreva algumas de suas questões ou estratégias usadas para resolver o problema.

Discuta em grupo as estratégias e questões de cada um. Identifique quais estratégias funcionaram e quais não. Discuta as coisas que foram consideradas difíceis ou frustrantes.

Crie gráficos a partir das experiências comuns, das diferenças e das semelhanças. Um aluno pode registrar todas as idéias em seu XO.

sugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/lessons/Lesson 2/0000755000175000017500000000000010755626243025664 5ustar janijanisugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/lessons/Lesson 2/default.abw0000644000175000017500000001706110716617376030014 0ustar janijani application/x-abiword AbiWord

Slider Puzzle Lesson 2: Puzzle-Solving Contest (Team work activity)

Working in teams of 2-3 people, try to solve a 9-tile Slider Puzzle in the fastest time. Each team must select the same image, and click on it at the same time (Count: “3, 2, 1, GO!”). The timer indicates who finishes first.

The winning team should share their strategies with the class. Each team member should say one thing about how they solved the puzzle quickly and worked together.

Other students should describe their strategies too. Encourage everyone to name one way their puzzle solving skills have improved since the first time they played.

Repeat the contest with a 12 and 16 tile puzzle. Allow the winner of the preceding round to choose the puzzle image. Does the strategy change when there are more puzzle tiles to move? How?

sugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/lessons/Lesson 2/_es.abw0000644000175000017500000002315710716617376027141 0ustar janijani application/x-abiword AbiWord

Slider Puzzle Lección Nº2:

Competencia de Armado de Rompecabezas (actividad por equipos)

Trabajando en equipos de 2-3 personas, intenten resolver un Rompecabezas Deslizable de 9-piezas lo más rápido posible. Todos los equipos deben usar la misma imagen, y comenzar al mismo tiempo (Cuente: «3, 2, 1, YA!»). El cronómetro indica quien termina primero.

El equipo ganador debe compartir sus estrategias con la clase. Cada miembro del equipo debe decir una cosa sobre como resolvio el rompecabezas rápidamente y el trabajo en conjunto.

Los otros alumnos también deberían describir sus estrategias. Incite a todos a mencionar una manera que sus habilidades con los rompecabezas han mejorado desde la primera vez que lo jugaron.

Repita la competencia con 12 y 16 piezas. Permita al equipo ganador de la ronda previa elegir la imagen siguiente. ¿Cambia la estrategia con más piezas para mover? ¿Cómo?

sugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/lessons/Lesson 2/_pt.abw0000644000175000017500000002346010716617376027152 0ustar janijani application/x-abiword AbiWord

Slider Puzzle Lição 2:

Competição de Soluções de Quebra-Cabeças (atividade por equipe)

Trabalhando em equipes de 2-3 pessoas, tente resolver um Quebra-Cabeças Deslizante de 9 peças no menor tempo. Cada equipe deve selecionar a mesma imagem e clicar ao mesmo tempo (Conte: “ 3, 2, 1, JÁ! ”). O cronômetro indica quem termina primeiro.

A equipe vencedora deve compartilhar suas estratégias com a classe. Cada membro de equipe deve dizer uma coisa sobre como resolveu rapidamente o quebra-cabeças e sobre o trabalho em conjunto.

Os outros alunos também devem descrever suas estratégias. Estimule a todos a relatar de que maneira suas habilidades com os quebra-cabeças melhoraram desde a primeira vez que jogaram.

Repita a competição com quebra-cabeças de 12 e de 16 peças. Permita que a equipe vencedora da rodada anterior escolha a imagem. A estratégia muda quando há mais peças a mover? Como?

sugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/lessons/Lesson 3/0000755000175000017500000000000010755626243025665 5ustar janijanisugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/lessons/Lesson 3/default.abw0000644000175000017500000002625110716617376030016 0ustar janijani application/x-abiword AbiWord

Slider Puzzle Lesson 3: “My Picture” (Conveying original ideas)

From the Home screen of your XO, click on the “Paint” program.

Explore how the Paint activity works. Play and experiment with all the fun features (brushes, bucket, spray, different colors, etc.)

Create a picture that you would like to turn into a Slider puzzle. Save it as “sliderpuzzle1” and close Paint.

Open the Slider Puzzle and click on the “My Picture” button to find your “sliderpuzzle1” image. A window will open that shows the contents in your Journal -- look for “sliderpuzzle1” and click on it. Then click the “OK” button. The Journal window will close and your image will appear in the Slider Puzzle.

Play with your puzzle. Could you solve it? What made it hard or easy to solve? Switch laptops with a friend and try to solve one of their original puzzle images.

Share your experiences as a group: What makes an image easy or difficult to solve as a puzzle? Which strategies were helpful? One student should record this conversation on their XO Laptop using the “Write” program.

Now try creating a puzzle picture using the Record activity. Take a photo and save it as “sliderpuzzle2” and close Record. Go back to Slider Puzzle and open the new image from “My Picture” as before, then play with it.

sugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/lessons/Lesson 3/_es.abw0000644000175000017500000003533310716617376027141 0ustar janijani application/x-abiword AbiWord

Rompecabezas Deslizante Lección Nº3: «Mi Propia Imagen» (Transmitiendo ideas originales)

De la vista del Hogar en su XO, hacer clic en la actividad de «Pintar».

Explore como funciona la actividad de Pintar. Juegue y experimente con todas las funciones (pinceles, baldes, aerosol, colores, etc.)

Pinte una imagen que desee convertir en un Rompecabezas Deslizante. Guárdelo como «rompecabezas1» y cierre Pintar.

Abra el Rompecabezas Deslizante.

Haga clic sobre el botón «Mi Propia Imagen» para buscar la imagen «rompecabezas1». Una ventana se abrirá para poder buscar y seleccionar la imagen—encuentre «rompecabezas1» y haga clic sobre ella, seguido por un clic en el botón de «OK». La ventana se cerrará y la imagen aparecerá en el Rompecabezas Deslizante.

Juege con su Rompecabezas. ¿Se pudo resolver? ¿Qué lo hizo fácil o difícil de resolver? Intercambie laptops con un compañero y pruebe de resolver su imágen.

Comparta las experiencias como grupo: ¿Qué hace difícil o fácil resolver un rompecabezas? ¿Qué estrategias fueron útiles? Un alumno debe registrar la conversación usando la actividad de Escribir en su laptop.

Ahora intente crear un rompecabezas usando una foto de la Cámara. Tome una foto y guárdela como «rompecabezas2», cerrando la Cámara al finalizar. Vuelva al Rompecabezas Deslizante y abra la nueva imagen con «Mi Propia Imagen» como antes y juegue con ella.

sugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/lessons/Lesson 4/0000755000175000017500000000000010755626243025666 5ustar janijanisugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/lessons/Lesson 4/default.abw0000644000175000017500000002741510716617376030022 0ustar janijani application/x-abiword AbiWord

Slider Puzzle Lesson 4:

“Animals” (Independent Study Project example)

Pick a theme or subject you want to study, such as Animals. (Some other ideas might be: family, historical figures, planets, health, nutrition, home, country, or maps.)

Use “Paint” to draw a picture of a favorite animal or use “Record” to take a picture of an animal you see everyday.

Put your animal image in the Slider Puzzle.

Use the “Write” activity on your XO to make a list of questions about the animal such as: What does it eat? Where does it live? How does it make babies?

Try to answer the questions you wrote down about the animal. Use the Internet and books. Ask other students and grown ups what they know about the animal.

Present your picture and some facts you learned about the animal to your class. Explain why you chose this animal and how you got information about it. Talk about how you created the image with Paint or Record.

Discuss any challenges you had in researching your animal.

Have a class volunteer write down a list of these challenges on the XO or the classroom wall, adding to it after each student talks about their animal.

Think together about different ways to find answers to the questions.

Try solving each other’s Animal Slider Puzzles.

sugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/lessons/Lesson 4/_es.abw0000644000175000017500000004220510716617376027136 0ustar janijani application/x-abiword AbiWord

Rompecabezas Deslizante Lección Nº4:

«Animales» (ejemplo de Proyecto de Estudio Independiente)

Elija un tema o materia que se quiera estudiar, por ejemplo Animales. (Otras ideas pueden ser: la familia, personajes históricos, los planetas, la salud, la nutrición, el hogar, el país, o mapas).

Utilice «Pintar» para dibujar una imágen de su animal favorito o use la «Record» para sacar una foto de un animal que se vea todos los días.

Ponga la imágen del animal en el Rompecabezas Deslizante.

Utilice la actividad de «Escribir» en su XO para hacer una lista de preguntas sobre el animal tales como: ¿Qué come? ¿Dónde vive? ¿Cómo tiene crías?

Intente responder las preguntas que se hizo sobre el animal. Utilice Internet y libros. Pregunte a otros compañeros y mayores que saben de dicho animal.

Presente la imágen y algunos de los datos aprendidos sobre el animal a la clase. Explique porque se eligió dicho animal y como se obtuvo la información acerca de él. Mencione como se creó el dibujo con Pintar o se sacó la foto con Record.

Discuta algún desafío que se tuvo mientras se investigaba sobre el animal.

Que un voluntario anote la lista de desafíos en su XO o el pizarrón, agregando a ella cada vez que un compañero habla sobre su animal.

Debatir en grupo sobre las diferentes formas de encontrar respuestas a las preguntas.

Intenten resolver los Rompecabezas Deslizantes de Animales de los compañeros.

sugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/lessons/Lesson 4/_pt.abw0000644000175000017500000004221610716617376027154 0ustar janijani application/x-abiword AbiWord

Quebra-Cabeças Deslizante - Aula 4: “Animais” (exemplo de projeto de estudo independente)

Escolha um tema ou assunto que você deseja estudar, por exemplo, Animais. (Algumas outras idéias poderiam ser: família, personagens históricas, planetas, saúde, nutrição, lar, país ou mapas).

Use “Pintar” para desenhar uma imagem de seu animal favorito ou use a “Record” para tirar uma foto de um animal que você veja todo dia.

Ponha a imagem do animal no Quebra-Cabeças Deslizante.

Use a atividade “Escrever” de seu XO para compor uma lista de perguntas sobre o animal, tais como: O que ele come? Onde ele vive? Como se reproduz?

Tente responder às perguntas que você escreveu sobre o animal. Use a internet e livros. Pergunte a outros colegas e alunos mais velhos o que sabem sobre o animal.

Faça uma apresentação para sua classe — da imagem e de alguns fatos que você aprendeu sobre o animal. Explique porque escolheu o animal e como obteve as informações sobre ele. Fale sobre como você criou a imagem com a atividade Pintar ou como tirou a foto com a Record.

Discuta sobre os desafios que teve ao pesquisar sobre o animal.

Consiga um voluntário para anotar a lista de desafios no XO ou no quadro, adicionando a ela o que cada aluno fala sobre seu respectivo animal.

Discuta em grupo sobre as diferentes formas de encontrar respostas para as perguntas.

Tentem resolver os Quebra-Cabeças Deslizantes de cada colega.

sugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/lessons/Lesson 5/0000755000175000017500000000000010755626243025667 5ustar janijanisugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/lessons/Lesson 5/default.abw0000644000175000017500000004446710716617376030031 0ustar janijani application/x-abiword AbiWord

Slider Puzzle Lesson 5:

“Our Flag” (Group learning project example)

Skills:

Learn about your country’s flag, what it represents, and how it fits into your country’s history.

Understand what symbols are and the function they serve.

Learn how to brainstorm.

Practice discussing thoughts and ideas.

Find answers through discussion and research.

Activity:

Examine the flag of your country. What does it mean to you? How does it make you feel? Discuss why a country has a flag. Record your ideas on your XO and if possible, post somewhere in the classroom.

Make a list of the symbols, pictures, colors and/or writing on your country’s flag. Discuss what the symbols stand for (for example, the 50 stars on the American Flag represent the 50 states that are in the United States). Add these ideas on your XO too.

In small groups, brainstorm (think together) about what these symbols mean. Why did the creators of the flag choose these symbols? What are some other symbols of your country? If you were designing the flag today, would symbols would you put on it?

As a class, share what each group discussed. Explain the history of your native country’s flag and what the symbols actually mean. Share your ideas about other symbols of your country.

Create a picture of your country’s flag using “Paint” and save it.

Open your Flag image in the Slider Puzzle.

Solve the FLAG Slider Puzzles that have been created.

sugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/lessons/Lesson 5/_es.abw0000644000175000017500000004560210716617376027143 0ustar janijani application/x-abiword AbiWord

Slider Puzzle Lesson 5: “Our Flag” (Group learning project example)

Habilidades:

Aprender sobre la bandera de su país, lo que representa, y como encaja en la historia nacional.

Comprender que son los símbolos y la función a la que sirven.

Aprender a 'pensar libremente' (brainstorm)

Practicar la discusión de conceptos e ideas.

Encontrar respuestas por medio de la discusión e investigación.

Actividad:

Examine la bandera de su país. ¿Qué simboliza par uno? ¿Qué sentimientos despierta? Discuta por que un país tiene una bandera. Anote sus ideas en su XO y de ser posible, en algún lugar del aula/clase/salón.

Haga una lista con los símbolos, imágenes, colores y/o lemas en la bandera del país. Discuta el significado de los símbolos (por ejemplo, las 50 estrellas de la bandera de EE.UU. representa cada uno de sus estados). Anote estas ideas en la XO también.

En grupos reducidos, 'piensen libremente' (brainstorm) sobre el significado de los símbolos. ¿Porqué los creadores de la bandera los eligieron? ¿Qué otros símbolos tiene el país? Si se estuviera diseñando la bandera hoy, ¿qué símbolos le pondrían?

Como clase, compartan lo que cada grupo discutió. Explique la historia de la bandera nacional y el significado real de sus símbolos. Intercambien ideas sobre otros símbolos nacionales.

Haga un dibujo de la bandera nacional usando «Pintar» y guárdela.

Abra la imagen de la bandera en el Rompecabezas Deslizante.

Resuelva el rompecabezas recién creado.

sugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/lessons/Lesson 6/0000755000175000017500000000000010755626243025670 5ustar janijanisugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/lessons/Lesson 6/default.abw0000644000175000017500000004022410716617376030015 0ustar janijani application/x-abiword AbiWord

Slider Puzzle Lesson 6: Create Your Own Flag

Skills:

Understand the purpose of a flag.

Reflect and think about individual characteristics.

Come up with symbols to represent these characteristics.

Practice presenting individual ideas to others.

Create an image using skills previously learned on the computer.

Build a newly created image on the Slider Puzzle.

Activity:

Using the “Paint” activity, design your own flag that symbolizes YOU. Place objects, symbols, colors and designs that are meaningful and representative of YOU. If you have difficulty coming up with ideas, talk to other students, they might help to spark ideas in your imagination.

Share your own personal flag with the class and explain the symbols you included on it. (For example, one girl’s flag might have many hearts because she has a lot of love for the people around her; another boy might have pictures of books because he love to read).

Put your newly created flag into the Slider Puzzle.

Walk around and solve each other’s puzzles.

sugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/lessons/Lesson 6/_es.abw0000644000175000017500000004047710716617376027151 0ustar janijani application/x-abiword AbiWord

Slider Puzzle Lesson 6: Create Your Own Flag

Habilidades:

Comprender el propósito de una bandera.

Reflexionar y pensar sobre las características individuales.

Encontrar símbolos que representen dichas características.

Practicar la presentación de ideas a otros.

Crear una imagen usando habilidades previamente aprendidas en la computadora.

Armar una nueva imagen en el Rompecabezas Deslizante.

Actividad:

Usando la actividad de «Pintar», diseñar una bandera que los simbolice a UNO. Ponga objetos, símbolos, colores y diseños que tienen significado y son representativos de UNO. Si se hace difícil encontrar ideas, charle con sus compañeros, que seguro tienen ideas que puedan liberar la imaginación.

Comparta su bandera personal con el resto de la clase y explique los símbolos usados en ella. (Por ejemplo, la bandera de una chica puede tener muchos corazones ya que tiene mucho amor para brindar a sus compañeros; otro chico puede tener libros porque le gusta mucho leer).

Ponga la nueva bandera en el Rompecabezas Deslizable.

Pasee resolviendo los rompecabezas de los compañeros.

sugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/lessons/Lesson 6/_pt.abw0000644000175000017500000004044110716617376027154 0ustar janijani application/x-abiword AbiWord

Slider Puzzle Lição 6: Crie Sua Própria Bandeira

Habilidades:

Compreender o propósito de uma bandeira.

Refletir e pensar sobre as características individuais.

Encontrar símbolos que representem essas características.

Praticar a apresentação de idéias individuais para outros.

Criar uma imagem, usando habilidades previamente aprendidas com o computador.

Construir uma nova imagem no Quebra-Cabeças Deslizante.

Atividade:

Usando a atividade “Pintar”, desenhe sua própria bandeira que simbolize VOCÊ. Coloque objetos, símbolos, cores e desenhos que sejam significativos e representativos de VOCÊ. Se você tem dificuldade em ter idéias, converse com outros alunos; eles podem ajudá-lo a estimular sua imaginação.

Compartilhe sua bandeira pessoal com a classe e explique os símbolos que você incluiu nela. (Por exemplo, a bandeira de uma menina pode ter muitos corações porque ela tem muito amor pelas pessoas ao seu redor; um outro menino pode ter imagens de livros porque ele gosta muito de ler).

Ponha a nova bandeira no Quebra-Cabeças Deslizante.

Dê uma volta e resolva os quebra-cabeças dos colegas.

sugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/lessons/Lesson 7/0000755000175000017500000000000010755626243025671 5ustar janijanisugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/lessons/Lesson 7/default.abw0000644000175000017500000004202410716617376030016 0ustar janijani application/x-abiword AbiWord

Slider Puzzle Lesson 7:

The n-puzzle (Mathematical Patterns and Sequences)

The n-puzzle is general name for a slider puzzle that consists of a grid of numbered squares with one square missing, and the numbers out of sequence. The 9-puzzle is a 3×3 numbered grid, the 16 puzzle is a 4×4 numbered grid. The goal of the n-puzzle is put the scrambled numbers back in sequence.

The n-puzzle is a classical problem for modeling repeatable steps (or “algorithms”) involving mathematical patterns (or “heuristics.”) For example, you can begin by counting the number of misplaced tiles as you formulate a strategy for solving the puzzle. The n-puzzle also helps students to understand that some tile arrangements are unsolvable.

Skills:

Recognize patterns.

Practice classification and grouping.

Practice sequencing.

Put numbers in order.

Activity:

Start the Slider Puzzle activity and choose the category labeled “Sequencing.” Sequencing is when you put things into a logical order.

When the first image comes up, think how this image is set up differently from the one on the Slider Puzzle. The Slider Puzzle creates a large image, where all the squares are pieces of the larger image, while the Sequencing image contains a number on each tile.

Try to solve the 9-tile puzzle first. Try to put the numbers in order from smallest to largest. Model for other students how to slide the keys and place them in order.

Once you are able to solve the 9-puzzle, share your strategies with the class. How is this different from the Slider Puzzles where you are assembling a picture?

Now try to solve the 16-puzzle. How is this harder or easier?

After completing the 16-puzzle, walk around and help those who are having trouble.

sugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/lessons/Lesson 7/_es.abw0000644000175000017500000004555610716617376027155 0ustar janijani application/x-abiword AbiWord

Rompecabezas Deslizante Lección Nº7:

El rompecabezas-n (Patrones y Series Matemáticas)

El rompecabezas-n es un nombre genérico para un rompecabezas deslizante que consiste en una grilla con números y una pieza faltante, estando los números desordeandos. Un rompecabezas-9 es una grilla de 3x3, el rompecabezas-16 es una grilla numerada de 4x4. El objetivo es ordenar los números.

El rompecabezas-n es un clásico problema para modelar pasos repetibles (o «algorítmos») que involucran patrones matemáticos (o «heurísticas»). Por ejemplo, se puede comenzar contandon la cantidad de piezas o números fuera de lugar al mismo tiempo que se formula la estrategia para resovler el rompecabezas. El rompecabezas-n también ayuda a los alumnos entender que algunas disposiciones no tienen solución.

Habilidades:

Reconocimiento de patrones

Practicar la clasificación y agrupamiento.

Practicar series.

Ordenar números.

Actividad:

Inicie el Rompecabezas Deslizable y elija la categoría llamada «Secuencias». El secuencionamiento es cuando se ponen las cosas en un órden lógico.

Cuando aparezca la primera imagen, vea como esta imagen difiere del Rompecabezas Deslizable. El Rompecabezas Deslizable crea una gran imagen, donde cada pieza es una parte de la imagen completa, mientras que en Secuencias la imagen sólo contiene un número en cada pieza.

Intente resolver el rompecabezas-9 primero. Intente ordenar los números de menor a mayor. Muestre a los chicos como deslizar las piezas y ponerlas en orden.

Una vez resuelto el rompecabezas-9, comparta sus estrategias con la clase. ¿Cómo difiere del Rompecabezas Deslizable cuando se estaba armando la imagen?

Ahora intente resolver el rompecabezas-16. ¿En qué es más fácil o difícil?

Tras completar el rompecabezas-16, pasee y ayude a los que todavía encuentran dificultades.

sugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/lessons/0Overview/0000755000175000017500000000000010755626243026165 5ustar janijanisugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/lessons/0Overview/default.abw0000644000175000017500000003122010716617376030306 0ustar janijani application/x-abiword AbiWord

Slider Puzzle: Lesson Plans Overview

A slider puzzle is a classic logic game that challenges a player to slide tiles on a board to form a picture or pattern. You may not lift any tile off the board; you can only slide a tile up, down, right or left. You must use strategy and logic to find a sequence of moves that will allow you to unscramble the tiles and solve the puzzle.

This digital Slider Puzzle provides a fun context for young learners (and beginning XO users) to explore basic functions of the XO Laptop, learn individual and collaborative problem-solving skills, and develop creative projects that reflect an understanding of curriculum they are studying.

Throughout the school year, the Slider Puzzle activity can be integrated into different subject areas (i.e. geography, math, creative writing). Students can make puzzle images relating to a subject the class is studying, and share them with peers. In the process they will also learn how to use and integrate the output from activiites like Paint and Record, and how to collaborate over the Mesh.

Skills:

Practice using logic and strategic thinking to solve a problem.

Practice visual comparison and problem solving skills.

Practice discussing thought processes around problem solving.

Learn to explain ideas, thought processes and strategies to peers.

Learn from classmates.

Learn how to use specific programs of the XO Laptop.

Learn how to use the Paint activity with a game.

Learn to work together on a project.

Learn to express ideas you are studying through an original project.

sugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/lessons/0Overview/_es.abw0000644000175000017500000004216410716617376027441 0ustar janijani application/x-abiword AbiWord

Slider Puzzle:Plan General de las Lecciones

Un 'rompecabezas deslizante' (slider puzzle) es un clásico juego de lógica que invita al jugador a deslizar las piezas sobre un tablero para formar una imagen o patrón. No se pueden levantar las piezas del tablero; sólo se pueden deslizar hacia arriba, abajo, derecha o izquierda. Se debe utilizar la estrategia y la lógica para encontrar la secuencia de movimientos que permitan ordenar las piezas y resolver el rompecabezas.

Este rompecabezas deslizante digital provee un marco entretenido para los jóvenes (y usuarios principiantes de la XO) para explorar las funcionalidades básicas de la XO, aprender de forma individual y grupal para resolver problemas, y desarrollar proyectos creativos que reflejan un entendimiento de la curricula que se está estudiando.

A lo largo del año escolar, la actividad del Rompecabezas Deslizante puede ser integrada en diferentes áreas temáticas (ej.: geografía, matemáticas, composición). Los alumnos pueden crear imágenes para el rompecabezas que se relacionan con sus estudios en el aula, y compartirlas con sus compañeros. En el proceso también aprenderá como utilizar e integrar el producto de la actividad de Pintar, la cámara, la red en malla, y otras herramientas.

Habilidades:

Practicar el uso de la lógica y pensamiento estratégico para resolver un problema.

Practicar la comparación visual y habilidades para resolver problemas.

Practicar la discusión sobre el proceso de pensamiento para la resolución de problemas.

Aprender a explicar ideas, procesos de pensamiento y estrategias a los compañeros.

Aprender de los compañeros.

Aprender el uso de actividades específicas en la laptop.

Aprender a usar la Actividad de Pintar con un juego.

Aprender a trabajar en grupo sobre un proyecto.

Aprender a expresar ideas bajo estudio por medio de un proyecto original.

sugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/lessons/0Overview/_pt.abw0000644000175000017500000004174110716617376027455 0ustar janijani application/x-abiword AbiWord

Slider Puzzle: Plano Geral das Lições

Um 'quebra-cabeças deslizante' (slider puzzle ) é um clássico jogo de lógica que convida o jogador a deslizar as peças sobre um tabuleiro com o intuito de formar uma imagem ou um padrão. Não se pode levantar as peças do tabuleiro; somente deslizá-las para cima, para baixo, para a direita ou para a esquerda. Deve-se usar a estratégia e a lógica para encontrar a seqüência de movimentos que permitam ordenar as peças e resolver o quebra-cabeças.

Este Quebra-Cabeças Deslizante digital proporciona um contexto divertido para alunos jovens (e usuários principiantes do XO) para explorar as funções básicas do XO, aprender individual e colaborativamente as habilidades para a resolução de problemas e desenvolver projetos criativos que reflitam uma compreensão do currículo em que estão estudando.

Ao longo do ano escolar, a atividade do Quebra-Cabeças Deslizante pode ser integrada em diferentes áreas temáticas (por exemplo: geografia, matemática, redação criativa). Os alunos podem criar imagens no quebra-cabeças, relacionando-as com um assunto em que a classe esteja trabalhando e compartilhá-la com seus pares. Durante o processo, aprenderão como utilizar e integrar o resultado da atividade de desenho, da camera, da rede em malha e de outras ferramentas.

Habilidades:

Praticar o uso da lógica e do pensamento estratégico para resolver um problema.

Praticar a comparação visual e habilidades para resolver problemas.

Praticar a discussão sobre o processo de pensamento para a resolução de problemas.

Aprender a explicar idéias aos seus pares, através de processos e estratégias.

Aprender com seus pares.

Aprender como usar atividades específicas do XO.

Aprender a usar a Atividade de Pintar com um jogo.

Aprender a trabalhar em grupo em um projeto.

Aprender a expressar idéias sobre um estudo através de um projeto original.

sugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/mamamedia_icons/0000755000175000017500000000000010755626243025717 5ustar janijanisugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/mamamedia_icons/circle-check.svg0000644000175000017500000000444610716617376030770 0ustar janijani image/svg+xml sugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/mamamedia_icons/arrow_right.png0000644000175000017500000000070510716617376030762 0ustar janijaniPNG  IHDR6!XbKGD pHYsnu>tIME RIDATX?KADJ3I%iJ Xe% Ii"!T+ 13bBBrl[橖)fY2L&S#eUUǃeUtIME l˙GIDATX*EQQ%2"%g$%#rH܂32r n\ 0=uL@ Wz]~@D4ZѪoGRk{ ua⌸Qrϊ5Z~lSY ԍe\`3{g(ag8P%g$Շscg.jX-S(4+]vY&$4 MZbK/ӨV]X%} gb߇cJT,X<#Mp#)Et!Vj/oYL$֖H2?c"y)v0XyT@ dKL-IENDB`sugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/mamamedia_icons/circle-x.svg0000644000175000017500000000467310716617376030164 0ustar janijani image/svg+xml sugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/SliderPuzzleWidget.py0000644000175000017500000004604110743343012026753 0ustar janijani# Copyright 2007 World Wide Workshop Foundation # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # # If you find this activity useful or end up using parts of it in one of your # own creations we would love to hear from you at info@WorldWideWorkshop.org ! # import pygtk pygtk.require('2.0') import gtk, gobject import pango import md5 from mamamedia_modules import utils #from utils import load_image, calculate_matrix, debug, SliderCreator, trace from types import TupleType, ListType from random import random from time import time from math import sqrt from cStringIO import StringIO import os ### # General Information ### up_key = ['Up', 'KP_Up', 'KP_8'] down_key = ['Down', 'KP_Down', 'KP_2'] left_key = ['Left', 'KP_Left', 'KP_4'] right_key = ['Right', 'KP_Right', 'KP_6'] SLIDE_UP = 1 SLIDE_DOWN = 2 SLIDE_LEFT = 3 SLIDE_RIGHT = 4 def calculate_matrix (pieces): """ Given a number of pieces, calculate the best fit 2 dimensional matrix """ rows = int(sqrt(pieces)) cols = int(float(pieces) / rows) return rows*cols, rows, cols class SliderCreator (gtk.gdk.Pixbuf): def __init__ (self, width, height, fname=None, tlist=None): #tlist): if width == -1: width = 564 if height == -1: height = 564 super(SliderCreator, self).__init__(gtk.gdk.COLORSPACE_RGB, False, 8, width, height) if tlist is None: items = [] cmds = file(fname).readlines() if len(cmds) > 1: _x_ = eval(cmds[0]) for i in range(16): items.append(_x_) _x_ = eval(cmds[1]) else: items = tlist self.width = width self.height = height self.tlist = items self.prepare_stringed(2,2) #def scale_simple (self, w,h,m): # return SliderCreator(w,h,tlist=self.tlist) #def subpixbuf (self, x,y,w,h): # return SliderCreator(w,h,tlist=self.tlist) @classmethod def can_handle(klass, fname): return fname.lower().endswith('.sequence') def prepare_stringed (self, rows, cols): # We use a Pixmap as offscreen drawing canvas cm = gtk.gdk.colormap_get_system() pm = gtk.gdk.Pixmap(None, self.width, self.height, cm.get_visual().depth) #pangolayout = pm.create_pango_layout("") font_size = int(self.width / cols / 4) l = gtk.Label() pangolayout = pango.Layout(l.create_pango_context()) pangolayout.set_font_description(pango.FontDescription("sans bold %i" % font_size)) gc = pm.new_gc() gc.set_colormap(gtk.gdk.colormap_get_system()) color = cm.alloc_color('white') gc.set_foreground(color) pm.draw_rectangle(gc, True, 0, 0, self.width, self.height) color = cm.alloc_color('black') gc.set_foreground(color) sw, sh = (self.width / cols), (self.height / rows) item = iter(self.tlist) for r in range(rows): for c in range(cols): px = sw * c py = sh * r #if c > 0 and r > 0: # pm.draw_line(gc, px, 0, px, self.height-1) # pm.draw_line(gc, 0, py, self.width-1, py) pangolayout.set_text(str(item.next())) pe = pangolayout.get_pixel_extents() pe = pe[1][2]/2, pe[1][3]/2 pm.draw_layout(gc, px + (sw / 2) - pe[0], py + (sh / 2) - pe[1], pangolayout) self.get_from_drawable(pm, cm, 0, 0, 0, 0, -1, -1) utils.register_image_type(SliderCreator) ### # Game Logic ### class MatrixPosition (object): """ Helper class to hold a x/y coordinate, and move it by passing a direction, taking care of enforcing boundaries as needed. The x and y coords are 0 based. """ def __init__ (self, rowsize, colsize, x=0, y=0): self.rowsize = rowsize self.colsize = colsize self.x = min(x, colsize-1) self.y = min(y, rowsize-1) def __eq__ (self, other): if isinstance(other, (TupleType, ListType)) and len(other) == 2: return self.x == other[0] and self.y == other[1] return False def __ne__ (self, other): return not self.__eq__ (other) def bottom_right (self): """ Move to the lower right position of the matrix, having 0,0 as the top left corner """ self.x = self.colsize - 1 self.y = self.rowsize-1 def move (self, direction, count=1): """ Moving direction is actually the opposite of what is passed. We are moving the hole position, so if you slice a piece down into the hole, that hole is actually moving up. Returns bool, false if we can't move in the requested direction.""" if direction == SLIDE_UP and self.y < self.rowsize-1: self.y += 1 return True if direction == SLIDE_DOWN and self.y > 0: self.y -= 1 return True if direction == SLIDE_LEFT and self.x < self.colsize-1: self.x += 1 return True if direction == SLIDE_RIGHT and self.x > 0: self.x -= 1 return True return False def clone (self): return MatrixPosition(self.rowsize, self.colsize, self.x, self.y) def _freeze (self): return (self.rowsize, self.colsize, self.x, self.y) def _thaw (self, obj): if obj is not None: self.rowsize, self.colsize, self.x, self.y = obj class SliderPuzzleMap (object): """ This class holds the game logic. The current pieces position is held in self.pieces_map[YROW][XROW]. """ def __init__ (self, pieces=9, move_cb=None): self.reset(pieces) self.move_cb = move_cb self.solved = True def reset (self, pieces=9): self.pieces, self.rowsize, self.colsize = calculate_matrix(pieces) pieces_map = range(1,self.pieces+1) self.pieces_map = [] for i in range(self.rowsize): self.pieces_map.append(pieces_map[i*self.colsize:(i+1)*self.colsize]) self.hole_pos = MatrixPosition(self.rowsize, self.colsize) self.hole_pos.bottom_right() self.solved_map = [list(x) for x in self.pieces_map] self.solved_map[-1][-1] = None def randomize (self): """ To make sure the randomization is solvable, we don't simply shuffle the numbers. We move the hole in random directions through a finite number of iteractions. """ # Remove the move callback temporarily cb = self.move_cb self.move_cb = None iteractions = self.rowsize * self.colsize * (int(100*random())+1) t = time() for i in range(iteractions): while not (self.do_move(int(4*random())+1)): pass t = time() - t # Now move the hole to the bottom right for x in range(self.colsize-self.hole_pos.x-1): self.do_move(SLIDE_LEFT) for y in range(self.rowsize-self.hole_pos.y-1): self.do_move(SLIDE_UP) # Put the callback where it was self.move_cb = cb self.solved = False def do_move (self, slide_direction): """ The moves are relative to the moving piece: >>> jm = SliderPuzzleMap() >>> jm.debug_map() 1 2 3 4 5 6 7 8 * >>> jm.do_move(SLIDE_DOWN) True >>> jm.debug_map() # DOWN 1 2 3 4 5 * 7 8 6 >>> jm.do_move(SLIDE_RIGHT) True >>> jm.debug_map() # RIGHT 1 2 3 4 * 5 7 8 6 >>> jm.do_move(SLIDE_UP) True >>> jm.debug_map() # UP 1 2 3 4 8 5 7 * 6 >>> jm.do_move(SLIDE_LEFT) True >>> jm.debug_map() # LEFT 1 2 3 4 8 5 7 6 * We can't move over the matrix edges: >>> jm.do_move(SLIDE_LEFT) False >>> jm.debug_map() # LEFT 1 2 3 4 8 5 7 6 * >>> jm.do_move(SLIDE_UP) False >>> jm.debug_map() # UP 1 2 3 4 8 5 7 6 * >>> jm.do_move(SLIDE_RIGHT) True >>> jm.do_move(SLIDE_RIGHT) True >>> jm.do_move(SLIDE_RIGHT) False >>> jm.debug_map() # RIGHT x 3 1 2 3 4 8 5 * 7 6 >>> jm.do_move(SLIDE_DOWN) True >>> jm.do_move(SLIDE_DOWN) True >>> jm.do_move(SLIDE_DOWN) False >>> jm.debug_map() # DOWN x 3 * 2 3 1 8 5 4 7 6 """ # What piece are we going to move? old_hole_pos = self.hole_pos.clone() if self.hole_pos.move(slide_direction): # Move was a success, now update the map self.pieces_map[old_hole_pos.y][old_hole_pos.x] = self.pieces_map[self.hole_pos.y][self.hole_pos.x] self.is_solved() if self.move_cb is not None: self.move_cb(self.hole_pos.x, self.hole_pos.y, old_hole_pos.x, old_hole_pos.y) return True return False def do_move_piece (self, piece): """ Move the piece (1 based index) into the hole, if possible >>> jm = SliderPuzzleMap() >>> jm.debug_map() 1 2 3 4 5 6 7 8 * >>> jm.do_move_piece(6) True >>> jm.debug_map() # Moved 6 1 2 3 4 5 * 7 8 6 >>> jm.do_move_piece(2) False >>> jm.debug_map() # No move 1 2 3 4 5 * 7 8 6 Return True if a move was done, False otherwise. """ for y in range(self.rowsize): for x in range(self.colsize): if self.pieces_map[y][x] == piece: if self.hole_pos.x == x: if abs(self.hole_pos.y-y) == 1: return self.do_move(self.hole_pos.y > y and SLIDE_DOWN or SLIDE_UP) elif self.hole_pos.y == y: if abs(self.hole_pos.x-x) == 1: return self.do_move(self.hole_pos.x > x and SLIDE_RIGHT or SLIDE_LEFT) else: return False return False def is_hole_at (self, x, y): """ >>> jm = SliderPuzzleMap() >>> jm.debug_map() 1 2 3 4 5 6 7 8 * >>> jm.is_hole_at(2,2) True >>> jm.is_hole_at(0,0) False """ return self.hole_pos == (x,y) def is_solved (self): """ >>> jm = SliderPuzzleMap() >>> jm.do_move_piece(6) True >>> jm.is_solved() False >>> jm.do_move_piece(6) True >>> jm.is_solved() True """ if self.hole_pos != (self.colsize-1, self.rowsize-1): return False self.pieces_map[self.hole_pos.y][self.hole_pos.x] = None self.solved = self.pieces_map == self.solved_map return self.solved def get_cell_at (self, x, y): if x < 0 or x >= self.colsize or y < 0 or y >= self.rowsize or self.is_hole_at(x,y): return None return self.pieces_map[y][x] def debug_map (self): for y in range(self.rowsize): for x in range(self.colsize): if self.hole_pos == (x,y): print "*", else: print self.pieces_map[y][x], print def __call__ (self): self.debug_map() def _freeze (self): return {'pieces': self.pieces, 'rowsize': self.rowsize, 'colsize': self.colsize, 'pieces_map': self.pieces_map, 'hole_pos_freeze': self.hole_pos._freeze()} def _thaw (self, obj): for k in obj.keys(): if hasattr(self, k): setattr(self, k, obj[k]) self.hole_pos._thaw(obj.get('hole_pos_freeze', None)) ### # Widget Definition ### class SliderPuzzleWidget (gtk.Table): __gsignals__ = {'solved' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()), 'shuffled' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()), 'moved' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),} def __init__ (self, pieces=9, width=480, height=480): self.jumbler = SliderPuzzleMap(pieces, self.jumblermap_piece_move_cb) # We take this from the jumbler object because it may have altered our requested value gtk.Table.__init__(self, self.jumbler.rowsize, self.jumbler.colsize) self.image = None #gtk.Image() self.width = width self.height = height self.set_size_request(width, height) self.filename = None def prepare_pieces (self): """ set up a list of UI objects that will serve as pieces, ordered correctly """ self.pieces = [] if self.image is None: # pb = self.image.get_pixbuf() #if self.image is None or pb is None: for i in range(self.jumbler.pieces): self.pieces.append(gtk.Button(str(i+1))) self.pieces[-1].connect("button-release-event", self.process_mouse_click, i+1) self.pieces[-1].show() else: if isinstance(self.image, SliderCreator): # ask for image creation self.image.prepare_stringed(self.jumbler.rowsize, self.jumbler.colsize) w = self.image.get_width() / self.jumbler.colsize h = self.image.get_height() / self.jumbler.rowsize for y in range(self.jumbler.rowsize): for x in range(self.jumbler.colsize): img = gtk.Image() img.set_from_pixbuf(self.image.subpixbuf(x*w, y*h, w-1, h-1)) img.show() self.pieces.append(gtk.EventBox()) self.pieces[-1].add(img) self.pieces[-1].connect("button-press-event", self.process_mouse_click, (y*self.jumbler.colsize)+x+1) self.pieces[-1].show() self.set_row_spacings(1) self.set_col_spacings(1) @utils.trace def full_refresh (self): # Delete everything self.foreach(self.remove) self.prepare_pieces() # Add the pieces in their respective places for y in range(self.jumbler.rowsize): for x in range(self.jumbler.colsize): pos = self.jumbler.get_cell_at(x, y) if pos is not None: self.attach(self.pieces[pos-1], x, x+1, y, y+1) def process_mouse_click (self, b, e, i): # i is the 1 based index of the piece self.jumbler.do_move_piece(i) def process_key (self, w, e): if self.get_parent() == None: return False k = gtk.gdk.keyval_name(e.keyval) if k in up_key: self.jumbler.do_move(SLIDE_UP) return True if k in down_key: self.jumbler.do_move(SLIDE_DOWN) return True if k in left_key: self.jumbler.do_move(SLIDE_LEFT) return True if k in right_key: self.jumbler.do_move(SLIDE_RIGHT) return True return False ### SliderPuzzleMap specific callbacks ### def jumblermap_piece_move_cb (self, hx, hy, px, py): if not hasattr(self, 'pieces'): return piece = self.pieces[self.jumbler.get_cell_at(px, py)-1] self.remove(piece) self.attach(piece, px, px+1, py, py+1) self.emit("moved") if self.jumbler.solved: self.emit("solved") ### Parent callable interface ### def get_nr_pieces (self): return self.jumbler.pieces @utils.trace def set_nr_pieces (self, nr_pieces): self.jumbler.reset(nr_pieces) self.resize(self.jumbler.rowsize, self.jumbler.colsize) self.randomize() @utils.trace def randomize (self): """ Jumble the SliderPuzzle """ self.jumbler.randomize() self.full_refresh() self.emit("shuffled") @utils.trace def load_image (self, image, width=0, height=0): """ Loads an image from the file. width and height are processed as follows: -1 : follow the loaded image size 0 : follow the size set on widget instantiation * : use that specific size""" if width == 0: width = self.width if height == 0: height = self.height if not isinstance(image, SliderCreator): self.image = utils.resize_image(image, width, height) else: self.image = image self.filename = True self.full_refresh() def set_image (self, image): # image is a pixbuf! self.image = image self.filename = True def set_image_from_str (self, image): fn = os.tempnam() f = file(fn, 'w+b') f.write(image) f.close() i = gtk.Image() i.set_from_file(fn) os.remove(fn) self.image = i.get_pixbuf() self.filename = True def show_image (self): """ Shows the full image, used as visual clue for solved puzzle """ # Delete everything self.foreach(self.remove) if hasattr(self, 'pieces'): del self.pieces # Resize to a single cell and use that for the image self.resize(1,1) img = gtk.Image() img.set_from_pixbuf(self.image) self.attach(img, 0,1,0,1) img.show() def get_image_as_png (self, cb=None): if self.image is None: return None rv = None if cb is None: rv = StringIO() cb = rv.write self.image.save_to_callback(cb, "png") if rv is not None: return rv.getvalue() else: return True def _freeze (self, journal=True): """ returns a json writable object representation capable of being used to restore our current status """ if journal: return {'jumbler': self.jumbler._freeze(), 'image': self.get_image_as_png(), } else: return {'jumbler': self.jumbler._freeze()} def _thaw (self, obj): """ retrieves a frozen status from a python object, as per _freeze """ print obj['jumbler'] self.jumbler._thaw(obj['jumbler']) if obj.has_key('image') and obj['image'] is not None: self.set_image_from_str(obj['image']) del obj['image'] self.full_refresh() def _test(): import doctest doctest.testmod() if __name__ == '__main__': _test() sugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/mmm_modules/0000755000175000017500000000000010755626243025127 5ustar janijanisugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/mmm_modules/i18n.py0000644000175000017500000001372210743343012026250 0ustar janijani#!/usr/bin/env python # -*- coding: utf-8 -*- # Copyright 2007 World Wide Workshop Foundation # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # # If you find this activity useful or end up using parts of it in one of your # own creations we would love to hear from you at info@WorldWideWorkshop.org ! # import os import gettext import locale import gtk, gobject _ = lambda x: x # Images were taken from http://www.sodipodi.com/ # except for korea taken from http://zh.wikipedia.org/wiki/Image:Unification_flag_of_Korea.svg lang_name_mapping = { 'zh_cn':(None, _('Chinese (simplified)'), 'china'), 'zh_tw':(None, _('Chinese (traditional)'), 'china'), 'cs':(None, _('Czech'),'czech_republic'), 'da':(None, _('Danish'),'denmark'), 'nl':(None, _('Dutch'), 'netherlands'), 'en':('English', _('English'),'united_states'), 'en_gb':('English', _('English - Great Britain'),'united_kingdom'), 'en_us':('English', _('English - U.S.'),'united_states'), 'fi':(None, _('Finnish'),'finland'), 'fr':('Français', _('French'),'france'), 'de':(None, _('German'),'germany'), 'hu':(None, _('Hungarian'),'hungary'), 'it':(None, _('Italian'),'italy'), 'ja':(None, _('Japanese'),'japan'), 'ko':(None, _('Korean'),'korea'), 'no':(None, _('Norwegian'),'norway'), 'pl':(None, _('Polish'),'poland'), 'pt':('Português', _('Portuguese'),'portugal'), 'pt_br':('Português do Brasil', _('Portuguese - Brazilian'),'brazil'), 'ru':(None, _('Russian'),'russian_federation'), 'sk':(None, _('Slovak'),'slovenia'), 'es':('Español', _('Spanish'),'spain'), 'sv':(None, _('Swedish'),'sweden'), 'tr':(None, _('Turkish'),'turkey'), } class LangDetails (object): def __init__ (self, code, name, image, domain): self.code = code self.country_code = self.code.split('_')[0] self.name = name self.image = image self.domain = domain def guess_translation (self, fallback=False): self.gnutranslation = gettext.translation(self.domain, 'locale', [self.code], fallback=fallback) def install (self): self.gnutranslation.install() def matches (self, code, exact=True): if exact: return code.lower() == self.code.lower() return code.split('_')[0].lower() == self.country_code.lower() def get_lang_details (lang, domain): mapping = lang_name_mapping.get(lang.lower(), None) if mapping is None: # Try just the country code lang = lang.split('_')[0] mapping = lang_name_mapping.get(lang.lower(), None) if mapping is None: return None if mapping[0] is None: return LangDetails(lang, mapping[1], mapping[2], domain) return LangDetails(lang, mapping[0], mapping[2], domain) def list_available_translations (domain): rv = [get_lang_details('en', domain)] rv[0].guess_translation(True) if not os.path.isdir('locale'): return rv for i,x in enumerate([x for x in os.listdir('locale') if os.path.isdir('locale/' + x) and not x.startswith('.')]): try: details = get_lang_details(x, domain) if details is not None: details.guess_translation() rv.append(details) except: raise pass return rv class LanguageComboBox (gtk.ComboBox): def __init__ (self, domain): liststore = gtk.ListStore(gobject.TYPE_STRING) gtk.ComboBox.__init__(self, liststore) self.cell = gtk.CellRendererText() self.pack_start(self.cell, True) self.add_attribute(self.cell, 'text', 0) self.translations = list_available_translations(domain) for i,x in enumerate(self.translations): liststore.insert(i+1, (gettext.gettext(x.name), )) self.connect('changed', self.install) def modify_bg (self, state, color): setattr(self.cell, 'background-gdk',color) setattr(self.cell, 'background-set',True) def install (self, *args): if self.get_active() > -1: self.translations[self.get_active()].install() else: code, encoding = locale.getdefaultlocale() if code is None: code = 'en' # Try to find the exact translation for i,t in enumerate(self.translations): if t.matches(code): self.set_active(i) break if self.get_active() < 0: # Failed, try to get the translation based only in the country for i,t in enumerate(self.translations): if t.matches(code, False): self.set_active(i) break if self.get_active() < 0: # nothing found, select first translation self.set_active(0) # Allow for other callbacks return False ### def gather_other_translations (): from glob import glob lessons = filter(lambda x: os.path.isdir(x), glob('lessons/*')) lessons = map(lambda x: os.path.basename(x), lessons) lessons = map(lambda x: x[0].isdigit() and x[1:] or x, lessons) images = filter(lambda x: os.path.isdir(x), glob('images/*')) images = map(lambda x: os.path.basename(x), images) f = file('i18n_misc_strings.py', 'w') for e in images+lessons: f.write('_("%s")\n' % e) f.close() sugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/mmm_modules/borderframe.py0000644000175000017500000000644010743343012027760 0ustar janijani# Copyright 2007 World Wide Workshop Foundation # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # # If you find this activity useful or end up using parts of it in one of your # own creations we would love to hear from you at info@WorldWideWorkshop.org ! # import pygtk pygtk.require('2.0') import gtk, gobject, pango BORDER_LEFT = 1 BORDER_RIGHT = 2 BORDER_TOP = 4 BORDER_BOTTOM = 8 BORDER_VERTICAL = BORDER_TOP | BORDER_BOTTOM BORDER_HORIZONTAL = BORDER_LEFT | BORDER_RIGHT BORDER_ALL = BORDER_VERTICAL | BORDER_HORIZONTAL BORDER_ALL_BUT_BOTTOM = BORDER_HORIZONTAL | BORDER_TOP BORDER_ALL_BUT_TOP = BORDER_HORIZONTAL | BORDER_BOTTOM BORDER_ALL_BUT_LEFT = BORDER_VERTICAL | BORDER_RIGHT class BorderFrame (gtk.EventBox): def __init__ (self, border=BORDER_ALL, size=5, bg_color=None, border_color=None): gtk.EventBox.__init__(self) if border_color is not None: self.set_border_color(gtk.gdk.color_parse(border_color)) self.inner = gtk.EventBox() if bg_color is not None: self.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(bg_color)) align = gtk.Alignment(1.0,1.0,1.0,1.0) self.padding = [0,0,0,0] if (border & BORDER_TOP) != 0: self.padding[0] = size if (border & BORDER_BOTTOM) != 0: self.padding[1] = size if (border & BORDER_LEFT) != 0: self.padding[2] = size if (border & BORDER_RIGHT) != 0: self.padding[3] = size align.set_padding(*self.padding) align.add(self.inner) align.show() self.inner.show() gtk.EventBox.add(self, align) self.stack = [] def set_border_color (self, color): gtk.EventBox.modify_bg(self, gtk.STATE_NORMAL, color) def modify_bg (self, state, color): self.inner.modify_bg(state, color) def add (self, widget): self.stack.append(widget) self.inner.add(widget) self.inner.child.show_now() def push (self, widget): widget.set_size_request(*self.inner.child.get_size_request()) self.inner.remove(self.inner.child) self.add(widget) def pop (self): if len(self.stack) > 1: self.inner.remove(self.inner.child) del self.stack[-1] self.inner.add(self.stack[-1]) def get_child (self): return self.inner.child def set_size_request (self, w, h): self.inner.set_size_request(w,h) super(BorderFrame, self).set_size_request(w+self.padding[0]+self.padding[2], h+self.padding[1]+self.padding[3]) def show (self): self.show_all() # def get_allocation (self): # return self.inner.get_allocation() sugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/mmm_modules/json.py0000644000175000017500000002377410716617376026473 0ustar janijaniimport string import types ## json.py implements a JSON (http://json.org) reader and writer. ## Copyright (C) 2005 Patrick D. Logan ## Contact mailto:patrickdlogan@stardecisions.com ## ## This library is free software; you can redistribute it and/or ## modify it under the terms of the GNU Lesser General Public ## License as published by the Free Software Foundation; either ## version 2.1 of the License, or (at your option) any later version. ## ## This library is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ## Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public ## License along with this library; if not, write to the Free Software ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA class _StringGenerator(object): def __init__(self, string): self.string = string self.index = -1 def peek(self): i = self.index + 1 if i < len(self.string): return self.string[i] else: return None def next(self): self.index += 1 if self.index < len(self.string): return self.string[self.index] else: raise StopIteration def all(self): return self.string class WriteException(Exception): pass class ReadException(Exception): pass class JsonReader(object): hex_digits = {'A': 10,'B': 11,'C': 12,'D': 13,'E': 14,'F':15} escapes = {'t':'\t','n':'\n','f':'\f','r':'\r','b':'\b'} def read(self, s): self._generator = _StringGenerator(s) result = self._read() return result def _read(self): self._eatWhitespace() peek = self._peek() if peek is None: raise ReadException, "Nothing to read: '%s'" % self._generator.all() if peek == '{': return self._readObject() elif peek == '[': return self._readArray() elif peek == '"': return self._readString() elif peek == '-' or peek.isdigit(): return self._readNumber() elif peek == 't': return self._readTrue() elif peek == 'f': return self._readFalse() elif peek == 'n': return self._readNull() elif peek == '/': self._readComment() return self._read() else: raise ReadException, "Input is not valid JSON: '%s'" % self._generator.all() def _readTrue(self): self._assertNext('t', "true") self._assertNext('r', "true") self._assertNext('u', "true") self._assertNext('e', "true") return True def _readFalse(self): self._assertNext('f', "false") self._assertNext('a', "false") self._assertNext('l', "false") self._assertNext('s', "false") self._assertNext('e', "false") return False def _readNull(self): self._assertNext('n', "null") self._assertNext('u', "null") self._assertNext('l', "null") self._assertNext('l', "null") return None def _assertNext(self, ch, target): if self._next() != ch: raise ReadException, "Trying to read %s: '%s'" % (target, self._generator.all()) def _readNumber(self): isfloat = False result = self._next() peek = self._peek() while peek is not None and (peek.isdigit() or peek == "."): isfloat = isfloat or peek == "." result = result + self._next() peek = self._peek() try: if isfloat: return float(result) else: return int(result) except ValueError: raise ReadException, "Not a valid JSON number: '%s'" % result def _readString(self): result = "" assert self._next() == '"' try: while self._peek() != '"': ch = self._next() if ch == "\\": ch = self._next() if ch in 'brnft': ch = self.escapes[ch] elif ch == "u": ch4096 = self._next() ch256 = self._next() ch16 = self._next() ch1 = self._next() n = 4096 * self._hexDigitToInt(ch4096) n += 256 * self._hexDigitToInt(ch256) n += 16 * self._hexDigitToInt(ch16) n += self._hexDigitToInt(ch1) ch = unichr(n) elif ch not in '"/\\': raise ReadException, "Not a valid escaped JSON character: '%s' in %s" % (ch, self._generator.all()) result = result + ch except StopIteration: raise ReadException, "Not a valid JSON string: '%s'" % self._generator.all() assert self._next() == '"' return result def _hexDigitToInt(self, ch): try: result = self.hex_digits[ch.upper()] except KeyError: try: result = int(ch) except ValueError: raise ReadException, "The character %s is not a hex digit." % ch return result def _readComment(self): assert self._next() == "/" second = self._next() if second == "/": self._readDoubleSolidusComment() elif second == '*': self._readCStyleComment() else: raise ReadException, "Not a valid JSON comment: %s" % self._generator.all() def _readCStyleComment(self): try: done = False while not done: ch = self._next() done = (ch == "*" and self._peek() == "/") if not done and ch == "/" and self._peek() == "*": raise ReadException, "Not a valid JSON comment: %s, '/*' cannot be embedded in the comment." % self._generator.all() self._next() except StopIteration: raise ReadException, "Not a valid JSON comment: %s, expected */" % self._generator.all() def _readDoubleSolidusComment(self): try: ch = self._next() while ch != "\r" and ch != "\n": ch = self._next() except StopIteration: pass def _readArray(self): result = [] assert self._next() == '[' done = self._peek() == ']' while not done: item = self._read() result.append(item) self._eatWhitespace() done = self._peek() == ']' if not done: ch = self._next() if ch != ",": raise ReadException, "Not a valid JSON array: '%s' due to: '%s'" % (self._generator.all(), ch) assert ']' == self._next() return result def _readObject(self): result = {} assert self._next() == '{' done = self._peek() == '}' while not done: key = self._read() if type(key) is not types.StringType: raise ReadException, "Not a valid JSON object key (should be a string): %s" % key self._eatWhitespace() ch = self._next() if ch != ":": raise ReadException, "Not a valid JSON object: '%s' due to: '%s'" % (self._generator.all(), ch) self._eatWhitespace() val = self._read() result[key] = val self._eatWhitespace() done = self._peek() == '}' if not done: ch = self._next() if ch != ",": raise ReadException, "Not a valid JSON array: '%s' due to: '%s'" % (self._generator.all(), ch) assert self._next() == "}" return result def _eatWhitespace(self): p = self._peek() while p is not None and p in string.whitespace or p == '/': if p == '/': self._readComment() else: self._next() p = self._peek() def _peek(self): return self._generator.peek() def _next(self): return self._generator.next() class JsonWriter(object): def _append(self, s): self._results.append(s) def write(self, obj, escaped_forward_slash=False): self._escaped_forward_slash = escaped_forward_slash self._results = [] self._write(obj) return "".join(self._results) def _write(self, obj): ty = type(obj) if ty is types.DictType: n = len(obj) self._append("{") for k, v in obj.items(): self._write(k) self._append(":") self._write(v) n = n - 1 if n > 0: self._append(",") self._append("}") elif ty is types.ListType or ty is types.TupleType: n = len(obj) self._append("[") for item in obj: self._write(item) n = n - 1 if n > 0: self._append(",") self._append("]") elif ty is types.StringType or ty is types.UnicodeType: self._append('"') obj = obj.replace('\\', r'\\') if self._escaped_forward_slash: obj = obj.replace('/', r'\/') obj = obj.replace('"', r'\"') obj = obj.replace('\b', r'\b') obj = obj.replace('\f', r'\f') obj = obj.replace('\n', r'\n') obj = obj.replace('\r', r'\r') obj = obj.replace('\t', r'\t') self._append(obj) self._append('"') elif ty is types.IntType or ty is types.LongType: self._append(str(obj)) elif ty is types.FloatType: self._append("%f" % obj) elif obj is True: self._append("true") elif obj is False: self._append("false") elif obj is None: self._append("null") else: raise WriteException, "Cannot write in JSON: %s" % repr(obj) def write(obj, escaped_forward_slash=False): return JsonWriter().write(obj, escaped_forward_slash) def read(s): return JsonReader().read(s) sugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/mmm_modules/buddy_panel.py0000644000175000017500000001176610743343012027765 0ustar janijani# Copyright 2007 World Wide Workshop Foundation # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # # If you find this activity useful or end up using parts of it in one of your # own creations we would love to hear from you at info@WorldWideWorkshop.org ! # import pygtk pygtk.require('2.0') import gtk import logging from tube_helper import GAME_IDLE, GAME_STARTED, GAME_FINISHED, GAME_QUIT #from sugar.graphics.icon import CanvasIcon BUDDYMODE_CONTEST = 0 BUDDYMODE_COLLABORATION = 1 class BuddyPanel (gtk.ScrolledWindow): def __init__ (self, mode=BUDDYMODE_CONTEST): super(BuddyPanel, self).__init__() self.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) self.model = gtk.ListStore(str, str, str, str) self.model.set_sort_column_id(0, gtk.SORT_ASCENDING) self.treeview = gtk.TreeView() #col = gtk.TreeViewColumn(_("Icon")) #r = gtk.CellRendererText() #col.pack_start(r, True) #col.set_attributes(r, stock_id=0) #self.treeview.append_column(col) col = gtk.TreeViewColumn(_("Buddy")) r = gtk.CellRendererText() col.pack_start(r, True) col.set_attributes(r, text=0) self.treeview.append_column(col) col = gtk.TreeViewColumn(_("Status")) r = gtk.CellRendererText() col.pack_start(r, True) col.set_attributes(r, text=1) self.treeview.append_column(col) col.set_visible(mode == BUDDYMODE_CONTEST) col = gtk.TreeViewColumn(_("Play Time")) r = gtk.CellRendererText() col.pack_start(r, True) col.set_attributes(r, text=2) self.treeview.append_column(col) col.set_visible(mode == BUDDYMODE_CONTEST) col = gtk.TreeViewColumn(_("Joined at")) r = gtk.CellRendererText() col.pack_start(r, True) col.set_attributes(r, text=3) self.treeview.append_column(col) col.set_visible(mode == BUDDYMODE_COLLABORATION) self.treeview.set_model(self.model) self.add(self.treeview) self.show_all() self.players = {} def add_player (self, buddy, current_clock=0): """ Adds a player to the panel """ op = buddy.object_path() if self.players.get(op) is not None: return # buddy_color = buddy.props.color # if not buddy_color: # buddy_color = "#000000,#ffffff" # # icon = CanvasIcon( # icon_name='computer-xo', # xo_color=XoColor(buddy_color)) # nick = buddy.props.nick if not nick: nick = "" self.players[op] = (buddy, self.model.append([nick, _('synchronizing'), '', ''])) return nick def update_player (self, buddy, status, clock_running, time_ellapsed): """Since the current target build (432) does not fully support the contest mode, we are removing this for now. """ #return op = buddy.object_path() if self.players.get(op, None) is None: logging.debug("Player %s not found" % op) return print self.players[op] if status == GAME_STARTED[1]: stat = clock_running and _("Playing") or _("Paused") elif status == GAME_FINISHED[1]: stat = _("Finished") elif status == GAME_QUIT[1]: stat = _("Gave up") else: stat = _("Unknown") self.model.set_value(self.players[op][1], 1, stat) self.model.set_value(self.players[op][1], 2, _("%i minutes") % (time_ellapsed/60)) self.model.set_value(self.players[op][1], 3, '%i:%0.2i' % (int(time_ellapsed / 60), int(time_ellapsed % 60))) return (self.model.get_value(self.players[op][1], 0), self.model.get_value(self.players[op][1], 1)) def get_buddy_from_path (self, object_path): logging.debug("op = " + object_path) logging.debug(self.players) return self.players.get(object_path, None) def remove_player (self, buddy): op = buddy.object_path() if self.players.get(op) is None: return nick = buddy.props.nick if not nick: nick = "" self.model.remove(self.players[op][1]) del self.players[op] return nick sugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/mmm_modules/image_category.py0000644000175000017500000004242210743343012030447 0ustar janijani# Copyright 2007 World Wide Workshop Foundation # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # # If you find this activity useful or end up using parts of it in one of your # own creations we would love to hear from you at info@WorldWideWorkshop.org ! # import pygtk pygtk.require('2.0') import gtk, gobject import os from glob import glob import logging import md5 from sugar.graphics.objectchooser import ObjectChooser from borderframe import BorderFrame from utils import load_image, resize_image, RESIZE_CUT cwd = os.path.normpath(os.path.join(os.path.split(__file__)[0], '..')) if os.path.exists(os.path.join(cwd, 'mamamedia_icons')): # Local, no shared code, version mmmpath = cwd iconpath = os.path.join(mmmpath, 'mamamedia_icons') else: propfile = os.path.expanduser("~/.sugar/default/org.worldwideworkshop.olpc.MMMPath") if os.path.exists(propfile): mmmpath = file(propfile, 'rb').read() else: mmmpath = cwd iconpath = os.path.join(mmmpath, 'icons') from gettext import gettext as _ THUMB_SIZE = 48 IMAGE_SIZE = 200 #MYOWNPIC_FOLDER = os.path.expanduser("~/.sugar/default/org.worldwideworkshop.olpc.MyOwnPictures") def prepare_btn (btn): return btn def register_category (pixbuf_class, path): pass class CategoryDirectory (object): def __init__ (self, path, width=-1, height=-1, method=RESIZE_CUT): self.path = path self.method = method self.pb = None if os.path.isdir(path): self.gather_images() else: self.images = [path] self.set_thumb_size(THUMB_SIZE, THUMB_SIZE) self.set_image_size(width, height) self.filename = None self.name = os.path.basename(path) def gather_images (self): """ Lists all images in the selected path as per the wildcard expansion of 'image_*'. Adds all linked images from files (*.lnk) """ self.images = [] links = glob(os.path.join(self.path, "*.lnk")) for link in links: fpath = file(link).readlines()[0].strip() if os.path.isfile(fpath) and not (fpath in self.images): self.images.append(fpath) else: os.remove(link) self.images.extend(glob(os.path.join(self.path, "image_*"))) self.images.sort() def set_image_size (self, w, h): self.width = w self.height = h def set_thumb_size (self, w, h): self.twidth = w self.theight = h self.thumb = self._get_category_thumb() def get_image (self, name): if not len(self.images) or name is None or name not in self.images: return None self.pb = load_image(name) if self.pb is not None: rv = resize_image(self.pb, self.width, self.height, method=self.method) self.filename = name return rv return None def get_next_image (self): if not len(self.images): return None if self.filename is None or self.filename not in self.images: pos = -1 else: pos = self.images.index(self.filename) pos += 1 if pos >= len(self.images): pos = 0 return self.get_image(self.images[pos]) def get_previous_image (self): if not len(self.images): return None if self.filename is None or self.filename not in self.images: pos = len(self.images) else: pos = self.images.index(self.filename) pos -= 1 if pos < 0: pos = len(self.images) - 1 return self.get_image(self.images[pos]) def has_images (self): print ("IMG", self.images) return len(self.images) > 0 def count_images (self): return len(self.images) def has_image (self): return self.pb is not None def _get_category_thumb (self): if os.path.isdir(self.path): thumbs = glob(os.path.join(self.path, "thumb.*")) thumbs.extend(glob(os.path.join(self.path, "default_thumb.*"))) thumbs.extend(glob(os.path.join(mmmpath, "mmm_images","default_thumb.*"))) print thumbs thumbs = filter(lambda x: os.path.exists(x), thumbs) thumbs.append(None) else: thumbs = [self.path] print (self.path, thumbs) return load_image(thumbs[0], self.twidth, self.theight) class ImageSelectorWidget (gtk.Table): __gsignals__ = {'category_press' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()), 'image_press' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),} def __init__ (self, width=IMAGE_SIZE, height=IMAGE_SIZE, frame_color=None, prepare_btn_cb=prepare_btn, method=RESIZE_CUT, image_dir=None): gtk.Table.__init__(self, 2,5,False) self._signals = [] self.width = width self.height = height self.image = gtk.Image() self.method = method #self.set_myownpath(MYOWNPIC_FOLDER) img_box = BorderFrame(border_color=frame_color) img_box.add(self.image) img_box.set_border_width(5) self._signals.append((img_box, img_box.connect('button_press_event', self.emit_image_pressed))) self.attach(img_box, 0,5,0,1,0,0) self.attach(gtk.Label(), 0,1,1,2) self.bl = gtk.Button() il = gtk.Image() il.set_from_pixbuf(load_image(os.path.join(iconpath, 'arrow_left.png'))) self.bl.set_image(il) self.bl.connect('clicked', self.previous) self.attach(prepare_btn_cb(self.bl), 1,2,1,2,0,0) cteb = gtk.EventBox() self.cat_thumb = gtk.Image() self.cat_thumb.set_size_request(THUMB_SIZE, THUMB_SIZE) cteb.add(self.cat_thumb) self._signals.append((cteb, cteb.connect('button_press_event', self.emit_cat_pressed))) self.attach(cteb, 2,3,1,2,0,0,xpadding=10) self.br = gtk.Button() ir = gtk.Image() ir.set_from_pixbuf(load_image(os.path.join(iconpath,'arrow_right.png'))) self.br.set_image(ir) self.br.connect('clicked', self.next) self.attach(prepare_btn_cb(self.br), 3,4,1,2,0,0) self.attach(gtk.Label(),4,5,1,2) self.filename = None self.show_all() self.image.set_size_request(width, height) if image_dir is None: image_dir = os.path.join(mmmpath, "mmm_images") self.set_image_dir(image_dir) def add_image (self, *args):#widget=None, response=None, *args): """ Use to trigger and process the My Own Image selector. """ chooser = ObjectChooser(_('Choose image'), None, #self._parent, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT) try: result = chooser.run() if result == gtk.RESPONSE_ACCEPT: jobject = chooser.get_selected_object() if jobject and jobject.file_path: if self.load_image(str(jobject.file_path), True): pass else: err = gtk.MessageDialog(self._parent, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, _("Not a valid image file")) err.run() err.destroy() return finally: chooser.destroy() del chooser #print (widget,response,args) #if response is None: # # My Own Image selector # imgfilter = gtk.FileFilter() # imgfilter.set_name(_("Image Files")) # imgfilter.add_mime_type('image/*') # fd = gtk.FileChooserDialog(title=_("Select Image File"), parent=None, # action=gtk.FILE_CHOOSER_ACTION_OPEN, # buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT,gtk.STOCK_OK, gtk.RESPONSE_ACCEPT)) # # fd.set_current_folder(os.path.expanduser("~/")) # fd.set_modal(True) # fd.add_filter(imgfilter) # fd.connect("response", self.add_image) # fd.resize(800,600) # fd.show() #else: # if response == gtk.RESPONSE_ACCEPT: # if self.load_image(widget.get_filename()): # pass # #self.do_shuffle() # else: # err = gtk.MessageDialog(self._parent, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, # _("Not a valid image file")) # err.run() # err.destroy() # return # widget.destroy() def set_readonly (self, ro=True): if ro: self.bl.hide() self.br.hide() for w, s in self._signals: w.handler_block(s) #def set_myownpath (self, path): # """ Sets the path to My Own Pictures storage, so we know where to add links to new pictures """ # if path is None: # self.myownpath = None # else: # if not os.path.exists(path): # os.mkdir(path) # self.myownpath = path #def is_myownpath (self): # """ Checks current path against the set custom image path """ # return self.myownpath == self.category.path # #def gather_myownpath_images(self): # """ """ # rv = [] # self.images = [] # links = glob(os.path.join(self.myownpath, "*.lnk")) # for link in links: # linfo = filter(None, map(lambda x: x.strip(), file(link).readlines())) # fpath = linfo[0] # if os.path.isfile(fpath) and not (fpath in self.images): # self.images.append(fpath) # if len(linfo) > 1: # digest = linfo[1] # else: # digest = md5.new(file(fpath, 'rb').read()).hexdigest() # rv.append((link, fpath, digest)) # for fpath in glob(os.path.join(self.myownpath, "image_*")): # digest = md5.new(file(fpath, 'rb').read()).hexdigest() # rv.append((fpath, fpath, digest)) # return rv def emit_cat_pressed (self, *args): self.emit('category_press') return True def emit_image_pressed (self, *args): self.emit('image_press') return True def has_image (self): return self.category.has_image() def get_category_name (self): return self.category.name def get_filename (self): return self.category.filename def get_image (self): return self.category.pb def next (self, *args, **kwargs): pb = self.category.get_next_image() if pb is not None: self.image.set_from_pixbuf(pb) def previous (self, *args, **kwargs): pb = self.category.get_previous_image() if pb is not None: self.image.set_from_pixbuf(pb) def get_image_dir (self): return self.category.path def set_image_dir (self, directory): if os.path.exists(directory) and not os.path.isdir(directory): filename = directory directory = os.path.dirname(directory) logging.debug("dir=%s, filename=%s" % (directory, filename)) else: logging.debug("dir=%s" % (directory)) filename = None self.category = CategoryDirectory(directory, self.width, self.height, self.method) self.cat_thumb.set_from_pixbuf(self.category.thumb) if filename: self.image.set_from_pixbuf(self.category.get_image(filename)) else: if self.category.has_images(): self.next() def load_image(self, filename, fromJournal=False): """ Loads an image from the file """ #if self.myownpath is not None and os.path.isdir(self.myownpath) and not fromJournal: # name = os.path.splitext(os.path.basename(filename))[0] # while os.path.exists(os.path.join(self.myownpath, '%s.lnk' % name)): # name = name + '_' # f = file(os.path.join(self.myownpath, '%s.lnk' % name), 'w') # f.write(filename) # image_digest = md5.new(file(filename, 'rb').read()).hexdigest() # f.write('\n%s' % image_digest) # f.close() # self.category = CategoryDirectory(self.myownpath, self.width, self.height, method=self.method) # self.image.set_from_pixbuf(self.category.get_image(filename)) #else: self.category = CategoryDirectory(filename, self.width, self.height, method=self.method) self.next() self.cat_thumb.set_from_pixbuf(self.category.thumb) return self.image.get_pixbuf() is not None def load_pb (self, pb): self.category.pb = pb self.image.set_from_pixbuf(resize_image(pb, self.width, self.height, method=self.method)) #def set_game_widget(self, game_widget): # if self.has_image(): # game_widget.load_image(self.get_filename()) def _freeze (self): """ returns a json writable object representation capable of being used to restore our current status """ return {'image_dir': self.get_image_dir(), 'filename': self.get_filename()} def _thaw (self, obj): """ retrieves a frozen status from a python object, as per _freeze """ self.set_image_dir(obj.get('image_dir', None)) self.image.set_from_pixbuf(self.category.get_image(obj.get('filename', None))) class CategorySelector (gtk.ScrolledWindow): __gsignals__ = {'selected' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (str,))} def __init__ (self, title=None, selected_category_path=None, path=None, extra=()): gtk.ScrolledWindow.__init__ (self) self.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) if path is None: path = os.path.join(mmmpath, 'mmm_images') self.path = path self.thumbs = [] model, selected = self.get_model(path, selected_category_path, extra) self.ignore_first = selected is not None self.treeview = gtk.TreeView() col = gtk.TreeViewColumn(title) r1 = gtk.CellRendererPixbuf() r2 = gtk.CellRendererText() col.pack_start(r1, False) col.pack_start(r2, True) col.set_cell_data_func(r1, self.cell_pb) col.set_attributes(r2, text=1) self.treeview.append_column(col) self.treeview.set_model(model) self.add(self.treeview) self.show_all() if selected is not None: self.treeview.get_selection().select_path(selected) self.treeview.connect("cursor-changed", self.do_select) def grab_focus (self): self.treeview.grab_focus() def cell_pb (self, tvcolumn, cell, model, it): # Renders a pixbuf stored in the thumbs cache cell.set_property('pixbuf', self.thumbs[model.get_value(it, 2)]) def get_pb (self, path): thumbs = glob(os.path.join(path, "thumb.*")) thumbs.extend(glob(os.path.join(self.path, "default_thumb.*"))) thumbs = filter(lambda x: os.path.exists(x), thumbs) thumbs.append(None) return load_image(thumbs[0], THUMB_SIZE, THUMB_SIZE) def get_model (self, path, selected_path, extra): # Each row is (path/dirname, pretty name, 0 based index) selected = None store = gtk.ListStore(str, str, int) store.set_sort_column_id(1, gtk.SORT_ASCENDING) files = [os.path.join(path, x) for x in os.listdir(path) if not x.startswith('.')] files.extend(extra) for fullpath, prettyname in [(x, _(os.path.basename(x))) for x in files if os.path.isdir(x)]: count = CategoryDirectory(fullpath).count_images() print (fullpath, prettyname, count) store.append([fullpath, prettyname + (" (%i)" % count), len(self.thumbs)]) self.thumbs.append(self.get_pb(fullpath)) #if os.path.isdir(MYOWNPIC_FOLDER): # count = CategoryDirectory(MYOWNPIC_FOLDER).count_images() # store.append([MYOWNPIC_FOLDER, _("My Pictures") + (" (%i)" % count), len(self.thumbs)]) # self.thumbs.append(self.get_pb(MYOWNPIC_FOLDER)) i = store.get_iter_first() while i: if selected_path == store.get_value(i, 0): selected = store.get_path(i) break i = store.iter_next(i) return store, selected def do_select (self, tree, *args, **kwargs): if self.ignore_first: self.ignore_first = False else: tv, it = tree.get_selection().get_selected() self.emit("selected", tv.get_value(it,0)) sugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/mmm_modules/tube_helper.py0000644000175000017500000002437110743343012027771 0ustar janijani# Copyright 2007 World Wide Workshop Foundation # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # # If you find this activity useful or end up using parts of it in one of your # own creations we would love to hear from you at info@WorldWideWorkshop.org ! # import telepathy #import telepathy.client from sugar.presence.tubeconn import TubeConnection from sugar.presence import presenceservice #import dbus import logging logger = logging.getLogger('tube_helper') GAME_IDLE = (10, 'idle') GAME_SELECTED = (20, 'selected') GAME_STARTED = (30, 'started') GAME_FINISHED = (40, 'finished') GAME_QUIT = (50, 'quit') class TubeHelper (object): """ Tube handling mixin for activities """ def __init__(self, tube_class, service): """Set up the tubes for this activity.""" self.tube_class = tube_class self.service = service self.pservice = presenceservice.get_instance() #bus = dbus.Bus() name, path = self.pservice.get_preferred_connection() self.tp_conn_name = name self.tp_conn_path = path #self.conn = telepathy.client.Connection(name, path) self.game_tube = False self.initiating = None # Buddy object for you owner = self.pservice.get_owner() self.owner = owner self.connect('shared', self._shared_cb) self.connect('joined', self._joined_cb) #if self._shared_activity: # # we are joining the activity # self.conn = self._shared_activity.telepathy_conn # self.tubes_chan = self._shared_activity.telepathy_tubes_chan # self.text_chan = self._shared_activity.telepathy_text_chan # self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES].connect_to_signal('NewTube', # self._new_tube_cb) # self.connect('joined', self._joined_cb) # self._shared_activity.connect('buddy-joined', # self._buddy_joined_cb) # self._shared_activity.connect('buddy-left', # self._buddy_left_cb) # if self.get_shared(): # # we've already joined # self._joined_cb() def _sharing_setup(self): if self._shared_activity is None: logger.error('Failed to share or join activity') return self.conn = self._shared_activity.telepathy_conn self.tubes_chan = self._shared_activity.telepathy_tubes_chan self.text_chan = self._shared_activity.telepathy_text_chan self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES].connect_to_signal('NewTube', self._new_tube_cb) self._shared_activity.connect('buddy-joined', self._buddy_joined_cb) self._shared_activity.connect('buddy-left', self._buddy_left_cb) def _shared_cb(self, activity): logger.debug('My activity was shared') self.initiating = True self._sharing_setup() logger.debug('This is my activity: making a tube...') id = self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES].OfferDBusTube( self.service, {}) self.shared_cb() #def _shared_cb(self, activity): # logger.debug('My activity was shared') # self.initiating = True # #self._setup() # # self.conn = self._shared_activity.telepathy_conn # self.tubes_chan = self._shared_activity.telepathy_tubes_chan # self.text_chan = self._shared_activity.telepathy_text_chan # self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES].connect_to_signal('NewTube', # self._new_tube_cb) # # for buddy in self._shared_activity.get_joined_buddies(): # pass # Can do stuff with newly acquired buddies here # # self._shared_activity.connect('buddy-joined', self._buddy_joined_cb) # self._shared_activity.connect('buddy-left', self._buddy_left_cb) # # logger.debug('This is my activity: making a tube...') # # id = self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES].OfferTube( # # telepathy.TUBE_TYPE_DBUS, self.service, {}) # # self.shared_cb() def shared_cb (self): """ override this """ pass # # FIXME: presence service should be tubes-aware and give us more help # # with this # def _setup(self): # if self._shared_activity is None: # logger.error('Failed to share or join activity') # return # # bus_name, conn_path, channel_paths =\ # self._shared_activity.get_channels() # # # Work out what our room is called and whether we have Tubes already # room = None # tubes_chan = None # text_chan = None # for channel_path in channel_paths: # channel = telepathy.client.Channel(bus_name, channel_path) # htype, handle = channel.GetHandle() # if htype == telepathy.HANDLE_TYPE_ROOM: # logger.debug('Found our room: it has handle#%d "%s"', # handle, self.conn.InspectHandles(htype, [handle])[0]) # room = handle # ctype = channel.GetChannelType() # if ctype == telepathy.CHANNEL_TYPE_TUBES: # logger.debug('Found our Tubes channel at %s', channel_path) # tubes_chan = channel # elif ctype == telepathy.CHANNEL_TYPE_TEXT: # logger.debug('Found our Text channel at %s', channel_path) # text_chan = channel # # if room is None: # logger.error("Presence service didn't create a room") # return # if text_chan is None: # logger.error("Presence service didn't create a text channel") # return # # # Make sure we have a Tubes channel - PS doesn't yet provide one # if tubes_chan is None: # logger.debug("Didn't find our Tubes channel, requesting one...") # tubes_chan = self.conn.request_channel(telepathy.CHANNEL_TYPE_TUBES, # telepathy.HANDLE_TYPE_ROOM, room, True) # # self.tubes_chan = tubes_chan # self.text_chan = text_chan # # tubes_chan[telepathy.CHANNEL_TYPE_TUBES].connect_to_signal('NewTube', # self._new_tube_cb) def _list_tubes_reply_cb(self, tubes): for tube_info in tubes: self._new_tube_cb(*tube_info) def _list_tubes_error_cb(self, e): logger.error('ListTubes() failed: %s', e) def _joined_cb(self, activity): if not self._shared_activity: return for buddy in self._shared_activity.get_joined_buddies(): self._buddy_joined_cb(self, buddy) logger.debug('Joined an existing shared activity') self.initiating = False self._sharing_setup() logger.debug('This is not my activity: waiting for a tube...') self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES].ListTubes( reply_handler=self._list_tubes_reply_cb, error_handler=self._list_tubes_error_cb) def joined_cb (self): """ override this """ pass def _new_tube_cb(self, id, initiator, type, service, params, state): logger.debug('New tube: ID=%d initator=%d type=%d service=%s ' 'params=%r state=%d', id, initiator, type, service, params, state) if (type == telepathy.TUBE_TYPE_DBUS and service == self.service): if state == telepathy.TUBE_STATE_LOCAL_PENDING: self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES].AcceptDBusTube(id) self.tube_conn = TubeConnection(self.conn, self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES], id, group_iface=self.text_chan[telepathy.CHANNEL_INTERFACE_GROUP]) logger.debug("creating game tube") self.game_tube = self.tube_class(self.tube_conn, self.initiating, self) self.new_tube_cb() def get_bus_name (self): return self.tube_conn.participants.get(self.tubes_chan[telepathy.CHANNEL_INTERFACE_GROUP].GetSelfHandle(), None) def new_tube_cb (self): """ override this """ pass def _get_buddy(self, cs_handle): """Get a Buddy from a channel specific handle.""" logger.debug('Trying to find owner of handle %u...', cs_handle) group = self.text_chan[telepathy.CHANNEL_INTERFACE_GROUP] my_csh = group.GetSelfHandle() logger.debug('My handle in that group is %u', my_csh) if my_csh == cs_handle: handle = self.conn.GetSelfHandle() logger.debug('CS handle %u belongs to me, %u', cs_handle, handle) elif group.GetGroupFlags() & telepathy.CHANNEL_GROUP_FLAG_CHANNEL_SPECIFIC_HANDLES: handle = group.GetHandleOwners([cs_handle])[0] logger.debug('CS handle %u belongs to %u', cs_handle, handle) else: handle = cs_handle logger.debug('non-CS handle %u belongs to itself', handle) # XXX: deal with failure to get the handle owner assert handle != 0 return self.pservice.get_buddy_by_telepathy_handle(self.tp_conn_name, self.tp_conn_path, handle) def _buddy_joined_cb (self, activity, buddy): logger.debug('Buddy %s joined' % buddy.props.nick) self.buddy_joined_cb(buddy) def buddy_joined_cb (self, buddy): """ override this """ pass def _buddy_left_cb (self, activity, buddy): logger.debug('Buddy %s left' % buddy.props.nick) self.buddy_left_cb(buddy) def buddy_left_cb (self, buddy): """ override this """ pass sugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/mmm_modules/notebook_reader.py0000644000175000017500000001005610743343012030630 0ustar janijani# Copyright 2007 World Wide Workshop Foundation # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # # If you find this activity useful or end up using parts of it in one of your # own creations we would love to hear from you at info@WorldWideWorkshop.org ! # import pygtk pygtk.require('2.0') import gtk, gobject, pango import os from abiword import Canvas from gettext import gettext as _ import locale import logging logger = logging.getLogger('notebook-reader') class ReaderProvider (object): def __init__ (self, path, lang_details=None): self.lang_details = lang_details self.path = path self.sync() def sync (self): """ must be called after language changes """ self.lesson_array = [] lessons = filter(lambda x: os.path.isdir(os.path.join(self.path, x)), os.listdir(self.path)) lessons.sort() for lesson in lessons: if lesson[0].isdigit(): name = _(lesson[1:]) else: name = _(lesson) self.lesson_array.append((name, self._get_lesson_filename(os.path.join(self.path, lesson)))) def _get_lesson_filename (self, path): if self.lang_details: code = self.lang_details.code else: code, encoding = locale.getdefaultlocale() if code is None: code = 'en' files = map(lambda x: os.path.join(path, '%s.abw' % x), ('_'+code.lower(), '_'+code.split('_')[0].lower(), 'default')) files = filter(lambda x: os.path.exists(x), files) return os.path.join(os.getcwd(), files[0]) def get_lessons (self): """ Returns a list of (name, filename) """ for name, path in self.lesson_array: yield (name, path) class BasicReaderWidget (gtk.HBox): def __init__ (self, path, lang_details=None): super(BasicReaderWidget, self).__init__() self.provider = ReaderProvider(path, lang_details) self._canvas = Canvas() self._canvas.show() self.pack_start(self._canvas) self._canvas.connect_after('map-event', self._map_event_cb) def get_lessons(self): return self.provider.get_lessons() def load_lesson (self, path): logger.debug("load") try: self._canvas.load_file('file://'+path, '') except: self._canvas.load_file(path) self._canvas.zoom_whole() self._canvas.zoom_width() def _load_lesson (self, name, path): self.load_lesson(path) def _map_event_cb(self, o, e): self._load_lesson(*self.provider.lesson_array[0]) class NotebookReaderWidget (gtk.Notebook): def __init__ (self, path, lang_details=None): super(NotebookReaderWidget, self).__init__() self.provider = ReaderProvider(path, lang_details) self.set_scrollable(True) for name, path in self.provider.get_lessons(): canvas = Canvas() canvas.connect_after('map-event', self._map_event_cb, path) canvas.show() canvas._mapped = False try: canvas.load_file('file://' + path, '') except: canvas.load_file(path) self.append_page(canvas, gtk.Label(name)) def _map_event_cb(self, o, e, path): logger.debug("map-event: %s" % path) if not o._mapped: o.zoom_whole() o.zoom_width() o._mapped = True sugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/mmm_modules/timer.py0000644000175000017500000001264310743343012026612 0ustar janijani# Copyright 2007 World Wide Workshop Foundation # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # # If you find this activity useful or end up using parts of it in one of your # own creations we would love to hear from you at info@WorldWideWorkshop.org ! # import pygtk pygtk.require('2.0') import gtk, gobject, pango import os from time import time cwd = os.path.normpath(os.path.join(os.path.split(__file__)[0], '..')) if os.path.exists(os.path.join(cwd, 'mamamedia_icons')): # Local, no shared code, version mmmpath = cwd iconpath = os.path.join(mmmpath, 'mamamedia_icons') else: propfile = os.path.expanduser("~/.sugar/default/org.worldwideworkshop.olpc.MMMPath") if os.path.exists(propfile): mmmpath = file(propfile, 'rb').read() else: mmmpath = cwd iconpath = os.path.join(mmmpath, 'icons') from utils import load_image class TimerWidget (gtk.HBox): __gsignals__ = {'timer_toggle' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (bool,)),} def __init__ (self, bg_color="#DD4040", fg_color="#4444FF", lbl_color="#DD4040", can_stop=True): gtk.HBox.__init__(self) self.counter = gtk.EventBox() self.counter.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(bg_color)) self.counter.set_size_request(120, -1) hb = gtk.HBox() self.counter.add(hb) self.lbl_time = gtk.Label() self.lbl_time.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(lbl_color)) self.pack_start(self.lbl_time, False) self.time_label = gtk.Label("--:--") self.time_label.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(fg_color)) hb.pack_start(self.time_label, False, False, 5) self.prepare_icons() self.icon = gtk.Image() self.icon.set_from_pixbuf(self.icons[1]) hb.pack_end(self.icon, False, False, 5) self.pack_start(self.counter, False) self.connect("button-press-event", self.process_click) self.start_time = 0 self.timer_id = None self.finished = False self.can_stop = can_stop def set_label (self, label): self.lbl_time.set_label(label) def prepare_icons (self): self.icons = [] self.icons.append(load_image(os.path.join(iconpath,"circle-x.svg"))) self.icons.append(load_image(os.path.join(iconpath,"circle-check.svg"))) def set_can_stop (self, can_stop): self.can_stop = can_stop def modify_bg(self, state, color): self.foreach(lambda x: x is not self.counter and x.modify_bg(state, color)) def reset (self, auto_start=True): self.set_sensitive(True) self.finished = False self.stop() self.start_time = 0 if auto_start: self.start() def start (self): if self.finished: return self.set_sensitive(True) self.icon.set_from_pixbuf(self.icons[0]) if self.start_time is None: self.start_time = time() else: self.start_time = time() - self.start_time self.do_tick() if self.timer_id is None: self.timer_id = gobject.timeout_add(1000, self.do_tick) self.emit('timer_toggle', True) def stop (self, finished=False): if not self.can_stop and not finished: return self.icon.set_from_pixbuf(self.icons[1]) if self.timer_id is not None: gobject.source_remove(self.timer_id) self.timer_id = None self.start_time = time() - self.start_time if not finished: self.time_label.set_text("--:--") else: self.finished = True self.emit('timer_toggle', False) def process_click (self, btn, event): if self.timer_id is None: self.start() else: self.stop() def is_running (self): return self.timer_id is not None def ellapsed (self): if self.is_running(): return time() - self.start_time else: return self.start_time def is_reset (self): return not self.is_running() and self.start_time == 0 def do_tick (self): t = time() - self.start_time if t > 5999: # wrap timer t = 0 self.start_time = time() self.time_label.set_text("%0.2i:%0.2i" % (t/60, t%60)) return True def _freeze (self): return (self.start_time, time(), self.finished, self.timer_id is None) def _thaw (self, obj): self.start_time, t, finished, stopped = obj if self.start_time is not None: if not stopped: self.start_time = t - self.start_time self.start() return self.start_time = time() - self.start_time self.do_tick() self.stop(finished) sugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/mmm_modules/__init__.py0000644000175000017500000000031110716617376027237 0ustar janijanifrom borderframe import * from timer import * from image_category import * from i18n import * from notebook_reader import * from buddy_panel import * from tube_helper import * import utils import json sugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/mmm_modules/utils.py0000644000175000017500000001430610743343012026630 0ustar janijani# Copyright 2007 World Wide Workshop Foundation # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # # If you find this activity useful or end up using parts of it in one of your # own creations we would love to hear from you at info@WorldWideWorkshop.org ! # import pygtk pygtk.require('2.0') import gtk RESIZE_STRETCH = 1 RESIZE_CUT = 2 RESIZE_PAD = 3 TYPE_REG = [] def register_image_type (handler): TYPE_REG.append(handler) def calculate_relative_size (orig_width, orig_height, width, height): """ If any of width or height is -1, the returned width or height will be in the same relative scale as the given part. >>> calculate_relative_size(100, 100, 50, -1) (50, 50) >>> calculate_relative_size(200, 100, -1, 50) (100, 50) If both width and height are given, the same values will be returned. If none is given, the orig_* will be returned. >>> calculate_relative_size(200,200,100,150) (100, 150) >>> calculate_relative_size(200,200,-1,-1) (200, 200) """ if width < 0: if height >= 0: out_w = int(orig_width * (float(height)/orig_height)) out_h = height else: out_w = orig_width out_h = orig_height else: out_w = width if height < 0: out_h = int(orig_height * (float(width)/orig_width)) else: out_h = height return out_w, out_h def load_image (filename, width=-1, height=-1, method=RESIZE_CUT): """ load an image from filename, returning it's gtk.gdk.PixBuf(). If any or all of width and height are given, scale the loaded image to fit the given size(s). If both width and height and requested scaling can be achieved in two flavours, as defined by the method argument: RESIZE_CUT : resize so one of width or height fits the requirement and the other fits or overflows, cut the center of the image to fit the request. RESIZE_STRETCH : fit the requested sizes exactly, by scaling with stretching sides if needed. RESIZE_PAD : resize so one of width or height fits the requirement and the other underflows. Example: Image with 500x500, requested 200x100 - RESIZE_CUT: scale to 200x200, cut 50 off each top and bottom to fit 200x100 - RESIZE STRETCH : scale to 200x100, by changing the image WxH ratio from 1:1 to 2:1, thus distorting it. - RESIZE_PAD: scale to 100x100, add 50 pixel padding for top and bottom to fit 200x100 """ for ht in TYPE_REG: if ht.can_handle(filename): return ht(width, height, filename) # if filename.lower().endswith('.sequence'): # slider = None # cmds = file(filename).readlines() # if len(cmds) > 1: # _x_ = eval(cmds[0]) # items = [] # for i in range(16): # items.append(_x_) # _x_ = eval(cmds[1]) # slider = SliderCreator(width, height, items) # slider.prepare_stringed(2,2) # return slider # img = gtk.Image() try: img.set_from_file(filename) pb = img.get_pixbuf() except: return None return resize_image(pb, width, height, method) def resize_image (pb, width=-1, height=-1, method=RESIZE_CUT): if pb is None: return None print "utils: method=%i" % method if method == RESIZE_STRETCH or width == -1 or height == -1: w,h = calculate_relative_size(pb.get_width(), pb.get_height(), width, height) scaled_pb = pb.scale_simple(w,h, gtk.gdk.INTERP_BILINEAR) elif method == RESIZE_PAD: w,h = pb.get_width(), pb.get_height() hr = float(height)/h wr = float(width)/w factor = min(hr, wr) w = w * factor h = h * factor print "RESIZE_PAD: %i,%i,%f" % (w,h,factor) scaled_pb = pb.scale_simple(int(w), int(h), gtk.gdk.INTERP_BILINEAR) else: # RESIZE_CUT / default w,h = pb.get_width(), pb.get_height() if width > w: if height > h: #calc which side needs more scaling up as both are smaller hr = float(height)/h wr = float(width)/w if hr < wr: w = width h = -1 else: h = height w = -1 else: # requested height smaller than image, scale width up and cut on height h = -1 w = width else: if height > h: #requested width smaller than image, scale height up and cut on width h = height w = -1 else: # calc which side needs less scaling down as both are bigger hr = float(height)/h wr = float(width)/w if hr < wr: w = width h = -1 else: h = height w = -1 # w, h now have -1 for the side that should be relatively scaled, to keep the aspect ratio and # assuring that the image is at least as big as the request. w,h = calculate_relative_size(pb.get_width(), pb.get_height(), w,h) scaled_pb = pb.scale_simple(w,h, gtk.gdk.INTERP_BILINEAR) # now we cut whatever is left to make the requested size scaled_pb = scaled_pb.subpixbuf(abs((width-w)/2),abs((height-h)/2), width, height) return scaled_pb ### Helper decorators def trace (func): def wrapped (*args, **kwargs): print ("TRACE", func.func_name, args, kwargs) return func(*args, **kwargs) return wrapped sugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/images/0000755000175000017500000000000010755626243024056 5ustar janijanisugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/images/Animals/0000755000175000017500000000000010755626243025442 5ustar janijani././@LongLink0000000000000000000000000000014500000000000011565 Lustar rootrootsugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/images/Animals/image_justi_h250_w333_lg.gifsugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/images/Animals/image_justi_h250_w333_lg.gif0000644000175000017500000010354310716617376032442 0ustar janijaniGIF89aMJ63kAr5 388f39M33pp3 flfͬ33|lf3o;35,M@'di]ר )x-%- P:JCj80(ډZzbOKFn𸜽 tZPhQ LzRVII0Ox"aJRRiw9B A $ }Lg~"VN3 T O} R~2wL "Uъ/1g W3$/0h36Er;K" Ft)$r\p8t$ G Jd.){BSp]  h(HEK&Rpg D 6 CѬ!YAm5C AIJE0y[¶;9@` )Yr8Ԓ&OS5VAd !ogVգQ$>2.'Y) 4g(tp_5 -%h&oѐcǦ-riCsBkn;e-/O؊歭`Ko񋿓O]K5-W}c -4yȨq@|#$D}D SP9Uݣ}}0R<– ^. ա"4!V(S W%LxVË$1VTQKFq PRRSlNgz5pZ M,el×Ŧ.%>0 + t` xCB<&pѕVH5,@XPi3l }l!2 lH3oFjbG'>B t`,l`6lp t@lpA x.rgV+M0~s:@TcD@ Ap=05 Co#a /!>0@^ȑ;r`rxBl<;H9o@t]H,uvNel$l_DED ލ7Д@PF.% oGq}AHb @U90AqqģWfE#M܍n4=Hk ; 0~=+AkzdZ$"EqA \`IQ ֥< Ta_%@3!72cQzi=L5#LW@ܲ?v oX A6fϜL9F AF4sXa# `t{^'-Ѣ% Ԑw˚u6;i xHJ OG30JE:Q E1Q+BČT#zD=3y&Pc, T=w"m !dT@Ƴ-KY (E @KڲT,@%|P&tIƢb% / \G7݄t 8g^I p ' lٍ1bH#3VHS7t(DU @AC.JPY* D ; 5VP7KhnP 9LeaV v}G#WFN$U:}%m oD@PbT 9-XUƓ9`Tŗ+ *JCUZ5+C៨FŸcL 0k!k d,)A'FQ{=oPq*c&#t ITp8)< TAv5 u&lGŊëG :POv=!-:˫N2XJCki2@eГUE_ j:4;OaaaK`3;:bN:],g-'Ԗ W2#`9 yD4P; P!L$Q97N59H`)W226)WPy#0bM68KEe:$la#,~2IePf{:$zFB(dWf&+ͥ:CFcWXmh 7+  Ba#h3n#PG0 /۠ m?A!Ybkn%qT `=0 M 01"#c44:w:/4u5I;ԂXVbHdv`}XTnK \ uaR95O$Q0?094hm% ll~bmU~ USA-=I6TkiL:Ljxo5Z4"3z;9utNw#&fJmME0 > aݳdQ+VaDe7pr1 G pOt:XaDd4:o2K`BD$XeVg,75YQGy8K2h5H v~P#Y $&2YTx0Y@`IRb 7!FnIԥziJtcxj4{k`5 t `2DD* "zkAN,1$@!Aila TX% .w @B'b˸]HSF#:@ ճTP8Pkx"-e4wf8Jl.! [6gƇFaN,RՋm!ܡFk'PgP|?!R]1)&!cD*%r6̳|66i`JB@JPT@P jZ*6zʗ*$Lf %6ljv!ffXT!b$' YSrG" | bu vaiB n#@J@@ pʪZ f}0hڬp>dP  ʜ5,!kJ ,*,20+@h6کn'P C>Z +`Z* -psm""O&uPJYVPX$vJѠ':z'{J,0Z [' @3,`4ڷڳ'ڳ4j}|{` [, -k,61w_$۲P Lۯ9۪ʴ0˸һd7AZ0fqf @TS;+~˺ۺ!|;4jBP|2;+J~5˴J ꩪJk꺞ʷ$;̯*, -<ۮ싱4[bK,|+t ,8;z~ĩz7+kB;6ܲU+<2ʼ,{s*+{=۪i췂HL ,NJ9\Jz>`,Ьʸ‚K%4Ӽy;{L}2ơʮǵ}|˯C,ǹo|ɫ≮LoLŪ˪., ˫첈{Tf[;ڌ7:+BZʈ Ý,lqB9;~ .˛B|촂4.98M˷g= 쾩L|z|Ϭ l= ƌ~ܯM,@p>mDgq5ݚ3xk`:`f)Z" 9H jm%` l ϱ U@ @&v2RV9" """c1eqY $fUc%#OF^س7ۣ)2w HT$*pQ@r$ YnxdC1 C>c)nB[jr R"Q#p0 SN Q\mQ>Lum p2 dHxltS#* y%`VM`1*'x5 )<GqTAp N&e y}&XFyQ2A}I'p"`2UZ",h+yqMX$& & ]E~2Xf'ZS1 sZF^N`/R=R fQ9Md{0"0C6 )IQ;8D4]-C#4 pEonf?YVe"Z@֣$+h5Y"LH r Q>H -5`JX1.ӑNQH;tk5tK:C;gscb`um68苙؃Hb=bD2nA T!6~ny)HA2iRG@'XTrpEM)DP .Y5 tʲ9T{<Ic}]׸[75-5i D@( `P ȧ,ǩ=(糩R4R&T\t~q"vMDU~<%!ЉJ5QY9D8|_߽>r!GqsL%T8WHL̲XpAQsRI%AK,PxȊr,Jaz \ WHe1G"[a8*&sh1mFޙqY.ـ#dGH,}蟺 یRnWcaj8Qo0TH!RD |ɱj$` AL% XE̠K 1R%d*IC t NJ1IBX `xtب!"v8 M@YR4 @I@zT exSIR60 #wuK`ֲHq[䏤<܋X3LD(QHC9Sr&$ WN3!Rg%4(#uuJ=( %Y˜σ)LIqh1[JxP;A m cd< /V G%Hcj 5e! bf"^ ?8+O 4id@z, BX|"t4!03(rQhȎ-K 4w" C0 3NdZ^ ؊7 ]Q(̀E&dNBR\0!< KDA,xމ\X(sRJJXLFL.]7 ExY8ٽlj9A7/hNL  ,P>7 إ \@9XS-n=&6ՓLwbu ehjBa|@_|j_@R,4ے05XyF|l`CUp3ly 2Qㆶ*qegH"J,$.ZD5Fa3 $:5p1D8&3.$H9VڦX p>b7d^Ԝ\;=Q=&,ՙ"1\Vp4_Q@V|VDE + `Q;F0ؔ_]Fywe&@q'@r xǓuo0Rb@ q `r72b;3B;$S2]LLjz+ Qɵn !מ8Y@ P\DMj(3#*ebM]EKZ21 h!_!IHFdKpr4@{E@z;=@^o ӿDHdR4"L `D%\ 'e6&SxuQ`"n #`f0&@ #}UxVP$#YL" P!N[8$P*@קX;޾ڹ# X_pAgPozCi=ZGWx+cz F ^"L@-X9=lWs1h|$tIXhϥ@LY,)@DL ^M[O ^_ V \_Ә \aj_-!qh~!! _Qa U\> ^aDBVA)mHLT@HELV !a,b"!-`TL}0]_b-R/Vj:X n_4 Ec0N9_RmUQ,2c,!8!~#Cj!8@2!;4"R#d/5j_4#O3$,rd[$V$#-B"!=V Jc 0$@ΣP[.b.~-¢FWޤ6 GR%VF"8eX_% % *!֡Q%_"YF%,<^N"rUe%G:e$BM~eT6G$jGNbb*&d0aF"ifBfmeYRܙa\~G '%7r=l*a XgV% hfVfI_z&cnVC$\ޥFb8J%7%f@$d'qjdey~#hcG.a/zO~_gJ'b&7d6gx$Z&{*aVa w%H&{Wֆ'+mR@A|j*LhD<glPύnؑi:BiJ)V9Hu$CDwX0VH1\A옱D-j5n)CuWvX /L[C .YbbHL@h\ȁqdx\TClpjlm@HAsh* jL X.5XZx CvdU8kVj@E?|BAJH')g,K$EUp XݐBHHhmMXz4F0Ec@vd,dXpimxUvdlH,%.i4,z`'Z`I X$.#u0ȫ$8PŢChn,0@)RXXo)1ƨGV %i ntBp" I|@h+ۀX8siX|JkqKJiNF Q*ÀzI(D=ڤUhmMHʍʯYޤ90XT$H@\MNPl0Xt'2@CUک.0p|Y#,mUJTꨡ I@X,Hmž>Bh'E̘/!ޑ,HTdQ\A$Gb("qy=tBKA.nf$H V)PoPSX EvA)BҒV씍qclЋW!ÆiSXԍDpdD0 AM GC/  Uů/n?JxG~ԠЂhh/ I(qeKSoimɡPrH#fSFqÀWe.1*!k*IݨM5B-jtb$R*;.Ƅ¶iRlM@HW @loE \sP|l 'Ą(v,Y(hFKtasXhD*hRYAIlR0]RF$}o)oj/0(0ה+Rw 7eԜ#A0 >u&\'vxsߎ3HbgphݤMHP'U@*l؊5?Di.u/.%AjDWMmL,a[! Әύs/Cd)/Ǭi'lG @$.(L,twa4Y||Y`4uKqك.uFk[_)qe-@6}E@@겎\S, '6#qrZ̊:E&S?o2۔. H4U/  dBMt[aE_ xZxт f72hFuzfiN&3V@e\ V4G 4o*OՌoBnɓ)Se|6cLdC$(Dz "$1st2>bo;NHDc F"> $77'&'|1='kj~M^1O9?l=rGv7 W; sh5Ȼ$` n/,Zll1Q1pi-i*-!1Xb -iRD] o &a O`8'\4B/aM1Wl4ZT$&yajUHLtxX jCj%n3#`u<4T m4CB]U2Np#4gN$ `{ϲ2$5p' Pqoz\4Ъ @`Arw@S^9`Oq%_#;Zq$62$wXv SGY5%]"D;0E:RNu5Îi!@m"QЉgG_ G5l=j5Y5k6 x ٌ݂!8@8))Ѝ$`[`_QoqMmL\^{GƬ\1UY'Vv9Q TZHe [C"r)J_4"#|KTDdWQ TrWX7 (yr׏xq}hE, cԴ.sr\ъđ Zwi=}Mة"H{rL'd4@wtNl <J0h14<Qh/X6ixx\2mJLk)j呜J<1DXr~Ĕ oWV"$.2pMdBw u0w\h썀jEq4kcw5bw9PV)tTN1Oy<$LRoFFa+1fN!n֋heW:0hl( m{N ֗t:#!o4tGPފf.Sb$`ڳP%Jpv$Zg YB,kpp۲a1&E&ȭbn@պul<&q3T]8`$pvWޠ\8hOHPAK`/M`7s5lU l$G f7̅[ "jM6d%]ew8Nv]?e \ baH4%i*zDNmK\ZQ<r{HWTg[W[p7u57'C;H@sppM 0J?PqaKӐ Y YRM#PuM0')% hb%S> 0 nWtKDCX$z30lQ%ATܐ^R%=qܑCW kYsvFtc5@wqנf#/B8\  gJf@XZ": PiF%a 1eN5<2t wvM` gf)GjFnג#P7hvh8k E@&D3)&TEa?'lׂjkqց5B=#(tJ{@l7( Md?@UQY1! jqG&j"] xO·5glFLUXBE'eRIqB%`pqGqM:buJ61<9@SQ a0] -rK w8kC2 p&c&A$D1rrmhR)`WwȣI5ktQ֕g[zA؀l WooQcA`qVGC 4C#$ R=[Xm,hQ$+gX Sݶ: Rq 64%n`*7G &@5~c@)Qqpv[Q4(2 v}&Ap yKP+!/ Fcs~`&DDs) X&3˒xf0lNB0t wP Q*^rr]`j#jD`&%e&9H@Bg=|UvgqWPygQ|_7%R!"X6Q*1FG>(As6-{2-n6e"Rߴm ` J"`hKTDZ!f²("ӓoB[ vM`F(UEm?@T37 Y7E6-6+h 92("lFh)eV#"BӑK 3G,M.J6In8=;ė>JOZJ@J!VfEH i#֯ȡe#.j>Ė%n<W7pREVnzIPjM/10"A>oSbZE9 'jۤWukoMd_j%t"4al)AqEj(X-0%3"0q-@i803@6T'Y^eؤ/wgDBx]s6%lW1&Fe31͵'#u7)QNebݡ}7)/LVwmMa&@`z, 46 ; 6 2p,v0  p,5GqBg2]0^?ӔQKP;cwbʷ '`G`Yc; od0,jxݳg.z. @"6tQ:4x,=&`׃ P В0#jv0N>N!Ƈr?ŃٳT@|@jd i HQ,I$Qwe[ ME~_DB"b~k)H-LS@EqR%d \.!+'ᤢqq?@^lQ>tP\0D{R^ ,Tˀj46,] 29q$ðl( ֤ Wm`J `)=AhFv"`dPxGiaL@R:6pK91P@VL}:@h-pT8QIK>T0?DOLqBأ:SiyqȒZƱq1Y~ԏ1UެGTGhA┏brJJk8 7 c/@Ѷ\-eM"M@r׶muml`J0@$CyFWx v@Pgh90mrtզMj S 0H? S'p`L omP}w}}ܻ H5MRU<؆)w-mt}]jp@|]M{'5 kp5ٝ"qܣ-YR3=\wySBAqS3 4Pٝm :3:mS`""==ǻ=伭* AݱgVl `QlaMm =M@eݟkpxeRKNҶ\ ^ 2>ݨM2a },G#r}*0X Г%  4+mhfvH> =.nmu%i0泎>u~wm瓮ٞw@=왣KvZٞM?nˉ0CANvMm6}B0YP"0^n1ʀ@S#83.s.~=>`X cZQm{M%s׳ׂm]]0V\MI_#ع^Z.w}=NrPp#AǭϚޣy|OYyo?MV!-}|x=%&~}ߘO_MZLL)m޺b?|I?x|?۞Kr؊NN U/>knx?Znn^/ 턮"o @TmdgVbTVu*m$x/"H",hrEfP /r1.= %8׏ΌJF LLFSѐYИdfEUV`gV^hgl ZO DŇ葓Zv^nw鈕[6Y 7M)y), Y}Z6ǎ$'nJҴsJzٮ6U$Q01dԈgԊE4 _?Ueڈ2#lhdCFMH}~6)BΪU \R05;=M+F!u.lX΍X5@T @ @pb~dKni`F[rQeM$^YHrGj@*njj,=¸'ww gY-+ 竩lv˥|/ī>B5" J>Щ $:yT cX*h1H:}*$'Z,soZ&5_+j"gR[I~ ͂?h#Rmq'wk`96 wޖg T'ݞo4ئ5iKQ".wRBv vv1ql 1\+70WS{s/U+ғ0;gq[V2!Ն73ˌp,eSk&5@ܚ9Je+zIYkO8,1Pd غYȓUS^4;Ɍ7]-UKD\#aNOKVgFZ5o#D#0E4>`1bN I۹ P| o\WA!HH ^i+YS `5-H1 xM \[ QY#IsdNFjȵ6I)2 &C&ƅr[$$G ?͔J"Am˄K&1*MeJ#%R`LQT*16 $@GouJGVf.vzZ@NUE_G.Tj0"W,Y3p.eSeq j+-jj*M "VM hL Uk\<yJ%*)w$<-k$dD)QȸH@_##p@HF[2p) FoKp,q-,0&ٸ|wHi|FLg˔ h] 3 %: G .;^QSw@?` WƔ$%0ou QHVb%Ok\l?-bzƱ 6$*NL*du Z`mHtoXm\_+y`J#IkHF:_&4M=+ .2m,- zC;Y%*JU&02]={ݤ9[bv)y]Q%!+IT['T-պeMqzm50z4mo0Iˊ Nd 8Nf.ѷ8c'yd5*H||&Ds*;LC. Jtd2mF٧$@e*E {u0'_ҚcjNw>5 Hc.Tv6s{{O6L8ILb&řuѢ-vmhL{-)cwl:wZxs7_?]7GTpmW^ǟ{HšriؓVVd]Pz|qTJz!ަ :rmMďxIT˭1ێYeȒUI]ʿ̮8ɥ0  OE%äIٚqX=P,㬍KZTKH_옦 ]q(@J)P霈) Q Yuʊݲ\1b9 `ؑЅ YcFU@4]㤌X <|Qi=-VIϘtS ) HP@$ݍA@<@ ОdKyic=Ѽ4 hU |H H65 DŒ\h )N,TNTaH5^m#OW9 @>N4uJ92ќ5FDISN^Ѐ3 Bn(AuQ,LR|+(% P xIpȼϴX0%NQJ'Ӌ׳NIeI@ ؈tGFOP6A$Ac1R@ !~n0 'p?1̘\LIUgyl@ R,ԧ k6L@p؋5@42Qo  >n ݣ$T M=d.K89aHaύӍ QT|T-=ړ`~@}~@~g`vttzQsNWe܋H* (f72̈:Iȍxl2T_ŋUͶ \Y*eM$"ʧ MDfic-9V^%%cH!>'> pBšiG!O,Uy@d5yVMe' - J۱=[\N! eIF̊ ʿ"$&zU*\jOJgj b !̦@ @~b@@Q,lGKY'KP;VH:T@M)A+R@\,qE0D`<S9-  (axԑJ2ڷdmsgҳ B OL{BZU .JzEC>5 \`JuVզK\ W.GN0HDg QX34L7MI RGy M2RHSL Ԅ-3yıUCKp)Ԁ^L&ThoԈ田ƘvC, \QtxCM1~` @B^.bu .LRUlA+ įVH`x=1p%&V[42 "r >h" %I^!tCC!d@^9"Px +ݐ9EPЯT1uz *E0@%i0 F,fKΑJQn`]WAa@U< A$!FvE~@p4@V deMkY/ d @$tr%i`P@D&m }bR&(̀!ZՊ.hȹB. $&!:r@D.`VU( #?V FD:kl=cݧZ%ݲ&@"p8`Q8Cr3!FL }8daPQ Tʑv 88 V &5%VW%,b$Lp^ŰӓjmSHFrx֞ñ׾6-4@=|@c-+>@e%wH1I]'4LY {>8|n:|h/.;@91k{`nkv'%F׻ Cf]9 ro#$ud gM\% .EA>|"0p5@YΤ-ƕ ঘf˿T Q"EMJȋr$I9 &@ ) D4t:Lb5,jzȦMv _,4 f0B/Ҽ\JI]NА1dtHf_Q*(ṅA0e0sby~anXR` iw= Z*la:5su*-/HHt􃯣ڒβ!QiDh7(refToQgHUB"UH 2:BGdn ҝ4xرarpk3LbjHd(5GAHi-/qNMt!섅 +A@ ..݄Tبz٬}@47(b*Mj01l nA1%A!!ggPz!{3/5w|6w NdUc \upB7 ~u `> (^@w-NQ"@6jHPVqdO~PF]TfHW3X `R4vuIJzw)tR2+5T"=4`S>t,?z91 <N@C:pSQG`&  WHdUuHb)aB8IA@°J=q+JwXp2+P!+Y*C/HAbvSyZ @$u}C:!%?䦋)SS'"ap2  Vq&yjn{~/!A!ƕ &e0J0僀EiPsh{^H!fA Q#18Q 1E[W.vY4*- B zR'"pajt8')&DO7WHzb6S:@)F p2& kr+P`?ؕܺ;t")!!w JS;/J<$pV4,^yZ1bhdc Ŋ^A# 5,`[yF: 1}9 ~dEH__ap%0U\;a.P U6/DC=¬T UBf  9`htq %NE?@ dD}E;AtUj14|oJa@#C?]͹ ZFGQ>9BVIl&KHӦTv@nfy@_ CI`Ja7]T&0̨0cJk !zGJp2 -u4CE:q[%{@koDx A=N`ә曵%`Hh<\j@YA;TnrijlbZa&LevASD؜ p& Tt %,A`&AgKWH{ P2҂ OaW< ӷڨ2~)b@9)2rSUR" i0<AIvAEBH?K`IQt6anF\7c3|@[_`@jH @+ MVvZ͠C\œ`8'7Cj!g;4,8o[+"\pu9Pq(= J&]?Njq6ʕ{_ -?G@ǁn  &\vl[P3Ҷ d@!x5UqE^'IFV s20ZC{8 :+ 'F\( YYR0M{ym9WOI9h5zg J̵?IFJ roWbc|Î]DF8B>$T5?qUVh}rvJnDnphTZ^bfVfppD>B6nx~J:n"6zhz8@4Ț84-uu\@4T(}5@44TD9,KX!8(@siA$@a;hf(0bD4D`!kDn(u!T6Aaph@PR-j &F *I c5D 4hp qc\[掬"D@B;!aПH\QW \ hN;"i\tA`hj@gn '?tْ h ~ :ug0{@6p>Ϧ.H0sv  sa'gف)\Y"h1.P Nf) GB w@@up4`c%x51Y\$,y|ܥDG/$!V j?dBkYAصL* 5PdCD2Q(̡E+N,Cl%⣎,Ŕ'3uI' @ܦ@>q["6Xn(y$$O܀H2lM͐ך[&:b(t{¡f``k}g^0]2L8vF#X'*KYmh2?DR}(NP=kNtu8a{JX4!dIJWE۞9A׃Y$zzd8k@C; ]Mdq@qĬ@<2It^FmȞف]T@4$5_V[X mXݔDCd6Y 01¡ `t\U@ \`@ $` e Q\$FVZa|D B7Zd  o1(H]YYlAP4o`#0iu H @XR=oюrlK5 QbZàOD!Y8W `S 5IDsigPS6`MVO @i(&Ra NBI&$b@t>ͪ aJ Eqq0?PGYS) T@M  !3XX@#ɤoQ 9ƀN#P9Œ}5-5ViGq<(H$8GM@ P@PVR@Ti%iWAPI8dAx|fT@ 5($7@J%cV8id(ʦbƖY*K!Xh9h & IqZ n ij&+ o,m?>.JtjecR \gJ=n\ @Jd:@ :h,3|LA0u))AU^%m̭E&4mZX* }Ya%JQ,AvV:"xɚjz,J܎h =nNDy dlf⼮V/%,jx\琒y]Id`A/) 2#Dt Y&>0liZdp3p_jo(r[1wlr>nNcJp1%+R]l0J)nu i2 OmopWTl+D 0 "z@܎r,"j %HjnAźh V0ʭo1 K# VlBpo%mb _IW9l̬PF0"r_^~鐂sUh,@Pl ëU"Xؙ *) J ?sC3* 0orA-WqoIhB+;3*t4ENlGO3.qԭpFp枨J jXpNqBK_"*C++! k qB, xe7q /*3pn_/ˆ[ܾ0kg`6-B?lc94'5[,3_uz%SI_0ͱξn"k%rҮ9#rlh_1`knlr69j$ԅq$S$oT@Fg4Ƶ0tgsf52eSt`vs0#6.]5pJgq*6tөwe&-"~0u[tw7~f-+o^hjW7Q3\kwqTUb$nb0vlw芨oY5uC{=g>& wIkZWbYCC.W?2uǴe~wv|שo+xFlb x/8/߶\c.K$txve[1 j7ʲ0wky W8w8x␍bly"wv7*9vJtq?8wvSvx{sבʠnEOCϹJs&`0NyS˶&:/n{3ox+K]z7zz7祓pD#vKx _`Gz_FxccΣF B9{ im?x`+*j92\&reϷn:~on*y:E. +6av7L^C+tfg;綶Y{,oo۶m7|Zu2tR|5t;<2,[=$2'29nf_7ӻxF--+#9܂Vn/Ǝ*D{[ɞ|NЏ>ؓ/SG_'0Q&㻰oAc.ms~3s\orno~λp܏%lɢ`Sn+Ob>/1&rw4Wt0XhQVI52Ryc[WE|Q$6L[˵#YBth5t)8Fk^w{{ OXMqW Ȇdׅv34撤GHճVFB("7)FkYj6r8wŹF5zGD9UzβVq4t!q&Kjzr  '!BCڴPTE+ViLsIzD|eIKY찐1u,WD:[I`aPQ'"(מ~Ypw13e6M2^{bZ.; e)؉LJU{DΠ|ґ:jT;LYcr/hMC: Zۗ;6w!PD ["LkVk+DS&t,>(;7RI$}~s +ṥ.`$]ya/SC{Bhc{i\v (RWGʇJ&)!L  jݶ<9@b x{%sa vh6TMCMMkćB:v#1E4n&q?Um6s" em%ytwA.X,xB^JX`W~'@TqI{w*JY'%v hlezV eWLѦyޖ;BYI((xpA8NBd9&{qX^l['%9LA׉)x_?WlX FHx{&pN !G8? 9ߴ#v+ Hx3?5ِ{e$GVp7 Ўi8GqFy ytV@<0c4SIŋÔ/XQWP}k`vfxSQ+ qyYsI U<jHirqX)YM*O&erko!Ykl(Y PH\eٙkɁ_TW4cV%8wbF! @L5/61hI@{b[2^WӜeVmQg eٹ~QwQKY]YךJLoh@ŸyA!I)_BR_Цoʅ iImQ]r F\….JJFSt)\0@g0J SZ•Ny'N( ͰPP Y*Wuʚxլ Wк{:P2Uڬ ڭzDjJI}* w`J&6;PD b Tа+!;sugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/images/Animals/image_hsnr_h250_w421_lg.gif0000644000175000017500000002145510716617376032255 0ustar janijaniGIF89a~}\I33333ffff3ff38333̙f333̙fff,@"di(p,tmx|}fH,n~Ool:.eI&uzxL!4Zn;W2yST6Eb7@x@BiTt%@H.( @I&#v<@C DƎ@lxviڏP]6}w v笱話p"v`Tx.H0$0v*SU!W #6!2CL+ȱ6 層b.X*P D!Tudz;tD:x-77 cD돮cFKQioߢ=|xj (&C="Pc{Wgh صQnIB#wTgn?6سc@{wqמ _i@g%fPOߟ{A'`z&(^t&V(Y8 Av  y|,T{*Y"=h^)#2< x{Kh1GcɄ6B%5.D!.Hve4@E:`4f^Wޔb\Ёo`_'4X]f^f7gzoO 祘~ ;xc:^ W|p:sz{[ ѩf*Y3%ȈhTm63<w ڑnDkn8ꬷی|}/ɫnW C%Hķ-u|#ݗ ҋ +O]|Ѫo_-:{-JSn4݁82d/Hs(hMrh^H@];§Tf #jcZ- [) 3cCN O.3B[V w&4x`ҁ4dn= V땀6=/mEї *:px]DXYi%!~ǚIy%59tf'#I1 L#9ޅQ"@9#gܙ׉܁5Yɛ0 B"Uy )Yikǩ r_9P1|z|멚or! `ܹ5$ Y`*0g86- b +%*J %gہ9fXFd]VZgT*">"1M44 2~_p@, "R:z7V[n!h}?ŢoңP*%!"I`#1,Cc& 2|kuFg2g>fPҢhL b)D L֠ Ee{ʩ>Zex2 , GfjuG^`%O+x.Pp]i.#$)Y&4b@iڃtgtp%. Ȁ9Z" C2V*hs- ƣP f j)oa  l`BnF.6c,j yf/ö -jh"%Cb6'9+di#f(jUx`jMJI uNകôI[QI0G2#/ ;[y.63pV˴ot'4uRF Mg>න:]H]NDgwH<EUtFi#% PqDxlD@I/ pB{4W_;r?DʛD5+gm;.Tt[83SD68$c[@g:7njKutpD{3N$3l{@6 H?o4s\<-G3|s<3p =<Ʀ9I@@?hq0-= I3N9n I >w?Np Y4pK3?N/5ײtýia]z r@7g;ē13YM`BCRuA3rwē.3kdj<-wlS75Q$A@IPC6B J ȳj{l7xb<73QAtC>fSpǃ; gʻnr6svCpw ǑlL{5T|c޼Χ RdSDFXh0\< <,t w6Dh sۻw0=IFNљCD> 4"#zJ _ҰW 6,9=U0zgkӯDZ?є9&CM9mΎ6aD J@ݕ. gF]LZMH^" ed|^b_ =IгDz)d7+4׳ըp$G|N@ibpmؿ!UEDOuL}Ը]/(]{7z~Fzq$/[v-s-_4[HF) H dj!*)tNU Q`1Wu Y ˆOOvu`YMU ڄ .}Lj3Ii'0pm+؇2V&d6) 8d]rQڇwP8).uVv:?ݓۀ1JjCXTU_) <:oDPGٲRX0xFXRAbQ凕~݁^^M~J^q%ǒKHa w5A3 ~;:JAvxM C δ2hR-yHdi;l=aN兽/. Sm1.YN~$:>~DNQ'Ύ(>6^@S&xz؂.à;/N{p3grn!a5 Q./aς y.f o O?`.0眂+ӵd"̻Fyxpzii}ݠ؂C)$t$Lbgk_pSdddKbW?p4k߾5K\8 mE# ~PZp!Ar/.`(q"8x/2Lm(dX1-< <pɑp?+ڹC;B+X.dȎ(!-H.\*[" +*J@hDdњ iR Fk6#\r5nht*_vpPb,ၩZֈ@P܈lF[eRvw4il!s359Q 1Ե:Ҿl-|8q8ޖ]7ƌ̙\r(nj޿7s/޲5ǵ~>n^;gց,JԗxY܃!uA>-u,.L J6^vᆲt@Np#☣2_D"_o(HO#_>ABb(W [(I|H$gy)DY\o& &U{iۄVQ }CTv ficM%7"yJ!iBRhIZkӔC~iR )mjC`Kh"R!'z.UkCHЬ°8egmb}::_)Zr[︨{9f­Aiڛp^Y7Y8v$Ƒk\#C/6w4ز*+~pIK2剗>LΨy0 :>2yTp՜Q\5Y*'6D^ ݦN/0eZ`[rֱ, | vmSJ-m2Kain#N2IW\Daמ!V,B/n[TPػ 1UT+eqFzmݘ{x 's06ӳTh5G \N ͍ 9ST}D n%&V /F!{I"&m/Cz*" @Tjˑ!j`e FAT|Y @ F #$x`%3DAR `!=38P#Ǜ>:LJI# 8e0>P!@vq:H7o$cPH </ fb:-H=` C_#,QU`>BGl `X3甥 (eFZBy\HaNz`ۼQ9/*Y9 l5 HլaP^tm9[OEbBbf(i&QtBdV( PЕ EHTԢ{QtH")UAJC6lmy$9 Kyc2SB<(BUgjTjW`6[QX2( W{ߐV*A|)ם]3wݬ&m0?7 -iK;Z6]-k[Zz5m\kՎyo9g\)[#;RAS(BwLbQ:mjHp7um2󲶼Smi+[%ԝ/RMRuEncJYik#xEIƢ QRHX"u]J)n0[b."/Fc<ww0vKTX;<8^2]nl lUMNUl39j^pWREp,;9z3,BEu5fWϊ^4h_UuKY4;O;_z5XP:ժ^5KJgg Oo6ލr[_;,6e^F Zd ;Ҟ6 m9g kW;c74w:5F6uz~Vwo4D譄l; DUH_$2.QjMu#7j<$[Wk{_ 4׷z [Fƭtsq/?fAaUB7p3==/=p?PBfZ0_[]a/;ڿ`ao=Rwm1ִƍp`-`/Xq߹%_mvH0~o>?/ `ҟmT#3nnevЎgYfmsχ ~ӕ_8+<|< ]?_~^UlG}jUd }U=69)6!}@__Ur!ۏuR ]M `٘m`0rk[ iR+NT"&l: m:Xjp2]hA';sugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/images/Animals/image_nimo_h250_w299_lg.gif0000644000175000017500000001241010716617376032251 0ustar janijaniGIF89a+33fff023f5B̏fjff03fg̙˹ug3f33f3̽33ff,+@@pH,Ȥrl:ШtJNazpH~:|-|ISHm[ D LprX[ aszNL  dFqϪwÕb%Ȣ O6[B}IXUlBP! B,{l-rOfW=!ɓ>mJ(M"(B@nv0=aJ`1iՖ5CK6UjD'շq `!W`ݻ1NiBB]f7U"dJ1iʒXn- Rr2X`5 PD7pN x m k`rPvCj/ "siK}=ui#&+&Rr!K!\AW} ]`OT TgiWaPhi!{ѧ$:XgthU];XxSB/2gB|"4vʅ>F)$8@$ۡ00 z ݃p*:Dmԇ(f@sp <"DCSI嗋iC80q|5/YV(-<^H`yUR #`<~C8OӿO?E6qcG 5nm_dkJot;o9*M]"xMLaDQ{ִ<6aexGȑuu!1 <N2SB"p/XÇ`:7MHB5XVV(bRKN1RM,5F(<\Ў6Z(*395 &3 0c(J-(Z&r6*e,Qk@Ѥ0 I2SUӧԋaR"&I1Q)`zTJ \0"; P =2, 2heDѱ0I_Ule5I‘ӜPipl*@ J#*l Cǘ \: G8 ̧!OԫY9B7O ùD2V nyP@I@| .*+m:B  X.^$JZVKH\=:o^4+U+W!Gnta1R }mGzT\ MY[k.aWŊi$'ť6^=SVE)N-ŃoHNm[CAϷ,tZN~0pJᇗm/6Ω(wХo"ɑg 0n^bOgXLB^цqJ/Џt. ve儂cjAkJ1I^@X#`0 )Zh< UEr8E|2E02LKl|(@0 E"0o:.?kN+aiRľK@4P#4s5P >;B#OLKT![5{[Vos-׏o6H6X2sBLjiߧIbmV8 Zkl=]x/ЀRYCa CyÃc]*/1h4 8 -qaм5vm<WP~t=Ë}KhKֹu8.Hh}: -W.. ʊ"bc{);#uB4?2*9*r|@X{mKh9+Ϋ>+TqYQUa)d~fb[ %z~d j~B__/%kaw@vlLONu0D|'su׻n0M~r',0a{p'UBTte7Ȁ>?P6ws?rT} % bL,g̵tRsȗv.UdE /e AM9+2 VUU2tE<0UC{$P"G'<(6*G%0wP$uJEALgGx(Gcu'#bW~7'@evNEP~x~O|%bXr9GI[b(xbH#nx9oxRW8T 燸8LÊ7v33uD?wgCňz2*hSx;E2kr؈&St@YsyT9He$VaU ! +/ 92>62%-5zx x)Hp0[bn bXw ,W%b0bUGTns%uF&X UPm5"_r29QD#C)3$H% 9 T,(]H49([I)D]iX)2hm3.( HeQ;7 906AQYه'wss208eYِP6ecB<)xdC~ g Q!Ƶ8WYiE1|r@u 1@>CХ$@a^@ssuuXrrٚ)#15qJ8]9o~p\Н]@3]mOw]9TyWz.y=Y11xx[712rDk `A`z`0h=+1^:Mv ":M&tFi-QB0Z9uQ[OjwfX=ցGIJ3ã!&9X%MbNb䓦!Y= &Pv9L.ئ& Bv;5ӈqW~o 1d}T2'+26cDgtIcVWE:[$ QuOTI%!Z9t;Әi<[Fg{0OTmc3 QXlgH !j`ʚigE'jt`?݃qf&e顥 PtJg1tE&N,&[4GhyR!@ ZjlQZ s}ЯRH O  Ȇkh QVez܀ZIjNfpsk:6Ngw&BBc?W J%7BSlD"H?(2tO'p+q0@((IF(Pd -[wilbDkKNͱAab[֥=`"P (X=ITTppkVYt"daJ7YS% o{tKbf)(2p@# pgFH2ӛ {)bSk2$@'!c=ۣ锒,wǦYQ*#C@P`f}1\ #[Hnb H8Ҳq,dwh8z8Hϩ=i ]'Ԉ6' t8 k t"TᱳQw'fDᠷvRWN̉f-f 07F@vEo(/7Lfڳue%# .@^wRce\ ǰHGFSukX("WL[avB ,w=*әpshbdeqL:0:5׊j Ζg)?!b7Eg_Z+/-ܺx:g%!ҊG*$`JYR]N{; V %ӊiέW" If{ƌКŜϔ`]Pyl`Y'j ]038)f| }PgG,-0.͉5Z-PѰ:͇(4"Ґ0*fnNT\0K~I&* n%#߇7VL׸? JRG~W~Pe-h֪94wX&[l\X ˬ|(5ӑ҃x/}=kЌh=3 ~2M+q&9#ژx.Dԇ]]-,d-"?+M+&}ךҹAMPOe ܑ+lռݷ蔘0@sBgRV>)tZP3&r|d0t:h3a6L 0<+l @5W4S4nM QVDrI$iDc*8Ὡ+A_҂= .75kX{;\jH #}yqD>%OR+S\^܄Q2DrX4x(l^'|+Cku.(Kd ڱz2&B0yQHLl*QBۡvꢾ]QϲCb-Pp*RWLs=RHzxN {V,蘾̼Ԫ;sugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/images/Animals/image_mrfg_h250_w333_lg.gif0000644000175000017500000001212610716617376032233 0ustar janijaniGIF89aMnf f33pp 3ff̙*[f3 f uuf,M@#dihlp,tmx|pHA4rl25GQHqvzשxL>δz ҆7x?gNn%zq {o w=   0 $,̳GpbPA† #VPV,`3j,Ǐ ;hH(0œ"|Ǎ;v@S28d sKh4'Sh7s*-ЧPaU[p- ˳gœF7ѱh6@[˨d;[;&Vlp]u?+-hNX˗{׷}lP+XpyZ׌Q@(۷uK =7˝nxD*cz&$U[Ot ~כ2lîF0ro|yx@#dQE |F(VhYz'73g[ދ@܋+N\z,oo1ᏸ_/ `@֤b0TZ k8N'x*zYqy]f{eƹ?@ P|K"!bNGg裶)gf馜v駠Vdꪬꫠ"@ۏj뭸Zpj:j`:a𪬲B f묵n:@% n@*;@G@ (ͽ $Par{o:j[^k@",1yf<)JSo$s(@_<@0vE( 2EWd&_]EԬ(/\Q-VDTճL]Ҙ`+4om~m)Fg}RW-wVx p ΎEބ 2#w4 f(| y9!;㟧0v~lɩ.;9ez;eS=t{۹HÿR[Ss DMiXS(LvܻRXاn\ 4ﵷo\Z^G0~_:y P&%e"``KȗÀ`FVep0ϔY[&U?'i6GgdĜY"%QZԩtȟMt8$]CkUp(pDiL=DY?"!6K hH۰[9̏@FQC&a LP3ق9ÖC~YP#lO%5d$z,g/RQ!OȼL)mM;.w)p~[ kܿ|Hw"3^vM "/ӃIQ7WEʭ<C#J==MEDBfɛjK{߻ƬOc_ǫϧO֝&ljV +P P% `1C./wN 耨b U"-ٰM`t)$ .0P|%x-۴,G.2 *X,G U%RP=XE2,183) sz.8%TK1(QxM/h/WX!j!/B!0t!2}cx`X!<~pX0%A(Ѥc8XxUs3@YX3(pSAPSC\AWKs3bCSBY53 8usX5h xecP˸Јh4< nUWq刲8X  9Ue5vp4JȎx28J@وKXI4HvImY I@ I&8 9Yנ50ɑid5Y92"Y58ٓ!V()cbF4j0YKy6؉O QQZ\c]i6H>|p @9cDĐ8e pʵ\ݰ= W=4u[,7ӕLO: u9U|\Bv*d a>" 8 \IF$4C"[I;7dgAZ% )6Z!\vܠYl雍 ȕ ʹ֜ZNW hᵚ6V-lםIgٞ3ksf1h#rꙟQ:S>v ƞ'։E8)NbӉ_z<hD>?6#נyQ=;azI2"=ɚ!+:7 q=9/1â"! 9?AsGJ*CEj?S,Aa15Jeb p ^HJ.Qu:G'ceYc~Z`' y٧ta2b|+k9Tw >-I:d&%XZ;]"" k:e5qejV?5T>GjmfΦ_Raڅm@њ:;W>Š?:Zf>:DsZq=fcgDjQ:B*gY<ʮ&d:՚kFʭ_DKhjy:qysq&&$]e{h_g'2Oq U%ְ#kJif +Ù23fGzذ 1s0v=kCEkjk֯O*̡~qs z@ֶeL۵Ƴ g*h!9Hv* kFn\ʵ`CD Pi~E 8D&~ &Uѭs^5@zKq0+˸'6{pn!'wChDJfG[i8d;zJ GW)Ѱ='V7 Fq#BGif\_Cqy[i;w +;z!+FykqmgxǻQ)&"A$H.\ 2x!{᥇q$RgxHbp R}z2(+d6th{eevҖs e]\tI ["( f .+nWzu[CrV$Klk>b!|vH{lw|#!$+ B 2( sJ {4tDn)d'Y;|0d#lH{=ǏF7$wDxtfƻ!nœ{f(|;ZQ;|a #Hì}{tţqll\G;@{D*}sL Qvv 9~wqLpneRɮJ~&Թ{PgJ as,\MЬŬ͕͆ h~WBIx Mx uWIπ'x K{Mrd'L*L|鼻̈Lxye7A"Œ*|HDJ0*I̴rL&-˺d@,|<$UT},}ZA^` gLT}֬gV}%m ~jrmh]׷`"v|!͂}G؞ZX1|ētUB-I WJ8ڥ.DړQ,x h1+}+JzhMN.8T+1T.]M]h!ʲڽO}Ӎ+QTݘab. $݇mqۭMCc(Gꂂ='b޿m =P Mۭ"c(hu]w&~'8}'ڠ0U!ihL(Ib^OtNڠ) P0v;nB!XtiX! |PIu'Wrд\Kt#.dqxRl.|n, NN~;sugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/images/Animals/image_kili_h250_w387_lg.gif0000644000175000017500000003564410716617376032253 0ustar janijaniGIF89af@ffS̙3f.h33fi33ff̖G3OIzq2\e05љ,@@pH,Ȥrl:ШtJZجV:fsY t|< b'yz  {x{ x{z ~xvy~zoǽһGbkkoB]ntxn{5E`SO)XArՒ82R+ {AjT{d8 *zp<;u%.2[NÄ=#nBԫXSDy촂MWޓ@FɳF !&A\afPN63 pU~Bx=y*I h,i˟.' 5["&t8XxZ^Um2Aȓ+_μyJ )V5/꺰AOFA$8fq.E/"R߷`wH,b GY|y`T"rh-1>Ftpgs,0zP]$0C;=H|"'#&v'{, Ak@0F\riv a` ~$T& [F yLS!$#zO" Ɂ)F Nq1be:|A@]J! ^D)@-"kIjVhuWdwM < eB*6ců)Hѝ4 'Q㋍Kj.``k^aƉLfk:$ě%O#AV}1D00r|&,*u.N.oZ`1M1++p2@Y\pD W `T'K\9*,D<[;* 薯T?%lZ",uGQc"a_a#2!cxwHD J:^pJd H rW21bNm2$ @@zCNA;z 2딧)qEXO_(P% B袇ޅ"Ii"PP-}-ax.3`nI7GBVf/VMdJx A[PG6\xJ@n$4iҚ$."h&S)w1 pQ nc#J=u萟 54В4dJNMXvH-6jԨ&IOE(8$4XcJSВf1IMs ,BLG l {zqG༑usAtĦ^ bb5ĸ e93:܎GNAXz= NRfVG?0U5g3FB{Γ/+P"qh%ZWMkf'B(7,Z];6 zЀI[f. :.5ZT \Fnm\G4"u,e#6|ÂxU$Nz7HZX=< w XSNA1lLlc K8T@}0PtK#Zp.{`sL2'(Հ6pL:KhNrf>AxS59ЈN4FSu1/sGCd NO9W]ӲaM` 7[b+VĈD)Q9^m˦}rN<^6 R%h@'& =GrtX %65I(C y̡>I{^ދ46E(1*T3S)wÏŅц9&7|| #R26Pd& S Hn  )A]e:I.!d|sJ u>_],,si AiS&ͥ FOg$P.B7aLA#?$vo/gM^:[BMQNiSo6>,1ӠspHw7P piX./xp S `Q`V1`u "S3w38]uM~7v $P xj>|Pb~%m&6{j#{ rjpq Ea0PWO7ڂ'E+3{xPCpUеGd0]aa)>)ڃ{'p: @ # @q+bxs`vPot-s#T 3IOA:4 q(wx8v=Y10$hp #=H6'q sYxNl`0W*7(I9R&p~D! d S@}{tFj?2e8ZBC d #zouS#SR~ [$Dg指M\H15` pUʈ-4 F@u 3qHT }x+?(  3Աx| ?8b 1&0wNw][`1#8@s iy2 )KUT(vsr1PFPu-&,^b=5YY?1O` xDt[ OB]nKKT!0 XU'Fx@q2T@zFF`x }C󔸙kG\')YS1-hwp@ $6GFK9H..1@QFPu"LXɛYMОӁYu ANba\$bW"@sO:˴Qw"^Z_0zg?XY8Җhs)Kh&]P 8NNx."z/zOc5Z\URb 5hzԞG F3R]tL`1'WZOٹ(\LgdWa:) KvqF0Q`Ij umZ^ZW:Mk0jZRu5HС5a|FwOw0LSP$GTd:ƣ)pP[|@ZRI؉Yz= zVx$T`YgӤL 1>vYezPF rE*{Gsw(!ʽ H낡#rX]u D2W]ER;'2'.1RS'_BΣ,g3)\~8q3-5d_ 6Hִ\&`xhQSpBatYaԹ8'r" -a RU0$P7S(L:b= f;@Hc R \Q)l 00 Lg(Pa{ Qw$e9oP"P~%nqIhoosK[xM8ssX! w?x0*1zQID9{Q%%doj "SED2wY54:aq) 6E"qD1ǽ[E<;<`0EeJN"JA)pꐈ0ȔӦy\#;!'B>&n k&%Bm˳ Gu5-x"ױiB" ?sT̥ăP]XJ S;+ So3|dǀtA.2lH%grY0,3u1:% <-nak3 !7ZBms(o%"z՚q)'kxQ0o/ QB%4*Pp0PssY&C*3Bn"7&!cbv3}~x{8)HP)DdRzY.²$  $ q :D3$"G g ewuܗV l2 QS4Ă=`h8H 3 +V>h , `\aC@ ^$q "yT`1ױ|} N@x Eo3y6 b NM)$"@!=4SB0uF-B 2')߳$Bڢ4Ҕ9LnӀ#py %lT Gd gA12nGv%LQ9#Sna#x: 0HHh0a#ցR "GS lAڦ n}ZV4\ ûr' 7 {VЕq.QFTskBqsKP ȣoA'CYy |Zt"zm0B9\P =ݕ i7tH>tF7(fY n$Fvw39!x2bt2|0 |PIAsTr!Tsrމ- 1ڐs H M% !!D ~Ջd+tGySc>wq0 ;ЈAA$W!(2YW®30ooP cb{!6$(AE |KUu=>7Ǣ }XD]PBtCDmĵS'G$uAMC$<(4(>n_ԯ!b! D"#!%fJ4R\6ivqy;I@]f "&0-( .00" ,6r8. ' >.xy欯'$GJ1/% $$$ % *㣅yƽ+חi)T2,2P&Ǡ #eK/ᨤSɣ,fDG K)/90 JYx+cF= Gxq&e/L-dAE4ƕ;.GcfUJ8W0@xQSS*]^HC+ !ׇe%nkׯ0l*hAlke-BZ8LY&eEYpo*:$40IQsd21@w}! ׯ l`$ x0 HfA&:LB bC^|; @Ñ4oi1'A@SH9jjA` \ニ0qXqQ1 jLS5s5@QEdNԑ u heF2!ԌrcK-r Id90 "$?xyP@Q*ͦB]ye4 a3`-_mRU:" Ơo`񀳰 k$ڐ[wltU^^ =V}շ{5W̉l! H>LbBcҀ*yZLC]"woޑ!W|MYe~b48Ɲ&?zXg7%RD+suJuku;GI啱٪䙍R꣭xT"iEr;Λ.Jz <µnYͳ0qT}.\ I>n]>'pOo!cKJ]o9#]xdTk}7Vig) c)~Y:\c5i|e~]h*%3w9^k~p>鑮F~Z"}5Ҕ iLa#ґ5'>Q% jehS ^eX`b c>Իh$K`fSha #J >jV $e\%xX"PI=Ío_Ud!يUZxְ,YGы.9hvJ' )C<{$et'ܔM(RVµoLW0UX``:_ 0}nh X>@1;S)M Wu{e@JRU, :`Ӕ `r̟ (z lЄlY肀eS RMP^u3VG٥4 gV6{vlMtW+v]mD#WB[E Z}@U@@UMPNZG44  *!` xve,9JZ҂0 MΖ*spƪV}J۱ #0gd+-)Xf ֫u=jw;xv*ᕩu ڮ7pe %ϸ} \`kߛ`A*x_-aa Op!`WqUօAb%*(P3R#=;/e0`b=1.a1Uc/MvQb˸X8@SRegG'b&ќfϚyARC1p,f=x3d@ϙ@ ωvhIOҕ1iMoӝAjQԥ6QjUխv QYϚqSqA6NrG A=}t 8E(dx$NRLݞ@oYG6.q찉p!C:l4G3<9ѱe"L 08G*o΄Q'j(Jm9c.?-w:D'2zQa$N46ZɉsVU3KIС & CЏ@@O(#QLf&DdN]#FI$u|,]@50KȺ'G?+&yb§ D{S rC<;qI' q@ c9鱉 ,!  `WCMYAAsOkxdX^ǻ΅\`XꐂyD0=&'#vg} bG"Xgկn:h?=lto#4!P<0F@> Twb,c# `0*G*N$9aL.Z &, NnJ7ʄ6 e0@Op`$A[& :d ,H^2|*D-<>DJN@.&c1d5*O:&eTpIYM0YdRBJp0!0pfCp"NSO4oI" 1C P%znEO!.KJ. , p8VD#"$@Xl}1 Ҏ7B!0!!HA P-=-t@ϣ:P8 FOfE܈ a#:-rQb"CA=>ERQnс`GQh(B%Aa>őZ0B/ƂB0,ްeF2!rBiSfCRN"db4 wabj1*"}d*AbV,YBqn1IώCAa!hpe)pR,s3&9i`b"92aPf%G,nNE@+o. STD9O.Dn*o /ώo9(#^%HO#n[p2դB+< 0>@h=8Xa$"!EH(@Bp&@sHA9ί;:'Hbp/C Qrʶ>2=]Ea22&D"*S۶VKBݠ1[Le .1'3T$9QaK2N\"A7o VlO /2Das 'EEd)c4PuP{Qˁ4 1@F 0 [xInHo﮴`#AP|33>,}CaN aH¡C4A(a/5XD9x#4PYU4=.ИhS5a>"AAR%Z V#A" G*8G*! ! KUg SX0Z)bz 4d[N3NaD[!NČ^,a .@A4(VAE.`o$f$$3Z# d (%Sb'b6ls!S(."  Q\"2N$RE( UA{$[-k!+BĂGhX!qVOԯT34vNR!@(\ 9ȥy-0Ca4d4Nӏ@鎐~B@TS{1(a-fY-i@ Yg)g01F#ؾA4Ocʅe!blʣ3I> rM 3986cFL1 /QXU, IC;QQwTP6 ZXzcl hvp`@( Ny& !t#G> w(ik O r ay mPfֳ=1=n \4k5bH%I+!`,w?Qd=xdEIpG#0$# rb,2 TgU7"2IFp9[Y)*cc*y'Edf¡I Hv`uIFm##HANr:ڲN(0B!)jkIzA^76BƜgl!_:Nbcިc&9'+RWc'KzA'AVz@=(a(&s{,ܣ3r2- T BI ݊@+(d"coG@'NQOE4x7sԕsFT ^A.ED3-|4a'dj|}$AUfd3US6C 7*)2LR/ ە-\6̍h ̺$ƃ ]D+y**ڏP/#d[8DځaR%ܧb*$!U8tC``w}Nw?K !E qꥠ*> Oem|^JY;>{.!G. 6x9ZK^7#I%YJ8dJgA Q _#aґ?? ފI0]`.L>"7xTFZNu1!f:b#Y9@@cPef;n}аO7Ϋ:8s"b8TfQ0 ġH /iZ.  01yr6mI w.4]!*-26:>BFJNRVZ^Z%$=xa^818D@,!@ 5=<% &" "@A= :4 J^QyӜ@M_êzE$di’ ErF+ 1m$'ӨM00:GX Qr |2Y! I={#D.~Qk&=|\f&8-~;N0g9bIj-wcԸ ^痒<%(Vd&=; NAĐp #Y 4M g 4[:K/Cz,(Xݡk \WXtXl#,cZ$>EY(Qy~4Jm#I1XpxJNIP.̛R .z9u!GRɑ.4g;"ML8A+]Kz՝MfRthcgi>BElK%؆I(f=b; m'FҖ,@jODoCW;#.Fzy3hmH[(5, u6TąCFP;I+t-YaڅB]--ZQJya b귶E#jہV_%p3I`G Fŋpbe\dUh?V"@LO]Bp'1 q%k9b9!ˈILdc_ L995,"l-,rnj/Z!̫ctyEy񼲜,z6:ܥ IX_ή&+,_T<DK &=c|ƨ خiC>qKdzE' ;ZZ#d}eb< Z0\(}O(?܃]"z t7eD:U&91U5ϡ =6`D-U<.0[  *î E<̐9Ա[|(`a!a!hVTc9xVI]Ea!aB`N,ŔΝG9umӰAI_`A">FT5Q+f%Z]Cq@XӍiÈ ^\a@E*@12Wb^er='F  DubJ c 2)M5+6#B3%@A1&%\c.Fb'>G$#>E:c4c 22v25#Ȟ<ʞ >1:O'Hh "DEBPdLȗ(o`EpDd c2VO%`!8d1>c#'&RcGF[a`#8*cicX&' 䤛PC E:"C.BN2QZdO%ebe1^RD[H2 =GF#fEdH1C0\"، J W#LBN"dK*,c֍DD^F$,IUfOCfnV(gr2BfU:I&ik&g1DlmĖ'JnIpk⥙&# f0d1&%ku'_r%D$.Xge^ge>_tΙ&Mz}Fx|a}^\v.hjrhzh1hlj$.̇z'7Fhhn(i z4(2i:B)樒Jhbij6>QsRE院iV&)UFcc鈆蕪i(^yҀ>$ڨiLii*n(6ZF`jrjOnƩ'}騒*N)c:&Utj*R(<*jcꯞ\)$f*) :fY2)ɋrkO+Z;kY@~zk: kr2k2j j)*+.J,~.lNl~P1BZlflrƺŊlDɲ,llllm m"m*2m:BmJRmZbmjrm;sugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/images/Animals/image_chmk_h250_w250_lg.gif0000644000175000017500000000731210716617376032221 0ustar janijaniGIF89af3ff,@I8k9`Ghl[,4xepȤ9IĨԵZ̎%noJV<ش9g㲞7Esw\RP/Y V71M)NS2,G!if{D>\v?0D1-lQPw&ОٹS-z߈ٻڷ.6acp}Oh,FfuKPI\,@Dp 7y3|ı&$A"r$+Th/Ņ3ٴߊs܃9T;)"<5)5UŗqVt۵DQl?պ i^GSu 3kىuU1bc/ Km"mQɕ9Tske.uaaNi\woM~Zwj-| ٨NmKԗv.[?nx3ډ}Gc,82_{e$` x_d%(``%as ($h(,0(4h8<@)DiH&I'Ɔ0)Ly&@\vyEDŽZZSa|S xIh 3!vg\RA>y/&JT1ItJZ^H!,;@N 2Yc,HC.$X?03E>lH#"Cy@:UI6a\){裻tUROdުBOfKP+֘`,>ħE`rCNa DFH3mpns"%t0X$R?Pހf5"a9KCxM2b (\FtqnA$qf ̊VH]Q Ռ'-z0j!6,]7D\%os= ٸ񒔩> Yma),n[W6 l_3jqp9+o@p˰-,WD2.X/R2D`+k^2#؉ )FIa\g\`4w2DWɯRyΐ5 YagHv7'HD/ ۑQEn*VwQFfc6S_5/#m],Vg%>Su>M-9 kͬaht꘬^ZƟ jNOlQp]qJbujRWKeUc>u9 +եpl ZƗN!8(,Mʪ1WiNHQSB5MY1Y--7]dUۚg^l;-5IR1|7ma -++ru\,Wh[qƵr ܣ8d&7v˴,qǽ2:$-^KN&z$w!$'ߙ Wbկ(Wfp!G7 BD:>8 bI7:q\8˜>EܹW6O$Ll_)Vq-døͰ̑0\^@L"HN&;PL*[XN qb]9Tozw6)ჯlQtsuH_^h@Ά+aSY4O,9h4ᝠgc^=+0z8@hjY([ìGrJ 4=cTU 1SYffO +vx9Hmr{ߜ7J4x lYΥPs S?.s臚l Kb=ɮ:lE΂&dX;۞]rW̎K=VG?6ߪs$@ '{9'E!-1y;a?U y U>_<^vUIR:E O׭DuԤ w]l(-^y`-E|  0!,zIEH.Rsda -1Kd uuO &B@}TGZKHq:KB4,qJe-FY6ƀ xI5u MPwPs`NJ45t 4E1(Z`%w^ GtwPL76h*1N55@P#bEzOt567ÅB$ReVTs24i؅h+5:|\gH2^gtV NhdNׄ/7(qBa2H%\\| %4}u{u4]s޷Pt5WY Ջ'uBE0K` r&e\K%VrU8U׈`CH+5a`61HNQa(c 'Q2p;%c d5[eLx%uUJU73 bZRNRYRSVx0h/PcS)jHZsC46I{ LMDz(U4U8Tُ Ê% uST8\$EHRw=61Y܅I8Xht@iYH6ZiSX^7؇.Ԕ u5[J|URU?2X6K|5z)G2ct8/).ЗT^e{ȕ-[5ZMiTeU[u69ØY^75OoԗYNv=OrK:4RXD(Qٞ9Z]/xwX穂m >Xk T8yꋍ/zyZ)^?)"U:g&鞶PmÆ0Poӹء_jIY=Fz/*1eMꤊBʏD*apO:ZfSJUj`_*[: QaaziaJz7 spz _ǥ( e`{ʧv:k:t.jcZXg {haqc8 i81x&r _LHZbjʠ^ڪ 稲Jclzx""y*}D6jY#ʐ*e5:Zzؚںڭ:Zz蚮꺮ڮ:Zz$;sugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/images/Animals/image_mdic_h250_w250_lg.gif0000644000175000017500000000537310716617376032220 0ustar janijaniGIF89af,@0I8ͻ`(dihlVA,tmx p(͈ȤlL4tJUFX5-xdl,ݱp7ޞ j@7 ДҴ= =&IcT8dq ,C8:N3(r†'M /b̕:ұlnRСx,t&Bb&N6udžQ8b JUe^%ٳpmK׭xkº?KÈ odq7hL˘?xoMF'S.;װ]]Mc=۶ Nȓ+_μ$^|ԫC׺ l ("u: zf{CG{yOMk=K|^#u6`yWρO5V|‚ RhU|L}6]>z$Z$Uzd0b 9xTዌd^8cɤ*Evϴ 1MR) "`&c%vT]A̛ѩҜtz}2!ޙpw 9zN)eb̥;5iZ(fQb_b}Zb.b}ujJ6^OF+h|Vi+`5쳙,.9@d![lq+/2|k.nɎn4+kg'| eQ?SOxj# !qx'[|kLk_Gʱ #zfNǥ6݁?,?&s~" 4OKu3O06 =g ӐWs)L4kYFLjou(95eQ_ Y~#`kӸg9PW՗BtݪʠF7eӵ[i,gZT ݃0tS)h1cQ#\ahNqVE0Q HE[ս/ǭ2͊1C#ԪG/7r;p!^p&ahC[iu+$/$*reGFlo#](C5-,V F|]FV:+–+gIK5.GTnmd+S]1p2WiKs8LP&lLUFad5.lNSlNypF49Ѭ~ @JPȬO 51'ɕq^)ІmC3ь^#\uDK#H)(-Y 0,) 3DTS#P!)W$Pmԝ\#WɤO7d]YJ5fXp}~*ZtkS@/7۫Z$XU.l į(LkMXAY;$dOu%`aZW&ʹm^ŸҪͮwE%tJʹ.ڞ =Mv<-n_;\ MEFbNL,ZR!c|o/)[צb#ߕo ٶU^wc-Z vOlΗL}s-q :D}]W>0Q jR&a"ñ;߶NBu[j4Osj8/qfwEj˶'I;kl[ϳJ2ע,gX-f|#I i}WG0e-$7kޙ>츪0h=¹ZC%鰻tk&)&FL>8*NK+zj# FEVc(]iim3M4b(~dXszVUK#OyytvreEǍT';{V7zuݷ}78oaXXk6&,]{#>!|-zq5jN9b,CQ 7kE:<6w~OU5{-jhkrqni"&j+a0/bS.j(Wh[,'Z?OPsn.Z Baẑ4[Λ`NosgG)oV7G],ψSxyٱ(+P!{p~=u- $mV]oyqolV~M6_h='Iʌ$cf{N_<)uʏu_Wf\2|KK-yx x-XLԀIXM7-Noue: 6bJѲq(6.20ش8^MTk=jM!7DL@X>KȄMQ.TPʔ^bԅc5-uQlM'NrXvxxz|؇x;sugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/images/Animals/image_howl_h250_w250_lg.gif0000644000175000017500000000655410716617376032257 0ustar janijaniGIF89a3fff3f,@I8ͻ`(dihlp,tmR^@`(äl: T*ZجVNvL.hn+bN o#{XvtdwF}+O)Re Gvd'{ y̋Ǔ[ּͬJx tu؞Ep٭\'MqЂJ (!@H,BY@;s yd-0ae̛$Ο;}IУP pP `իXN-c5ׯ`ٳh֐ڷSq]W}L;c-@hȘ%[~mA[_ħ 'Zէj6X۸9gnY3mA=<ﲒ5=pYM+>@VX,V^ig֛o//G}{VawixcGy mW_|V7vZ RxT'bԊ,00QhcO}HF-CԎdFI  P?-nTBu !X1p(Q"0Dff ,`04ɝ/#'s6R$LӨ{.N\),fiI) &J|z"jjGQ4MdjHpH9 X;Rj+D,#"!M9*eO' ;f ӵjl l'ym W!@hg\NXPJz[{glMXk~vMuH{=Yro{f6toƅV0"rqopYs%jԩU{v^}nYaFb)rY1tt7wXسf=6!6m!V,vu !V7nV k'78Gl@+jӮ?h)FC;+B:yqv:͑|!y+$ |W\|fr~OÈ/@Yď<#ӟ.k]M3 SbF(?)D4@Or)=qʦ΁o8W  )NT\!z"zqQ03 tD$&[hHvHщUE@G[qG# !x29bvBXB(QDDW6x_ h+ "!I[1o$˳EFa%d1M6x(J2G,0V+ RIɀ2\XeT4`-\@7'|`n \Kbhcf iҒfi!,(֔qpKgV/]~Q4`Vĉ7Xdb5zv4;YcJ-3B3YZ`f]Ca霧ET2NE0,{G%* ed$kh&Rg {-negƆJR MCT!5ݬ-\lkHˊ{rTY6APOZ0%kW|Vk q@$=8[lԙְv+Am)36.<ߓ! ]m RiϿ ֬@w>l}.iIZ CWh\ ױM.r)6ͮvz xK7YiuwS17R=eQCbTE5" yUSfAh4:R*#P+5P/QTZP]XdhX !x48SÈ%U06%a$(s35|2(5b%m$!=hxsP8SAŸxXQߡ2Շphss E4XϡQ 2Qh3G%42Fe3LR7h5^45z1UMEk艿%5'Ո{y%xX VEĉZNPoEH5uVOub 5\WTj18[@SY25e5eYNl UP ӒZXU7b)]Օ!6)DyShبUu54$\WQ!6\u5`yI3YXny#\b3Z_5SY?y!eVYk/.n7#7e16\InNyLY[NNvI6\}6Z(87ɑV VٝNy\5)њU6e!S[e\V\]e J ;sugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/images/Animals/image_drti_h250_w322_lg.gif0000644000175000017500000003214010716617376032236 0ustar janijaniGIF89aBf33ff33 ffφ3VMd33ffdg׽r:r3ff3633,B@`!dihlp,tmx|pH,Ȥrl:ШtJZجvzxLnΆn9vpFDCV'ye> opnmqnl"Ş7nۏΐml9DSupCδ2Y` 4Pq6 SWC`UfT"=`bύ+ZFCHq Cϟ9GZvӹpLĕ^T&{bq#t(Ѥx,mNh,DpbLJ ֬edzA'ZI$=P q2\0< Pxn*_.*7.P- AbӔdG9niV.Hc-q l*Wi @`y/ G Y=eN9pH07f≠xJ%)3#\' 1c؇D $Eb; 9%nU1'8R\%~a "8xg' Ii'Sڙq"E` `r>]QE v7u\Qa)\rOm g6 vԺ<癵:Jc$xR2Ye2Vl(h)[ݱAgOq`?mD6(K_kG)GzVD'|IZ@#pkbc @#KhhL[A*|5cR-yuZ)n]isTk:BżZqXo5g=j)x<Qr(Rչ;ldDBY𛦕zv҃:PJ(Y{5 1۠8±e}n@&JQ5Nd9d'7w:نO6oMPӅ3Dqjg6hsO z桷z+"T;ɕ]d3*SIAP7ҽBLajTk?Gk'>񕏃K]8>NM@ w n cGIl& Z"DdD@l$w Hd"RpX l `|Ӝ׶*b1NqV!DQ$zlcp٨ DaW| O´я. ;X/ IRFpd*eaFQ#49 X`%\0Ih&R=~C!X{eق*<UFSj4UiFy}pр,ֻ\LgsKϖ {ـzH '=gb#HA=#f%>IOrT;a.rR#d&L Ea@sIJ))0fH@N)"x#E2Pr)'EI),#I63hsS#}7TɆ$c%Z*&#&D zMfLN'וv@ ՉwF<#1Eԟ'B,PE6gUulPi3w8l rvzqD ᜥP`4`1 HaX!FNpuh X-JvpR7O i{9x9@W7~NYs)e'(3E.%P|_}c\@ B"2<$Qe1`ȐW/ؓ9Iԍp d uIP4&98PM[[u\*S{U6ȓX*vDIJomNtQMYJIv %Gi݅eQٛٛ`x⑞JHtm]awBWAf#]s`=PaU`@l[)4`ׄjIpR\%8iH<%Uԥ$a]ZRGS?Eh[( 'SuXu\ hJ;L䔟mQ r1FY0F..5w5aדgEs> F.(Y}U\OlT`u  ;K'V>gɃa+)b ^R0XSצnpr:tZvzxz|ڧ~:Zz.#CfsJb2ZZW6$Es6 Rtrqefוn0QB R @l: ';tfѢg7haf-xV#DG ە Zh@ip!Qqg!J-)'o@]&Z@z՚J BW-I4 fТF$]o2@#n$qD3chnqg;DJ{u V$mVZ1*{ 1fv.hhRf0ppYf,QR'm0VeX@&.pek=(KpFN`nF_QGFV:M5Jmd[&hN* jֵF^Ycg$ݡ pMVn 5H)FY2p#j`` ar)፤a<(QLn))`8&HnNRlPpF9{L]AySp1@{.GmQ u9cg<BYG٭y __?3U)AOLn8&.yP5m"~W|dw>g+g߷0\XrrDWA>\|@qA恟khiHeI)H'bKW'F_'/i0P/rBM˾VYKKm飍K cB%t{ + NV_ XjA PF$ZDB ?Mo$OEO/)^Ix"CuQDP] }N6/5llzܐ'dct2(2%qD-[1y`29~÷B[6oxXhhT ޙY=$-A"E1A*Iea0ęq]5Iy͉*Qe֢1~dix{ =ǦEIe<8quN뀓#pnW&P;YɳLt&BDo.F+,` {g0[ڶN%t#ug9Ñ 4^ l>s@ JsF)Lt҅M'zСDE#lu:=α)Ԑ+}"JK3Y"Zu"* NNd6l,L y:L(&W(b:H `4\-ӔClɔʺLgAMq @:f"dqO`tg3gv~}ѨIȊC1|ߩN[iW/> '6+:(c0mhH?͡C "Sr3WuOuk`liV[}Pi%r=UbX#@CHdk {pP oT؂N0eLT, T=EdTtYk'[}v\P)9nCk*ß68UP0vT.XJR.LNGlxfRB|^*~gd|hZDK%Z(~p*2X^bIym:%ּ:#'ODS[bFnSaNjcyY'6nq@6TjK2F$H^v7"* y+iʁ=+'pi1V~9iB - B!$1SHCuاY%<`z\lOL'1Jk˜+i ThJc =|P!MY3SGVTII[PcYBށ̊zv}6}x^㞻޻_#3߼CS_cs߽߃_磟߾_㟿߿0  h"0 \ B0 +h b0 ;0"! Kh0*\! [°v!bhCͰ |5, xCч1шg@"z94cb(y34/E< ĵ PH]l"'}X̢StNq ZpxS"JP@+A7.r|5Y\Hg<]UFdkl͡CưIW uXFR$"ֶ[Ђt`p nFFʅ!OPƎ$Uв'knROT'WУ9a[G"]h݌ArF#mPrT$GkyE5da<+MYX] gm* },@K.t&%j&҈F<@fC:%<$4:tE;M VYlab)ܓT[#{Y%Z(d珝-SϛAubQR⵮y0ġ3Y|@U ]㛄RZq S$d*պuV53'q528 M|}f:I*XN4l, @*T [j;փ$Z> .M;:ick*Ƞ[I {N=oz:>hmm3Oݝ9BL|| x/Ŷxl/;zX W";1?=*|U:@SGPAo/~sDe!Hd wrЀd_5'$Cr1P{m>Ԏ }Th)[=yBP9U,]`TBOQ^eH @Se ȅLJv^{AӡS /9eGaTT I"\L<`n-0`[b1Ix`nR5e!rԶ="Q̥aܖ ZHBLV%a ȭU$M!Nk[ t`&aDN$ʈfTٚCYuǖu l1O ؘKwT$k#]Pc,UU[G( Ɏ u:;b V j-ew QPT?6R߮ -l ac 8.O ] 1Q=ch?\YZz@RoѕQ]Ohph;>D$ Hd@:$HRLԍ^)PFԬPrd4ړvXOYOOԟuǶd? j֙TI.Սu(S, NXd\GS$i")xVjשѕ\(d, ȦԎee )e0MU@ A=_e+L#!̦ (XҎw֎Yv & {:X{'%-؅ dA>G0IreWNN<)˹byZh$y@x @Nzg|V#iu HC)^^>|Gn]b=pv= 0، #@L(@$(YZ(ͅHaEÁV"tIVdHT\Tğx⩜M|hN,TˆtTNA4@NgN~֕ÇѕviU?:VT~mJ:'ԬA c`@>XR\d|myȡI_ԋFM]hldĴ]0ݱĝIMeM /d@X_,οB-)od_C `oNnB&j2hg~t,/F94jv1-|H_/hJFTTlnq7$\@0Z$uv\giw(n+\<>a8;*Y>ŷ8 ~'[Zpu('~#}ꋱ(|@@0 d~)x{#+=6XC2};؎j_rFgǴ/A*X ?+:~#om8[[Ab׫KwO*G!8XVUYy[QohmP:2r5uY%IhZP@g2#̇!^;_~zնb}. |6G;^f cqd>>(KHF#:Dt<ˆPC$ZxH^^ʼ 6diy A9s%ҝ yĚbBq5 o6X!(j\{XJ_ҖbtЎZ3H|sSZڛĉ:itY鰆xPJl!χ*L{3.rk(Bn@cAp,x6 vnƧFoBЉs{FԚL"e2FZC *!UV=D] DZ2!̾I*у˙xft z5Q7$G7"`nEm("`9:P>hChl$,xŽwbj>p{x¹k.`H0ȼwc7@ m[_N"]n2,jLqGNhǾKiXFʱ@V*w8AFq@YO:$8И8߰=a } p5nal@@ B;nu 4U!,ʒ77 &4)%/L9qꃫIƬWLP N`"AE8+4# X#ufhù&%OL!SbĞ0 f|EJG9pdG~Q~t'CVBj "kR'"^|EXfWy/y ZDvh$'-x[ZeaU%F.-IhE Y;4&KXdwV.{CwiA4ze)Iep}n4(59L0KVRDE `-J%- * [SrÃD:vⲤ3x#R>;Ml2U]*,x2O:#fW 7xN 2;sugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/images/Animals/thumb.gif0000644000175000017500000000056110716617376027256 0ustar janijaniGIF87a22f,220I8=`bizO ,- Ǎ}߮, x7$F0zΘ%JؤK\vSÙ =ѿ/Ix1QYvMU;H{|vxkny16u}*ZcDr$8sSG{dG4dv\ A]wAx^ftsƷuV"FɲOVJ:azM5i]`Ftj\)5kR5@N=vQqK=45w:3o5r(S4n:36؍6A=p[{$ d2ê )\8( 88…R0q]IKǓ(0 aMSɛٌxMZ:+BCJjC[ϫS5$\8c9CjڄUSOEpkxJ֢~Eh(B_kU(4u#c)DYh%o4DMz:@|-6dɸu i!k#kE W+~jm3䝻{H N>5?fB*HjbubwY~ 3CDݡKfQ7C&`g*j| h*DR](]4Cy?*zY8;&I{3K\&)fHJ!] WzjXU$ m5%U0RF1FV&c֩= wEeKbhhl=X&xvFZPvQWGTy]MryTD Z#Ejh]2sR0日y%4Є/B1 9J*Cv‘ReG++f֗&03܊9>d^jBAZVt0}VyP/ !+G)jČ0taCpK'(& 9Yvc^:67sȦbTCOܷ ꕳ9-Et@#CCו"ZTc\tϘ0]6&Htmx|͙GcFC|HWv?ӆG.Yn1 +Zw^3#$ 1&;sʼnlv, S]궮@Kl\914̋{5i;>ٰ М %.7=I~s)Co=;xr>/ܐS9^a~{MX׹f^)9QP l<2$-.TH"q# f/+uGG6FLß9[@x`=<2Q P \|bpP} vn P:!B(Ak3NP:)VTkx3͛F4ˌM 7"jB1&! CH\40Ž܂5"7]z P?vJ^(2=R,JA1J ~650gr@s(bxHO+EXG6B1;̆Niv)])Y!ƴ`lU:EV-C]DIpiplΧKoCYO&MRqx:h>u}= ϲ̱%Nv MLz,~"R D)g)Kn8R)6KC*f3|* YG*$AdQbw-]*@gm:x꒰S~ʕdxXCxլ5ӹ9@悵&j NQ|గ%BLc5gYVg- })ӂ֐أIh3rRK!+75xc>vBxN:\>TȐ I W[z{;]Wл}0@mP 0|ßPzu(Ё`E#N`u`/ |΅7,m5G;$2hyC  ᳤F @M3 x(Qɰx nCX%x)nЕ,0M]KLfdZY `x8Kbj"?b๔lHUa@/Ɓ2Fu$Zjs4 _w%$' 2!7:51%'bWlK 6\RRk1;E\~bB)#D&NM!{NfKm-@x2 4v "jn @"ېoo%7 Z'OI)G^F dO $v,!gtH?OMZkVV:Ċu&HKjH5E=N`!fv8E/o%LB?㠌Ӂ εj-"%QiJC]2c4..U}GR޳s:t\(M'کlsKѓoaM`<}+kr 7Y>(jmv_ȲᐣR 8h_'pג̸2~xz#!f^Ō=ϏMkr\֎}'*0a#LRSQvKKwkvx5_(/D| *l!f",^NC@do3~PfCq2dJNhK;2fbJ {0r0mKvSm[Z E}].a(uhxcLÆWs|#5bL'.†G# 1s8_4$evdEnG 5KهB4>~rSq8|s5lzрJ6 -q&N,dd zxGjv/;R@%)hR[`f8&wD { Q'ndpUdryzpFR"uAXCweT[{ZH5[Ov&VSR&RFG sivajua2#@<vJxo Hf-W ~C.w堑@WprVa[HYnUWS|8x7I55q3Np5Btitu7-c2j] H2O2XCY!0B~/2VX$F0<XwtX*񉕌=?apGsE*`(&S>+@HCѓSJC/EɥߣW\׋Y#!d: .:_8tm*?֖ -P)PQw:?i+|er40z8^T!pgR[}}JJdHcX{}sIhz)f+悙7512z7U6Ib 3376&Jy:H\iMȚf,HSJ`wneᪧ)ɭ犮]djf:wCSK405`Cc2aif9gg0"93l/;4-C65(Y #{ȸtcm}æ1ytϊER4#«l1B/T7j=3NvA30)a>Sezzv>BpA6>j#h3Ujbp~.;@0kdluuBCrkR*rHo28cPxTRSˆr񺰻9A˴hkۻDhGK|[8HKMoUQ&I@ P+S7H Ӏ Zڟ{@ba~&k{K tbMopZC6ZUT]Am*i3׽II7\{ qRq &tX ?1?[rT@t+:' ( 2@"ڈEY2f"'q + UxXY;DK*[&Ihtm"{x *B]M!XƬ }#PrunP zv l?ښ(4ൡu6.|怟;Ug A苽< |i,̎F' zIxg-R"2V}l8zkz頇 3;4z#gHvͮhT6'9{*X =c0Ml4ݬi&)%$pˬ;VAMtEiwTz=~ٵg_Vt6QՂ*Jo--twc}__(# 5v8Rvճe2rM&9Ig-$ÏU8$rqK%>*?TX?CX>8 q]>FciV9%Rќ^l$:w4 u(}u"[mgzf`Z8SCHXҁs8kS){괒K\):6 s,s+^1ק֬tb6 YB\9bIZI }pH\t/E@j[KzNҮnaXo͊d}`nb` uvI-nn} /p?E&jbLT! j^SP)=P^+o(D΅5V`R IjϦt=gN0OlQMd7ꛀOBL ЧZJ Uٸ?2 F{B <~K %.1a/ .{EQTTBAR\蛙o~SQqXhQN ,7 ߒ{7o 6)*~SIoZ 8ykzY}66ӹ*`m0:RdjE1|h+~bg/BY&MT8]D%haAFJNI)fjn"0 L48&O6Q^X!JCZ<(CIN8Z@!Qs*3]b5 ʨ8"@kb"lsYra╨4cJ-"B~)tJun~|6;6~;ɿw*\GUTY!1"f '^I!9AcDa-Z|!]a_3w *Huʜ(Ub'D%CM5Ƣ7% VYE@IS@&l>TOץ-PdD|5L\֗aBQtuIXTW46IŸXD!QRIgeֳx#BśK^2EZ%XA`UZy$&Mgnkl3a&[6醚ϲV3,$92V.`5@$+ZXAһ4{ Z뛙g.׈SS_LsLg-{ 2rʚn*37gvʃs')q:ISkJ5뜷^S/FY':Lpoy* \V9NNɧXke@ @bJx [lhm bRN{0Gt1<R# W,rn&?kj] [b̭|-&/'O\ g !ϰ. sΒ Φ*1գH@÷z i oRu1z/P,z߆J.gxm嘿7 5Р9u:su8 yqݜf`{Luߑio5]asnjW>:W'O+ӅwN:*;>??`5;{҃=w\ˀ NdUNȠ7@'hEA} dw!PN)4 ?-gtrVVMCǭψS X$D"|U<[ #8mtKTOFʔOh,61 ᩂ$:!kB"b y펀 |؆.ˆVQcU 2 'n%R\ !#IX CAHڤwd>HblѼ腎 L>ȃJW.`@ZeLeYD > rC $a)ВR/@@Ahr ˨XvIMDU!f\G}jd,3! jB8Yne/%h8yH?hHr h4xiMz-g~VFi&#`ʜTJR{n`baXBڗ]ZԏRQкE:IQ~09D tPp4 `c<@wP[vU7u{.:m I Ȣ3ꇡXPx SɂhZX7_߸UyVHE pQV\G؜-#ȫiM jns(E we)vTo s&`D8Ʀh0i(<`<j5U-0"n)pWX=SAEk U$ri@ruOk @HބW{æ),5%dJ)-W_|d- #3Bjae $7#2)]>іsFf"ـ}N 0B35#0@#ic{oܛv|9e+s:6Sϛ]mX|Ri\բث2=$:e'd٧ŧjS,q:QʯܰK5Jix> UKO_D^gunhZڹ沔mZa*z|83d.pVna.JTqpՙ{xb|zUU=k; z9Q_yc1Z΅7Ѭ`~{OE7B2{cl js`ׂN7afOڅrR3ƶ= <.~ -+SbFHu>ƲT*,E t񒐼0z\8 ';`yK2$륯OY)Ezy%O>l;B $8||>,WQq,Qx4l)|S%gI3JPv8% #1NPWPHt~[7WxS7He#|p(M4X$VVӄ?2$TOL尃R1!J1zFT"ATEGQI2XPxRhN |PALB$NxNR=XGKp$c1J ԀЀ0QD0Sāׇ ((0W;;ܴ mЊ@S0{N(H`aAX&" q,!ԘFX\"rQxȰTr8` "Hpq0(H/`=!"h(h(-4@ XG}hQY@VYX&`v'c!pW 5 Ev%uGI!RA7(Rq[QI UyU9i]bcYHYQ X|•~f K4I0it1pi~p# &2ip#|EP טcᙏ9]7cBsH 'mQ*8 ) P"g(L4ܴ&9y\Sm=kzD~mEJ,po4 p 9ngr.r ny[B̯/Kpƈk/q#Q'2I'D TFtRkZ\ĥpZı)20TŐ`7Z3qz|{yw{KGK[$BG.mXR`O/T'eܻ6mx4 ur7Dz1!5~.GIHyUNN*Xn} rW__-%ՎUaMd&meզ\M/)l!;>78ۺ *aP^' >Ťݸʑ3la >䬸D][jrbSwhHX4vP" _ wƈ^րQd0`؍^qU8/9O40;o4T-]#U< r"b+P `qVJ#T wTḬ%yҾƸBd)#;x)t:Ђb"-"WHoO 86pd|#,9!|!7R(wu|X_I}8ZP`Yax~ E){j. Xi̫oMyE" /0`7o_ߕ76u_J gN/ X4I2P0QZ^GE~Qq\>iv^*v3"0 " *-/694;ACEAM"[?<`#dMM+Gst{}pJk* V<\866hox9%W/"g𸊯y>ëɋĉ`ܙ8BXɂ Db`ԸJB.bY'On@%K!O qU !CC+~AER%&/\`eJ'4utH$.ʪ( ;, SUSNh֦@׭\&T!j޼psQ {EBի".*W+B|!-bv82O7p]կ*1-o @\$zߕ] Εc="FeNy0o 5`2qlRW[f^avId\–l|zw]Y πXA w[pZ@n7z)/7ex[n:?(˭X!\wvYGԆ6\A.(,)VJ7쾺aXTgoq{ʿ}Lg.er|Ce#[guǍ[F+;3C1l0I^6/o0XNtݜzpI{ ip/F0m2ق#20i+BP>eg$;P{(T!p| LM=*L,n,~JPx~ҨoO-00 NP*;sugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/images/Music/image_weird_h250_w384_lg.gif0000644000175000017500000001502710716617376032117 0ustar janijaniGIF89aDGa3e]H)6q3f333ff3x͏9f13ZZ,@ dihlp,tm8mWpH,ǜrl:Ш3Yجv˕zxllxܴz|2$~.vx|ERUA'vb"g UUg;;fp ߲? jT H ~. @g9 U;ʇemh00 , 0a,~>8ͣ6,P .FCR lj$Әd 6T:@ձTZ} ѷKjZC2&pDYwKe JUHDTW$s`]c?Tr&Dm3"9=b"\@޾, vS@>xr^T gȠzFfEȠs7 `uadsPCu*%l?;X7݄\0!0ZyHlWA"E[iSIFXvFy7'5؃bh٤t>݅gȿ]@-ã'A@I.XC 1J_ȗof*d#ȯR`djBiw&3ޖ`x#ݒy%on$q>u[sQp(AG 5}ZWawgi'tk;w`ܑ+>9c<pF?=FCL*7XX$%y%GG`*kI`:Juڍ\I%#zT=HdF-hfԗu Bi}hx~ݧF9l(%i}muaY ޖBq0~h-r`JYWKHb?5 RKwWh|aY]{wGT}!nc&l6@`+'$LTcƒ&JHM6FTrDcb="HqrƲz`~bP&iqIۇz1qavrU .") ('O'EjXY (IqgNDC'uG* ȡ5R gMv+F #b#(@:VRz>X࣊FbN x "EI3p&*&9IE x>p012T, V *\0YEhyWXR'MulCQxW$)S /uv-BU#^|~B23%2i H*_u-o-184k5q^eW.$6<" ~M3I2,#vE3/ ZB*ɍ*]tՓK*I "&+YVe/n1Z&EWsij`5qgư|΀ Xf Fw=p@ Q&?f8?]EVxkEWg=۬t6ѲH@u0s#Avp] dl;h adc @,=P+{F'O]@ ?{lSGBn!tl`KKj% #A>&d(RQnoq'3 )Z{9<. @mʋv;Up ;6"kw @ GTQ7o8[9\ і1aM00k]@eJP#ԫ B~x nlTk׵Ζ,Akk'% #zQcDy KnjMF gC*3C;.Dlt8$7zQAGprajBБ"33R1Z g3ҭl;H;E#L1]Fdq yQ^R~7Ԕ>Ip!@L1 AD`6xyH@wp*շ`y^H`Mb$Iq!χEpt9 'J(|Α'pf"yx`ALJEJ`Yryd5jW~a4 ԏ xR l7MGK=J=Aхu}&Ɔ¡`]bwNj\LzAENQKh(f P}\}#q-EA@%"g"RK!0NMcކҏ ^zrLYҧ=soHM}r.0g#7PTԏo$B+l eRM׀C N "B=@I I$`&̕G`3!M54H"Xľ3-c*n$u_rX,o~}`'C^N+GgYJshqH|0N&$Γ4xX2' iUƄjR+&b IzWҧjNZk!v}Q>rӦĊaDN!0%8cIA&!'HH8#>r^<:-?ݍPE'(첐O ﮔ>ϭMƔYR}>R(#,%= c*32V1HbXi$+&o;,BQ;DUChPk3/W&H靝gug~#9PN-4SrBgW-a%O(alz-~V)*~9XoOmv.9S>l9'EB+;eSjSY&MbӲԏ- ']GvU)֏/)<z̲F9n[<, 8yӄ'ĵrKOvR47D(g`b1,T7-[I#M1qm*R! \+1:u{cHF**Ln)0(F. KNW[.8DZ i0m鵄#UBkݸ* 1Px-]D&`d\ Ddm`*l,y`:b;`RGG`n T ;H|\Jz(}L0hj@xrp}d:A y_+{0^z.YMuc_%P <0Erѧ8+6qwշiX"Jdk.!CImd"fc`á($ `y,.!_Y#T_mwh&A̛sf5Rj.|j#.#-jm$%)n(g:JF6:IUp`^AyT5\SeZ:7ǪlD2۬BR[brۭ߂l>XIxۮ[⛯ۯp\# 3ܰCS\csܱ#\'+ܲ/3\7㜳;ܳ?C]G#K3ݴO;sugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/images/Music/image_wpwa_h250_w250_lg.gif0000644000175000017500000000453310716617376031753 0ustar janijaniGIF89a3f3f3f,@I8ͻ`(diIkp,/xn=6 rYD~)scZTTeJx<ejE[G ~oq`}pep2`'dsae.#tTɿ'R@ m2*LOÏjMKG⹂jxdǏ,1(f.RʜIS 勚@PRѣH"(@J uӍLjך;a6]_9RH+HpʝK.&˷߿ 3na[NŐ>L˒&;Ҍ̜;MiMUSRHi6 ٳam{7%xރUMA1Qi&f:7Y.ĥË7(X3@U>NYSWUGa@ }ėʀނ 6F8^7ޘ Lbj@$"= U9xXRS&Dt6h3#FV䄍HxMI9XRIF)%T8)Sf#T[%@&U jYՙg~G抻)&a&;Ir ˛\ijrhg!*t5褔Vj饘&imZ*jV^7*ɭz*w~1ZJ^ަ+JAƯn)h, ^FH"$(+pmw]jh Jƻokxptl2Ksq}g8(wm_xŽW`+|JL 8g@-DmH'=}&Ja1†_W!T0P1gjVSEj D08#D@s'ķuLB8y!% XQ<Ҙ e:wGpPBD8Jw[S8eV,O^L)3wcnF2_O;wRdr.!oԃjf>Rio/;8K4b>[)01?O{@5 0.Aqꂗ S&z GHLx%T@ /Mb107OpR< i(DNm*!!X&:SLH*Z:+d{ez1zT`VF֨RM<17b4G⭱}W T T:t F}P"ì8t pQIge\y4B'.AN &3ְ0˒'y3⎉8$.EyUlh$,X0:htHKnęv.VZX|%sFysAr'4cp,4I3Iz̧>فUz>PALdP7# [JhcOxJ~ Y $F-#豦sJjeH]";c)M_S<(tvZӜT:X;3̨Yø5fɪ A̫D5EĚdX ʉ}@)e\J׺xͫ^׾ `{7"Gűb)!^mbkT*yͲk4Hvke[2+ZaFgeL k1-l$ړjܪ#rrJ 8蹉F.6AA)$ոV&6w=2yy!79ڻ rHuť}fr/a έ맅 ػ VM>7!.a q&8NuBS'$xFZ[xe4YXW’tXi8eT`,?y |vxߗjZ;^MX/=ne=4b׼k `KZ~JT@4!;NA[ٌVTܓ,qw蓤^[-$H7vz-N!7)O 8$4(O;TDPD_)aA#2 ?y WGqw"gNۼzbokAt9&}HOҗtG;sugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/images/Music/image_devin_music_w333_lg.gif0000644000175000017500000003713710716617376032554 0ustar janijaniGIF89aM̙uvfS!Re-3ff̙f3̙f̙f@nz'0-)BH$ wkk,M@BHȣ2\:Ч4JZ밑L$0x,.4zn8|.<~~S ]bc`eat`vm  J _lqĢΣ`U ܶ{hitf^dj2KeB"\Ç ""q !^15pb݃T>T0e+WD% slA֢XcBB4QNRe?HXdΝ`apCҪ],ZIBjw .GitsX\P-l΅ } "i!GVCG$/\JB2tv-劋Pװ0HEm4@2[2[A=rkz/Q >:HXZNn3hcͫ_~f& -o<-O/(CGpDlMcf %00wCT~ 1O`|]gܵ^[pDxp`q(pb7 $HzQ*aG8au Rp@Bvhx䏥@\gY>1QtȊ7x*0ʩwc~XS'1x'wjd>=E:$|H9a~T\%`g9܄)Qfj/p8AuzNF `Yzqav*C.we:lZN7zC$p 頃-#"iWD$nF$i=0h/v$bvl(fQhXu"䪝jef*pˤ.D[V L]P%<1x!_YӮvbp# 0mڙ66:LJͧC&јpr=ws-t]vӍf՞2Y1 P0s gr0!bC {#ЅS9 |N~tb,.shC{ZBS;[SBpb̽]ġcq@,Rcr"хtW#P)D!h Kdph QHHД|̣*IV\nt"tc#)GD2|4%0H4jdlA΄3IiZSجf6j 4EKa&7\[YC!f4y#j҈Da.K>Jp,gLy BЄ2u&A  g3͎nݦFk6T#&EG1xfMnARh L<->[ vZ zPyŨT#UB5F{jՋn X;ӋӫM-7zk"p(՞U𦻻Uu-IV3)jU;Փ63(Z U 3bX Vue/Vokjj A,WjSunn/P%lbTD$Mc P=*S*4{K]Vݭv]fqcUur d4k,V@s}y׾=/++`խbM} \]݂Y$}a t1?]80zO\`YQ-L]"o׺eo5Vp[K܈>Xޥ1u+a#:?H,B$_?r8TLh %D>PN>t;ə9>@Ԙ@`ٓ3{Xf=BQB*$P4CJ5@?T$EC<i E?:DGTm7FSܩ29jC!FN$IwNBCG[d 8/CtHK.ITFQv͵ B"0D-OGzD:GN!-UGrDT4GLTJ7*t0`Cyu`X3bZb/ɣDIN$iJKԤ**,jNyTkڨ:ڃ\JYaթYkT%Uev4'J*D GJ%OF)J6Ee*JLU54\ꩠʬd\ S"V٤hW3WSxŭ6u7@<TE!*LeZq\*exS*\M%%huMeM@7%Xh1%=;@WE\j\&e KbQpr&k[FqAraW4[ug ;'5{r`&su[Pge[)]BZU"kdFҕq)j.{daF]V`4Vn[ hDK7!qk2[|i7>4Ua%njQVQ\{=Ц"o6e9[GUg_&oTqFerٖ[Zv^_r赶a&W@{reb9V^DRp2K;wgI+Gs1dj}&lki^ pauc6'pö%5p5wsûۼ+n[atv4q1wL pf9ukнg־-i˿8 ™q+c_%7j< o(a۸-fvg{6,j( ,n;7V7pa.\O1WW1֌ GZ`1߉0Z9ZjhFg!l{rzx7$U DL@ ߌ"m4WҢWwtP|= 7 Ե3}m!m|BR'LІ>}8\I^޷,Az\xW̲Y[-W`}htW 8 t "}1p@0 ρA6YFv2SBSGy f-k .p]= wɋ6@mi"s-5۽ܾ چԞmܧSLK[ d(N]n^o qIu08+90~Bx}Xfl_smI{ۧǿ2K3P f s#T ;o(AsksѝVz€eK (9S! ~:PE*.d (|ūVB=$:haBd{-ZlXZgqJ_Xx9ɠ}U;]ڍ^~"/7ᣂ&MaǑA D͢ĩzĜ+I.K7,]畯/ iH魷`OsMZo:"ΚN4ڎ;, DMrN_L≿+MMNcY/ 9ՑlX^6]uzcySKvhQ)h1c昡~7jzJl0^c>[o^Um@mp7#<ItQ/=Uo}e Lo1՛5ƕdDuTt2oy삙Ys^{Axst{[g]O}' POxI 33@%@x+l7JK}|7<щo|lw}%\_(ߡP8@vk=2H&9s\Y㒷ɰqA B.L a;f# xE no_'pt"uHd R Jllc"j)Pf$s(^I&n1c"EJJ _C~quL(ǝfh;@hF3QdeJE҉)RY1՗_q`b*Kӕ1GL hr?$XfFs`rKHBRB fj@WgV{>C9v\>+J]/]c8L=rzy3.jF0k͆]Y2]47<8ilUusܦ&?u7V{a,..v;#䕖6vnenfnu r1zV=/y齩S}[o7-{gx߿4&~7~w~ǟؘyoP& pP %0ů,p0( )PMQ0SpYO30aC0UA00]pfP C!HPw 0 p $  L!p=0O s ;E  @+e 0## tP0% 0 7#b !RIQ# 8# +1 550`@qV}1 'P_1.Q˯`qF1 ! CPQ P1 N̈́b&:a+q#q!1/1ugQ/P KЌ+'&#ծ1$;%/ q Տ r 2ݏQ~&#F&cI<#2 F& ) Qrb)gr'#d"ۑ+ #P(2( G$ 1)߰[ %{*%S+%R"22(1ֲ1 `W+R Pq2202010Q311(]p%XF6q+sJs4-8mdN3,W-9` r8r3S+R44#ҩ1S1:3%C &AP!q/[P8&E<2DB=׳#=4,bS  S>;!33+C!R'? A5Ur0sBSBA*寸JSBCy<DOtSA#.%TFr 0Cq<T@wr&CtDO8Hn44Ae0s.B 2Cݰ2gM1&@L Vt#6s![ >%'0Pj_r*TR5TSPAr u5QGPTa+0M] ߔB-7_uST9!IGu"J$Q F1GUKF0S[uVu>4֨=D!3w< ! ƾ _zi{מ7}$,?u1S=Qσ?ٖ^߫pr"x&]1$x-ô=;S}][ښUzYͷt۽ċ^ !qh,"8@iF+-w8,c5|6{Le) .F):JV!pm=-}ZV^r"da5]bBZ6 f.>R&2)`NGBnLsa0<1+Ŋ ##;K&S?orS#M[RʎXUCo]># a@(ŠAFQdy% r%˖+;iEZS.9!ozr1%V6;.!Vbz^ ەj<ɤ O6=ԎTչ]}AzW ^=8ƍ+jۈl\<1/15`Br>+k_{Ƞڶkk " (01W $Zr|7 H\;-@m]2,<1∏G|9 wbOMwgi۝fFj$x@[y6x{V8 T}ugdLՌ#Y&Ge>U`.!hh1@xf!n2ɡwlyazJ~[q bkFm6&?N4*u׃գO- xxW瞕&J:"ԇe @Jrl 7vAYd aݫYx Y`a8 (PXmOaWlm,q[l:x#:hVjz_*:Rݹj7k*DK/7̋ =p&oy VY|{ ꚼ 5r-(RXS<ԮQmZ8\[щG0EQEۜ^Bnj(zH&˃Vʸx.פ dǖb )N;N i:x޼SW3$}\,c'/kނiVOwJ~ E3^Z-*]"mMʜHA0P^ӽ|3_p>- v@ԠAOj (x]dD@Y{^6Pa)8yexIL"WvXalK 5x@ xU졺Lt.{r#"h ⱉǃ eP}dY ŖHs8d%(IyI/~ΎJ$!϶G B {W4XH"2 I4!\M3&Ņ\=9JYP392 !E+[&#y!1ƎUV'3 RN<[%bv_E,1XHT"@0UbR9nPj,J(vArUz$xI]W9ZUd(#_ֱC0]-k[Zղx-k36ݭn{6ekO5$}4c> hδi%2@7/yk7Ezk|/}k޷ݯ~{_q Yh.pܠ+_RyHprl=p ;81I,!ab8/glcޘEL$7kI(osv"xA ?Q*b_9/ֲYlQ /v0\c38clMٜ%2sw 8v0ZdA3bc+o9b^4eY=pl3ݝt7A` 6ic&7](Bydz4%^ڰ|Jcٓ0'HNB.su Eލ4a>GKEuMשn&_賁-c;&1yMlJZMS=|R]6~bÈqH$۶yf8g?7mrdx=p}K4~m;\†IW"f[uqqOq!rEαrW-9 smfcyi,{۳>>]t|/}nqml^8/{ߟLs=4?Lz=\0<1q~`u@~)X=>r=JeC(g.볏}/,oM-!*l?;?rW˙nd:0Wӎm|d%G]߇_/Xߕ| j^j_^95l}\X@Zl Zr{AyK^@^@xK|}ڏgqa`Z@$-<ơWWFlڡaxU ^"} %ߘaD!#: #.:%ZjT"z'ڡеwٞH*Ȏ*")%:6V!nyչ`E"!"_"-R4vbMtb5f'bd"4NC+*bq c#2+,-b.R#cZ.Vc>>z.r*V@aC~ 4\5AX$8f#5NGv=#8#.iGZGNXd-Vb=fHE"'*MN^$+@e?Z3Šm톚$kDSRSV=$7Ff"zz`%J##~_q"%^Xd\X\$dt[XNf[=dA fYNcNQ7eIU"&@l6Rbv*2⠸$LVaB&#aF`Wƥgn"hKf,$;^Zd_H8`Pm%Z.&cc&VV&e%Wk$t&.DgH"'Q#n bĥl\#tuxpr~pfvgtюf-P mfqgm[*gsb$6t¢yR|Ҧt֎4c{Lvg|JCaޡ>VbLG}:rfgFf$}$6hFb&SBcVdhZagA hfc>b|jz( h,b]HdVgd%ڙKFK[Ψ~^bX"#5h=bb.bq;d(>dFgZdr,)ZևJ$5+ީF qEj(cufkN#(6;)aMFhfN)TVb&(U%jN4'uh|crE7Z)kRcPf⩺e}[BMGJM (isFR!'eɪ\*l jf"H$$\@+(ڤ#fh;ra$^)."~kΨʩĊiVx¤.i:$*+o:Xe7i6h8,(:k26(blΩ_*fF,GNm#,ke8VRboFXt;,j(PbkˆM&Fo^-gymZ[v!TmZ+*$XJ.".l6@랒g jk&s*жݢjk.YfBN-g-f-V.bmM6nJ.\-,ƤVj/m.ڞ.jo"mnR)xm%bjhuƫޢbn..N!֎vnH6)bV/Fm."-.'nVKo^-z/"j5brpzoc/foo-~ RhV.jHTkjr-Z'%K@,viaJ/ ^/ p>#-Ύ(q {k^(j0J'eĀ,Ylz&\sn1 {#2pݲg!i1gh 7kf11g*r/p"{qG DG#O dz&m>lݚ'32uvۧJ,ݪoo0,r.$1"3Zr03'c12Jjz*;3O,&{ 2Z4.ssd2q83(1Ivs6qܪ63³gC׳653ms?s' t34N?B.Cq;sugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/images/Music/thumb.gif0000644000175000017500000000121510716617376026747 0ustar janijaniGIF87a22ff+4fg̛ffy,jff 33ff,f"3fg 33ef)f33lf3333,22`"dihlp,t*vNEYxr)I (zK,N0tʭ:X&dPl"Go% n#{,h}~ZC0L*(Li+T-~A-*J@+#J0 Lx=K+K)XJ =& :K"K5 @ 4H V$(X0a…^|Q&Lc!Ä|AĀ1#B9.c,v<(bCR ch2ϗ ndAc I84bˎ6P! *ڱN 85A±ԃ6 ʂR&ϭm޻x-p/yF*WߟLm q1 U/X^-`s M;Ip֠Nx/ַ,1RW>\7EkcLp{̚JnwՀ{w ӣy =N9C2lO_Zl'/K]!;sugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/images/Space/0000755000175000017500000000000010755626243025111 5ustar janijanisugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/images/Space/image_esim_h250_w250_lg.gif0000644000175000017500000000361510716617376031705 0ustar janijaniGIF89a3f,@0I8ͻ`(]@alp,tmx.. pH,}H/I2:Шt eZvKz`vRς:ͼF׀vB~A D+6zg.Ꮣѐ+C. =LED:]Bp#ƌ<DGDI9(]嗌in -u *>))!Jի$bU֮_+lRfӪ][ؖ0 wSVԝD o L{UBs͑qdZ7ULbXVpsJa MiLZqy#`h˼xrnڳH }A`2`3ӳh[]Q'Bōb:~>mXcA~%4QWO̧=uX#PX+Wաa$_(n8Pb0(4Ջ6,-w͏5*8AZe$9[mK"C8MBAtX> ^[P$dhG3ZfryQb7s^Z l!fl~{O!Beafˡ^èf&Vji%}Ʀc}:9U$TLpi&}*[–^"鰅g,Eln|6z8Wm9Kmݮ=Ntҹi#i)ڄ?Gp!' /)ܯ{:-`8:K>xn]!/H`+~%LJ ,3gL0։Γl`[`xIՉV_}cj40rd#tS0v 2«NZ6UZC~چ'J7"B@J:Y7w;O>:ꬷN4(gS5'xW݅~ On!}pPϭk{i _nE,j/-ɿN"OgBD$MAOБ@8hVSbBN!j$6='OZ$ҦҮ,pگ6!Ah:ϥ5hc.hb%axiKe`S&7oj)\Lܲ1s^B3A שS8<=r}y & ࡦF~,!\Cc3N;A4/` 7_mA+Oڙq-a᭔Mqxa)tNHBT,+NMً1ۤ)(#ElEN)o2e}Qbf56f&#ֶƑfLP+jW[+4aSZ:,t8zj~z>#YbK]gP(ir=ڴN'k/A/,Ԣۮ9j%- !F=oZfxy _c.A1{H. x6"Ke6J0u$_c)r~yiG -)y.`%;sugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/images/Space/image_aisc_h250_w313_lg.gif0000644000175000017500000000721710716617376031671 0ustar janijaniGIF89a9f f33gf3333ff33fff3f31,9@pH,Ȥrl:ШtJZجvzxL.i'K/r ~QyxM }Z qXyLln_xfMohnfb[]nmI{BNxG@@ Ah]Рo\n$|@T QPB(O`˗(X0iv,6f%S *&̣1M%ja¨vIʃ$ZKGe2γU. L(:r)ךfώSs.yrdJW,۷? ʄ5% 'uzѦ ꇨQGUd&<2k%v`$-D#xÇFb@*RvXC:N 28=Χt%^1\O˗}7!JA_‘ ix EnAax"jCȀWD(b**sf7Ս) '%/ߌ8>bB~IQ;bxuu{G xa2WQ<[3Ӑ}l?-ިv|}j S-CԭbP"fQw. ٫fyr[~8{>饛>:P:.nwQ4;se/(_RL #OxN'|՞#ZbkLχ8߰м  `;7 1a;4Wկ`!&+D %5L['!E_ a+ma @4fcKFZwgtcP@DЃ&PhS"8T*Pbv)9Qp@k "TbU^D x~GGfUАaZ@0`anWHP-#U3 2*n.Kv@d0ȕīXWQDy :tL,7.fd4@!J CT#//Xr, )7uL%(%ePy0e.եj"VPYI9͉A^tfTRp)OMe(,HPLp [lL,]ι X1ªZ{z21DZ`4H"Nq"IdQFFt5<ꒅƥ?G aH`*x 4]I8^!_Jh W.]qUV9gdڇc=ÎV0f1"4yլJ#Rb vuOmEnC#]YpwcF 9\k)9-=E)|IC!*,5GVB͸v⠫X*~kn7jaʂuWd*d5<,K-x:!T*U_,`Fs]ʁ`, vL6Dž)llnVƇbjM%NW0g̾,zI #:=~&(26a$S"J1, s0h)&A$g'$ G3פwvx/^ pJFR7BԸ >65 O-q6NAPJ-UԜ17oLD*ǁysfUNC:jR'J}AiX9 V 9C?tXq6%0.?/tQ3cHG6Cٱ4@oQ,4Ems0G C7u$ߐmx&2ž -[&4Xf='83.Ё!G/,ڶ|C@-fl!U&ݝlKB̸Ntuom;J-Q21h.sy0/JXT!ook$8aQ7Q$R%b! 'ণw{ bAl@e0`M([ QݐA:8hK\h0c;'^Sy@#{rr7̞^-}GV #6‘3C0Ng]&w_8Vj~Tqc(ߒ(yP_+Mk*L[;&a 7Z  C.P_I/CU㇀JLz4Q. XM3{4Q/`[P}7~Հy|} TOu3^aO^5g%XJׂSf``lTބ3UdJxLPTP G`KSGh2e(gjyP~e#Xn}rPovC0m#X}hQF}1NnAQ}ŇHX}:Qz#<~3FDEY~5NDRAjg>щȃg0>h^HD ,R(2 vm(f h+"-OsҎxtU!]W8`T8% Q {sW0'+2T^xi(13Ta3U% A jSDz4=l !zF%)V‘EWJ3"(o"M'xab6iW[#R$E)WCHB ^)PEiWZBYMn_jrݠ[bCF0U_sx):w9Ixh2:9%r UPEYZ uoZ97^d4Ps𔦥*CryT#E_62P隍1yFD`}AA0SY!ʹ` vsZ@i 4yX!@'`U28H[6&3A"B`YJ"8U7gu_*ʅeXpa *JSpme[a=W [N*6f"7'&F 4A*Fs)A#SaLʋTpbV'#c\XzbZ'eJ[Tdpb¦`pa:_ vzu\|ڧ{I:CZZ;sugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/images/Space/image_tral_h250_w404_lg.gif0000644000175000017500000001341310716617376031710 0ustar janijaniGIF89a f#f333333ffTflf(33f33333ff3u{g{3!333,@!dihlp,tmx|pH,$O8#"Xu65LSzhQ9Ifi=w.sYq=g)CO *L'Mg3 &t`ZyAݽDc9 ;w :a&H-?6h`Id 1I'D3[c4 8s4`ӒΟ8?dRD@Y\ʴДJ炩XGz_ӯBRңK!UmFZ@@pʭx Z79Ri(kJ HfTx#8ɘ򬬫(`X"znq4"Mb~׮KW= \ֆMaq4Yo]S螽=[;0 6wE6u>|8yGAXP VB%2j>آ⍻l0b#c*pH#|NB8$GXb Uv0yKM$\Y$=\J^eetUޟˍ7AÌy2I#:hpa)\w_V6ex#) ld6( Zb\%`'B8 z,q#*`UkEf햡ViiJ^Sf9 A 'LH*1 o%RK e5l)G;Cwzl6*,r4ܲZpa<|3,+< & %$"ŰbutkǒEF- lZq:72VbACzxB1[B)L D0c)R?L!abTϕT{~@.cD9kA((6`9j Ao>@G E(95 Slzq ;7RykU n;=;dͽR$`=@]C%$Os[8mI~ o*3[0jtp | N"  KmnBh^ `43PwlH 8Ixl.LDEzh1f~bb0p ^$P#)_Lf+fBI!%fP} # )O':>y# ߁!2E<72Xڰӈ0 D&# 2GWڑyEFq Qǔ̬2hJi#sQˋ4)Ư + 3gxC.?K4Bf7F<=SƁ H Kj7Q3C5C-pP!O}(K@$U[Ert_b WOL=GMlA䟕D N̚ tBh91, ՆUP4`]$l 3FO Tc0(Ej, PhæUzq_W͖ڬ%YVC购p͎rUxͫ^bjX$FO{FP@afXLĪ\lFҚD,+{xi-)xڢ05UqM,]AYC䬳2PբY{G;pZSh7֟s@nF"[A6%AkQ CaO)8&` g4oRV rj=ͩ k7yhLml&ݖ̷no˛ XwNX87IJ ULMzk MK !yZ?Viu*E I8`G,rz?p5&Ovr-ߋ|e  B@Z:$ Nq\v1<Eoq66:s3v%nGևQP&ssџ;l3~熏<,%d7&7!ΛE^]sy_ԝ6!6*w'?b]<Sy&/hA =<4EhC'.rfr_z[ h{GD}JV$-hE>~ L骣? ڤb-("{D$g |,%cCzW&Hi#:tSF$ C;YWFjQDa"'xTw:‚G"yI5{gGGEէa|0*嗃kB&x@TXVH3{@87`&E"SxfQwEF\JC(c؆XWE7'{1P VE| LЄ1:uh Y Ѕa@q‚hWHV!J EQ%ǡǁMh|c,0 S\Q`_%c,z^ uRXWPb aC3yNJ~b lP(x X X_h8f;u-{CRY/qTLveP.G~He 9P'F3֑5֠Ds}U6(Y_Z);9:y.R3h;9=yWɃA CpIٔFR9TYAV:I6^9@_9dYfyhUu` iٖQZD ̳j{W\{_oeT$#w ʣ bhbSr15/9g#^b.NI%^4Oc*ZH%NPF 9y )y a\Q F#M4^֚KyMb2uOcr t 6.g81ޒkR&6\E@6˅ ib50}@% :e)%ej)h|rC9tÛI#4LP Jo2lii@52Љ4POo @nOfdA D^)\:sH&F H_' )f4|>#0j^F1"&° 7q[`;dc@0Ce@c =S }ա0!7*/>.#d<%c'&|hԦPxcS3$6yJ9m VFf.H3nJ(\Ñ':Nce1jq0y¢BʺF jJ:pPb<0.3;/qe0 @ce 4a^cpڪo5qE3;Dبj2̣î9n@0#Y'C`|&+7;+Sy@3.P@Sa¨:,W G>$KSl13;jJBK HJ;ac;+ ~n$ Sio nq>\۶SVXvTV|k}a3CQCO<.&ѓm yt[Tȗ]+@r)N_C!p3spR V>[AA鱺\8!Ûnrw'ɫh9PH] ً *@dj9v狾wkUҶ[ w\Qv>W@\|r>:۠A,wghgq(#dEQ` ;udC)\ 4B,'S5 as_>B l z{+YL9xr'O &6;tEShżBƵqsRW> B5p*|%A(=HoPtBa (vL q| \Lngi'vd yv'RJ7w0&eU<7М10E՜ lcK1< TO2G/U#x?yLrXThyzm18˾&p;I|fiKw 5R`]dτs]."a"r"h Z̾@{髄gˁz6B} 1 -ĭg"`@XJ9qh,( T]H'}M2r|1-@Q{|' :hmԚGy}bU +xEՆx/tMpG -YQ Od}0Q(jP5MG'ib)Ub?Etm֟ "xWڧTQ/]gpځΔ=l,B a3ݼ-YX2,dj4%ܽ`u`//$q =~}!,W茆KXԞDӂpKQ֊ v g SlVw;pWd&X&:Jd<`r}DbIQPL͢#=)IoX2FhRaY3nr0bNJlD0I"q)P^"M*+#ͦl BΔsM&S26G DT%CB *{" CO<١z}0Z`|Q]ݘM$y4zE'Ԉ%~` 'QU<8"_6 }=]RT //29@iK%פֿJ2g;O2.RKd8TqY bJ׮췀u R<3jM88:Qvޥi)9b4ΞN = 㵉o 01:ʒ3ssB."BRe*fz9V y*0c^3/:8Wyt5VSe2!?z1;j T g elT+dm3I*|6#4>k:7t#[8ؿo8CUJL#Օ\:O?N@>8y±<ӭRyD!h<o%|BRb6l>-r</ F >-2"BFJN)6^b image/svg+xml sugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/images/Sequencing Puzzles/0000755000175000017500000000000010755626243027614 5ustar janijani././@LongLink0000000000000000000000000000015200000000000011563 Lustar rootrootsugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/images/Sequencing Puzzles/image_Numbers.sequencesugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/images/Sequencing Puzzles/image_Numbers.seq0000644000175000017500000000001010716617376033076 0ustar janijani1 _x_+1 ././@LongLink0000000000000000000000000000015200000000000011563 Lustar rootrootsugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/images/Sequencing Puzzles/image_Letters.sequencesugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/images/Sequencing Puzzles/image_Letters.seq0000644000175000017500000000002410716617376033112 0ustar janijani"A" chr(ord(_x_)+1) sugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/images/Sequencing Puzzles/thumb.svg0000644000175000017500000000736110716617376031467 0ustar janijani image/svg+xml 1 2 3 4 sugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/locale/0000755000175000017500000000000010755626244024051 5ustar janijanisugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/locale/es/0000755000175000017500000000000010755626244024460 5ustar janijanisugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/locale/es/activity.linfo0000644000175000017500000000004010755626240027333 0ustar janijani[Activity] name = Slider Puzzle sugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/locale/es/LC_MESSAGES/0000755000175000017500000000000010755626244026245 5ustar janijani././@LongLink0000000000000000000000000000017200000000000011565 Lustar rootrootsugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/locale/es/LC_MESSAGES/org.worldwideworkshop.olpc.SliderPuzzle.mosugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/locale/es/LC_MESSAGES/org.worldwideworkshop0000644000175000017500000000242510755626240032552 0ustar janijani  (5=FOXajs | 5 /? H S ^ i t        AnimalsBirdsChoose a SubjectClose LessonInsectsLesson 1Lesson 2Lesson 3Lesson 4Lesson 5Lesson 6Lesson 7Lesson PlansMusicMy PictureSea LifeSequencing PuzzlesShuffleSolveSpaceSportsTime: Project-Id-Version: PACKAGE VERSION Report-Msgid-Bugs-To: POT-Creation-Date: 2007-09-10 10:34+0100 PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE Last-Translator: FULL NAME Language-Team: LANGUAGE MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit AnimalesPájarosElegir un temaCerrar lecciónInsectosLección 1Lección 2Lección 3Lección 4Lección 5Lección 6Lección 7Planes de la lecciónMúsicaMi cuadroVida del marRompecabezas con SecuenciasRevoltijoSolucionarEspacioDeportesTiempo: sugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/locale/ko/0000755000175000017500000000000010755626243024461 5ustar janijanisugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/locale/ko/activity.linfo0000644000175000017500000000004010755626240027335 0ustar janijani[Activity] name = Slider Puzzle sugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/locale/ko/LC_MESSAGES/0000755000175000017500000000000010755626243026246 5ustar janijani././@LongLink0000000000000000000000000000017200000000000011565 Lustar rootrootsugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/locale/ko/LC_MESSAGES/org.worldwideworkshop.olpc.SliderPuzzle.mosugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/locale/ko/LC_MESSAGES/org.worldwideworkshop0000644000175000017500000000332210755626240032551 0ustar janijani )   - 3>U^gy5-48 R`qx   #&+Rfm t~'!  AnimalsBirdsChoose a SubjectClose LessonImage FilesInsectsLesson 1Lesson 2Lesson 3Lesson 4Lesson 5Lesson 6Lesson 7Lesson PlansMusicMy PictureNot a valid image fileOverviewSea LifeSelect Image FileSelect image to share...Sequencing PuzzlesSolveSpaceSportsTime: Waiting for game image...Waiting for remote game...XOProject-Id-Version: PACKAGE VERSION Report-Msgid-Bugs-To: POT-Creation-Date: 2007-09-10 10:34+0100 PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE Last-Translator: FULL NAME Language-Team: LANGUAGE MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit 동물새주제를 선택하세요레슨 닫기이미지 파일곤충레슨 1레슨 2레슨 3레슨 4레슨 5레슨 6레슨 7레슨 플랜뮤직내 모습이미지 파일이 아님개관바다 생물이미지 파일을 선택하세요함께할 이미지를 선택하세요퍼즐 정렬하기풀기공간스포츠타임게임 이미지를 기다리는 중...먼 게임을 기다리는 중...XOsugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/locale/pt/0000755000175000017500000000000010755626244024474 5ustar janijanisugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/locale/pt/activity.linfo0000644000175000017500000000004010755626240027347 0ustar janijani[Activity] name = Slider Puzzle sugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/locale/pt/LC_MESSAGES/0000755000175000017500000000000010755626244026261 5ustar janijani././@LongLink0000000000000000000000000000017200000000000011565 Lustar rootrootsugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/locale/pt/LC_MESSAGES/org.worldwideworkshop.olpc.SliderPuzzle.mosugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/locale/pt/LC_MESSAGES/org.worldwideworkshop0000644000175000017500000000353010755626240032564 0ustar janijani!$/,  # +7?HQZclu ~   )0JGe      & 0 : DN_ gt #  #;  ! AnimalsBirdsChoose a SubjectClose LessonGame Started!Give UpImage FilesInsectsLesson 1Lesson 2Lesson 3Lesson 4Lesson 5Lesson 6Lesson 7Lesson PlansMusicMy PictureNot a valid image fileOverviewSea LifeSelect Image FileSelect image to share...Sequencing PuzzlesShuffleSolveSpaceSportsStart GameTime: Waiting for game image...Waiting for remote game...Project-Id-Version: PACKAGE VERSION Report-Msgid-Bugs-To: POT-Creation-Date: 2007-09-10 10:34+0100 PO-Revision-Date: 2007-05-23 10:48+0100 Last-Translator: Carlos Neves Language-Team: Portuguese MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit AnimaisPássarosEscolha um AssuntoFechar PlanoO Jogo Comecou!DesistirImagensInsetosLição 1Lição 2Lição 3Lição 4Lição 5Lição 6Lição 7Planos de EnsinoMúsicaMinha ImagemImagem inválidaResumoVida MarinhaSeleccione uma ImagenSeleccione imagem para partilhar...SequênciasBaralharResolverEspaçoDesportoIniciar JogoTempo: Esperando pela imagem para jogar...Esperando por jogo remoto...sugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/activity/0000755000175000017500000000000010755626243024445 5ustar janijanisugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/activity/activity.info0000644000175000017500000000031710743343012027142 0ustar janijani[Activity] name = Slider Puzzle service_name = org.worldwideworkshop.olpc.SliderPuzzle class = SliderPuzzleActivity.SliderPuzzleActivity icon = activity-sliderpuzzle activity_version = 5 show_launcher = yes sugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/activity/activity-sliderpuzzle.svg0000644000175000017500000000555310716617376031570 0ustar janijani ]> sugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/i18n_misc_strings.py0000644000175000017500000000034510716617376026534 0ustar janijani_("Sea Life") _("Animals") _("Birds") _("XO") _("Sequencing Puzzles") _("Sports") _("Insects") _("Music") _("Space") _("Lesson 5") _("Lesson 4") _("Overview") _("Lesson 3") _("Lesson 7") _("Lesson 6") _("Lesson 1") _("Lesson 2") sugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/SliderPuzzleUI.py0000644000175000017500000006153110743343012026046 0ustar janijani# Copyright 2007 World Wide Workshop Foundation # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # # If you find this activity useful or end up using parts of it in one of your # own creations we would love to hear from you at info@WorldWideWorkshop.org ! # import pygtk pygtk.require('2.0') import gtk, gobject, pango from mamamedia_modules import utils from mamamedia_modules import NotebookReaderWidget from mamamedia_modules import BorderFrame, BORDER_ALL_BUT_BOTTOM, BORDER_ALL_BUT_LEFT from mamamedia_modules import LanguageComboBox from mamamedia_modules import ImageSelectorWidget from mamamedia_modules import TimerWidget from mamamedia_modules import CategorySelector from mamamedia_modules import BuddyPanel from mamamedia_modules import GAME_IDLE, GAME_STARTED, GAME_FINISHED, GAME_QUIT #from utils import load_image, SliderCreator, GAME_IDLE, GAME_STARTED, GAME_FINISHED, GAME_QUIT, trace #from mamamedia_ui import NotebookReaderWidget, BorderFrame, BORDER_ALL_BUT_BOTTOM, BORDER_ALL_BUT_LEFT #from toolbar import SliderToolbar #from i18n import LanguageComboBox import locale import logging from glob import glob from SliderPuzzleWidget import SliderPuzzleWidget from time import time import os import md5 try: from sugar.activity import activity from sugar.graphics import units _inside_sugar = True except: _inside_sugar = False SLICE_BTN_WIDTH = 50 THUMB_SIZE = 48 IMAGE_SIZE = 200 #GAME_SIZE = 294 GAME_SIZE = 574 #MYOWNPIC_FOLDER = os.path.expanduser("~/.sugar/default/org.worldwideworkshop.olpc.SliderPuzzle.MyOwnPictures") # Colors from Rich's UI design COLOR_FRAME_OUTER = "#B7B7B7" COLOR_FRAME_GAME = "#FF0099" COLOR_FRAME_THUMB = COLOR_FRAME_GAME COLOR_FRAME_CONTROLS = "#FFFF00" COLOR_BG_CONTROLS = "#66CC00" COLOR_FG_BUTTONS = ( (gtk.STATE_NORMAL,"#CCFF99"), (gtk.STATE_ACTIVE,"#CCFF99"), (gtk.STATE_PRELIGHT,"#CCFF99"), (gtk.STATE_SELECTED,"#CCFF99"), (gtk.STATE_INSENSITIVE,"#CCFF99"), ) COLOR_BG_BUTTONS = ( (gtk.STATE_NORMAL,"#027F01"), (gtk.STATE_ACTIVE,"#014D01"), (gtk.STATE_PRELIGHT,"#016D01"), (gtk.STATE_SELECTED,"#027F01"), (gtk.STATE_INSENSITIVE,"#CCCCCC"), ) def prepare_btn(btn, w=-1, h=-1): for state, color in COLOR_BG_BUTTONS: btn.modify_bg(state, gtk.gdk.color_parse(color)) c = btn.get_child() if c is not None: for state, color in COLOR_FG_BUTTONS: c.modify_fg(state, gtk.gdk.color_parse(color)) else: for state, color in COLOR_FG_BUTTONS: btn.modify_fg(state, gtk.gdk.color_parse(color)) if w>0 or h>0: btn.set_size_request(w, h) return btn class SliderPuzzleUI (gtk.Table): __gsignals__ = {'game-state-changed' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (int,))} def __init__(self, parent): super(SliderPuzzleUI, self).__init__(3,3,False) self._parent = parent # We want the translatables to be detected but not yet translated global _ _ = lambda x: x self.labels_to_translate = [] self._state = GAME_IDLE inner_table = gtk.Table(2,2,False) self.add(inner_table) self.game = SliderPuzzleWidget(9, GAME_SIZE, GAME_SIZE) self.game.connect("solved", self.do_solve) self.game.connect("moved", self.slider_move_cb) self._parent.connect("key_press_event",self.game.process_key) self._parent.connect("key_press_event",self.process_key) self.game.show() desktop = BorderFrame(border_color=COLOR_FRAME_CONTROLS) desktop.show() desktop.add(self.game) self.game_wrapper = gtk.VBox() self.game_wrapper.show() inner = gtk.HBox() inner.show() #BorderFrame(border=BORDER_ALL_BUT_BOTTOM, # border_color=COLOR_FRAME_CONTROLS, # bg_color=COLOR_BG_CONTROLS) inner.pack_start(desktop, expand=True, fill=False) self.game_wrapper.pack_start(inner, expand=True, fill=False) # panel is a holder for everything on the left side down to (not inclusive) the language dropdown panel = gtk.VBox() # Logo image img_logo = gtk.Image() img_logo.set_from_file("icons/logo.png") img_logo.show() panel.pack_start(img_logo, expand=False, fill=False) # Control panel has the image controls control_panel = BorderFrame(border=BORDER_ALL_BUT_BOTTOM, border_color=COLOR_FRAME_CONTROLS, bg_color=COLOR_BG_CONTROLS) control_panel_box = gtk.VBox() control_panel.add(control_panel_box) spacer = gtk.Label() spacer.set_size_request(-1, 5) control_panel_box.pack_start(spacer, expand=False, fill=False) # ... # Slice buttons btn_box = gtk.Table(1,5,False) btn_box.set_col_spacings(5) btn_box.set_row_spacings(5) btn_box.attach(gtk.Label(), 0,1,0,2) #spacer = gtk.Label() #spacer.set_size_request(-1, 15) #control_panel_box.pack_start(spacer, expand=False, fill=False) #cutter = gtk.HBox(False, 8) #cutter.pack_start(gtk.Label(), True) self.btn_9 = prepare_btn(gtk.ToggleButton("9"),SLICE_BTN_WIDTH) self.btn_9.set_active(True) self.btn_9.connect("clicked", self.set_nr_pieces, 9) btn_box.attach(self.btn_9, 1,2,0,1,0,0) #cutter.pack_start(self.btn_9, False, False) self.btn_12 = prepare_btn(gtk.ToggleButton("12"), SLICE_BTN_WIDTH) self.btn_12.connect("clicked", self.set_nr_pieces, 12) btn_box.attach(self.btn_12, 2,3,0,1,0,0) #cutter.pack_start(self.btn_12, False, False) self.btn_16 = prepare_btn(gtk.ToggleButton("16"), SLICE_BTN_WIDTH) self.btn_16.connect("clicked", self.set_nr_pieces, 16) btn_box.attach(self.btn_16, 3,4,0,1,0,0) #cutter.pack_start(self.btn_16, False, False) #cutter.pack_start(gtk.Label(), True) #control_panel_box.pack_start(cutter, True) #spacer = gtk.Label() #spacer.set_size_request(-1, 10) #control_panel_box.pack_start(spacer, False) btn_box.attach(gtk.Label(), 4,5,0,1) control_panel_box.pack_start(btn_box, expand=False) self.thumb = ImageSelectorWidget(frame_color=COLOR_FRAME_THUMB, prepare_btn_cb=prepare_btn, image_dir='images') self.thumb.connect("category_press", self.do_select_category) self.thumb.connect("image_press", self.set_nr_pieces) control_panel_box.pack_start(self.thumb, False) spacer = gtk.Label() spacer.set_size_request(-1, 5) control_panel_box.pack_start(spacer, expand=False, fill=False) # The game control buttons btn_box = gtk.Table(3,3,False) btn_box.set_row_spacings(2) btn_box.attach(gtk.Label(), 0,1,0,3) btn_box.attach(gtk.Label(), 2,3,0,3) self.btn_solve = prepare_btn(gtk.Button(" "), 200) self.labels_to_translate.append([self.btn_solve, _("Solve")]) self.btn_solve.connect("clicked", self.do_solve) btn_box.attach(self.btn_solve, 1,2,0,1,0,0) self.btn_shuffle = prepare_btn(gtk.Button(" "), 200) self.labels_to_translate.append([self.btn_shuffle, _("Shuffle")]) self.btn_shuffle.connect("clicked", self.do_shuffle) btn_box.attach(self.btn_shuffle, 1,2,1,2,0,0) self.btn_add = prepare_btn(gtk.Button(" "), 200) self.labels_to_translate.append([self.btn_add, _("My Picture")]) self.btn_add.connect("clicked", self.do_add_image) btn_box.attach(self.btn_add, 1,2,2,3,0,0) control_panel_box.pack_start(btn_box, False) # Control panel end panel.pack_start(control_panel, expand=True, fill=True) inner_table.attach(panel, 0,1,0,1,0) self.game_box = BorderFrame(border_color=COLOR_FRAME_GAME) self.game_box.add(self.game_wrapper) inner_table.attach(self.game_box, 1,2,0,1, gtk.FILL, gtk.FILL) lang_combo = prepare_btn(LanguageComboBox('org.worldwideworkshop.olpc.SliderPuzzle')) lang_combo.connect('changed', self.do_select_language) # Push the gettext translator into the global namespace del _ lang_combo.install() lang_box = BorderFrame(bg_color=COLOR_BG_CONTROLS, border_color=COLOR_FRAME_CONTROLS) hbox = gtk.HBox(False) vbox = gtk.VBox(False) vbox.pack_start(lang_combo, padding=8) hbox.pack_start(vbox, padding=8) lang_box.add(hbox) inner_table.attach(lang_box, 0,1,1,2,gtk.FILL, gtk.FILL) timer_box = BorderFrame(border=BORDER_ALL_BUT_LEFT, bg_color=COLOR_BG_CONTROLS, border_color=COLOR_FRAME_CONTROLS) timer_hbox = gtk.HBox(False) self.timer = TimerWidget(bg_color=COLOR_BG_BUTTONS[0][1], fg_color=COLOR_FG_BUTTONS[0][1], lbl_color=COLOR_BG_BUTTONS[1][1]) self.timer.set_sensitive(False) self.timer.set_border_width(3) self.labels_to_translate.append((self.timer, _("Time: "))) timer_hbox.pack_start(self.timer, False, padding=8) self.timer.connect('timer_toggle', self.timer_toggle_cb) self.msg_label = gtk.Label() self.msg_label.show() timer_hbox.pack_start(self.msg_label, True) self.btn_lesson = prepare_btn(gtk.Button(" ")) self.labels_to_translate.append([self.btn_lesson, _("Lesson Plans")]) self.btn_lesson.connect("clicked", self.do_lesson_plan) timer_hbox.pack_start(self.btn_lesson, False, padding=8) vbox = gtk.VBox(False) vbox.pack_start(timer_hbox, padding=8) timer_box.add(vbox) inner_table.attach(timer_box, 1,2,1,2,gtk.FILL|gtk.EXPAND, gtk.FILL) #panel.pack_start(lang_box, expand=False, fill=False) self.do_select_language(lang_combo) self.buddy_panel = BuddyPanel() self.buddy_panel.show() if not parent._shared_activity: self.do_select_category(self) else: self.set_message(_("Waiting for remote game...")) # Contest mode flags self.set_contest_mode(False) self._on_lesson_plan = False def set_message (self, msg, frommesh=False): if frommesh and self.get_game_state() < GAME_STARTED: return self.msg_label.set_label(msg) def is_initiator (self): return self._parent.initiating def set_readonly (self, ro=True): self.thumb.set_readonly(ro) for b in (self.btn_9, self.btn_12, self.btn_16): if not b.get_active(): b.set_sensitive(False) @utils.trace def timer_toggle_cb (self, evt, running): logging.debug("Timer running: %s" % str(running)) if self._contest_mode and running: self.set_game_state(GAME_STARTED) self._send_status_update() #if self._contest_mode: # if running: # if self.game.filename and not self.game_wrapper.get_parent(): # self.game_box.pop() # else: # if not self.buddy_panel.get_parent(): # self.game_box.push(self.buddy_panel) def _set_control_area (self, *args): """ The controls area below the logo needs different actions when in contest mode, and also if we are the contest initiators or not. """ if self._contest_mode: if self.get_game_state() > GAME_IDLE: self.set_readonly() else: if self.is_initiator(): if self.timer.is_reset(): self.set_message(_("Select image and press Start Game...")) else: self.set_game_state(GAME_STARTED) else: self.set_message(_("Waiting for Puzzle image to be chosen...")) self.set_button_translation(self.btn_add, "Buddies") self.btn_add.get_child().set_label(_("Buddies")) def set_game_state (self, state, force=False): if state[0] > self._state[0] or force: self._state = state self.emit('game-state-changed', state[0]) self._set_control_area() if state == GAME_STARTED: self.set_button_translation(self.btn_add, "Buddies") self.btn_add.get_child().set_label(_("Buddies")) self._send_status_update() def get_game_state (self): return self._state def set_button_translation (self, btn, translation): for i in range(len(self.labels_to_translate)): if self.labels_to_translate[i][0] == btn: self.labels_to_translate[i][1] = translation break def set_contest_mode (self, mode): if getattr(self, '_contest_mode', None) != mode: self._contest_mode = bool(mode) self._set_control_area() if self._contest_mode: self.set_button_translation(self.btn_solve, "Give Up") self.btn_solve.get_child().set_label(_("Give Up")) self.set_button_translation(self.btn_shuffle, "Start Game") self.btn_shuffle.get_child().set_label(_("Start Game")) def is_contest_mode (self): return self._contest_mode# and self.game.filename def do_select_language (self, combo, *args): self.selected_lang_details = combo.translations[combo.get_active()] self.refresh_labels() def refresh_labels (self, first_time=False): self._parent.set_title(_("Slider Puzzle Activity")) for lbl in self.labels_to_translate: if isinstance(lbl[0], gtk.Button): lbl[0].get_child().set_label(_(lbl[1])) else: lbl[0].set_label(_(lbl[1])) if not self.game_wrapper.get_parent() and not first_time: self.game_box.pop() if isinstance(self.game_box.get_child(), NotebookReaderWidget): m = self.do_lesson_plan else: m = self.do_select_category m(self) @utils.trace def set_nr_pieces (self, btn, nr_pieces=None): #if isinstance(btn, gtk.ToggleButton) and not btn.get_active(): # return if self.is_contest_mode() and isinstance(btn, gtk.ToggleButton) and nr_pieces == self.game.get_nr_pieces(): return if isinstance(btn, gtk.ToggleButton): if not btn.get_active(): if nr_pieces == self.game.get_nr_pieces(): print "A" btn.set_active(True) return if nr_pieces is None: nr_pieces = self.game.get_nr_pieces() if btn is None: #not isinstance(btn, gtk.ToggleButton): if self._contest_mode: self.set_game_state(GAME_STARTED) for n, b in ((9, self.btn_9),(12, self.btn_12),(16, self.btn_16)): if n == nr_pieces and not b.get_active(): print "B" b.set_sensitive(True) b.set_active(True) return if self.thumb.has_image(): if not self.game_wrapper.get_parent(): self.game_box.pop() self.game.load_image(self.thumb.get_image()) #self.thumb.set_game_widget(self.game) self.game.set_nr_pieces(nr_pieces) self.timer.reset(False) if isinstance(btn, gtk.ToggleButton): for n, b in ((9, self.btn_9),(12, self.btn_12),(16, self.btn_16)): if b is not btn: print "C" b.set_active(False) b.set_sensitive(not self._contest_mode) def do_shuffle (self, *args, **kwargs): if self._contest_mode: if self.get_game_state() > GAME_IDLE: # Restart self.set_game_state(GAME_STARTED, True) self._parent.frozen.thaw() self.timer.reset(True) elif self.game.filename is not None and self.timer.is_reset(): # Start self.timer.start() elif self.thumb.has_image(): if not self.game_wrapper.get_parent(): self.game_box.pop() self.game.load_image(self.thumb.get_image()) #self.thumb.set_game_widget(self.game) self.game.randomize() self.timer.reset(False) def slider_move_cb (self, *args): if not self.timer.is_running(): self.timer.start() def do_solve (self, btn): if self.game.filename is not None: if not self.game_wrapper.get_parent(): self.game_box.pop() self.game.show_image() self.timer.stop(True) if self._contest_mode and self.get_game_state() == GAME_STARTED: if btn != self.btn_solve: self.set_game_state(GAME_FINISHED) self.set_message(_("Puzzle Solved!")) else: self.set_game_state(GAME_QUIT) self.set_message(_("Gave Up")) self._set_control_area() # @utils.trace # def do_select_category(self, owner, *args, **kwargs): # if isinstance(owner, CategorySelector): # self.thumb.set_image_dir(args[0]) # #self.game_box.pop() # if not self.thumb.category.has_images(): # self.do_add_image(None) # else: # if self.game_wrapper.get_parent(): # s = CategorySelector("images", _("Choose a Subject"), self.thumb.get_image_dir()) # s.connect("selected", self.do_select_category) # s.show() # self.game_box.push(s) # s.grab_focus() # else: # self.game_box.pop() def do_select_category (self, o, *args): if isinstance(o, CategorySelector): self.thumb.set_image_dir(args[0]) #if not self.thumb.category.has_images(): # self.do_add_image(None) else: if self.game_wrapper.get_parent(): print ("Current cat dir=", self.thumb.get_image_dir()) s = CategorySelector(_("Choose a Subject"), self.thumb.get_image_dir(), path="images") #extra=('images/Sequencing Puzzles',)) s.connect("selected", self.do_select_category) s.show() self.game_box.push(s) s.grab_focus() else: self.game_box.pop() @utils.trace def do_add_image (self, widget, *args): """ Use to trigger and process the My Own Image selector. Also used for showing the buddies panel on contest mode""" if self._contest_mode and self.get_game_state() >= GAME_STARTED: # Buddy Panel if not self.buddy_panel.get_parent(): self.timer.stop() self.game_box.push(self.buddy_panel) else: self.game_box.pop() elif self._contest_mode and not self.is_initiator(): # do nothing pass else: self.thumb.add_image() self.do_shuffle() #if response is None: # else: # # My Own Image selector # imgfilter = gtk.FileFilter() # imgfilter.set_name(_("Image Files")) # imgfilter.add_mime_type('image/*') # fd = gtk.FileChooserDialog(title=_("Select Image File"), parent=self._parent, # action=gtk.FILE_CHOOSER_ACTION_OPEN, # buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT,gtk.STOCK_OK, gtk.RESPONSE_ACCEPT)) # # fd.set_current_folder(os.path.expanduser("~/")) # fd.set_modal(True) # fd.add_filter(imgfilter) # fd.connect("response", self.do_add_image) # fd.resize(800,600) # fd.show() #else: # if response == gtk.RESPONSE_ACCEPT: # if self.thumb.load_image(widget.get_filename()): # self.do_shuffle() # else: # err = gtk.MessageDialog(self._parent, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, # _("Not a valid image file")) # err.run() # err.destroy() # return # widget.destroy() def do_lesson_plan (self, btn): if self._on_lesson_plan: return try: self._on_lesson_plan = True if self._contest_mode and self.get_game_state() < GAME_STARTED: return if isinstance(self.game_box.get_child(), NotebookReaderWidget): if self.game_box.get_child().loaded: self.game_box.pop() else: s = NotebookReaderWidget('lessons', self.selected_lang_details) s.connect('parent-set', self.do_lesson_plan_reparent) s.show_all() self.game_box.push(s) self.timer.stop() finally: self._on_lesson_plan = False def do_lesson_plan_reparent (self, widget, oldparent): if widget.parent is None: self.set_button_translation(self.btn_lesson, "Lesson Plans") self.btn_lesson.get_child().set_label(_("Lesson Plans")) else: self.set_button_translation(self.btn_lesson, "Close Lesson") self.btn_lesson.get_child().set_label(_("Close Lesson")) def process_key (self, w, e): """ The callback for key processing. The button shortcuts are all defined here. """ k = gtk.gdk.keyval_name(e.keyval) if not isinstance(self._parent.get_focus(), gtk.Editable): if k == '1': self.btn_9.clicked() return True if k == '2': self.btn_12.clicked() return True if k == '3': self.btn_16.clicked() return True if k == 'period': self.thumb.next() return True if k == 'comma': self.thumb.previous() return True if k == 'Return': self.set_nr_pieces(None) return True if k == 'slash': self.do_select_category(None) return True if k == 'question': self.btn_add.clicked() return True if k == 'equal': self.btn_solve.clicked() return True if k in ('Escape', 'q'): gtk.main_quit() return True return False @utils.trace def _freeze (self, journal=True): """ returns a json writable object representation capable of being used to restore our current status """ return (self.thumb._freeze(), self.game._freeze(journal=journal), self.game.get_nr_pieces(), self.timer._freeze()) def _thaw (self, obj): """ retrieves a frozen status from a python object, as per _freeze """ #self.thumb._thaw(obj[0]) if not obj[1].has_key('image'): self.game.load_image(self.thumb.get_image()) self.set_nr_pieces(None, obj[2]) print obj[1].keys() wimg = obj[1].has_key('image') self.game._thaw(obj[1]) if wimg: print "Forcing thumb image from the one in game" self.thumb.load_pb(self.game.image) self.timer._thaw(obj[3]) self.game_box.pop() @utils.trace def _send_status_update (self): """ Send a status update signal """ if self._parent._shared_activity: if self.get_game_state() == GAME_STARTED: if self.thumb.has_image(): self.set_message(_("Game Started!")) self._parent.game_tube.StatusUpdate(self._state[1], self.timer.is_running(), self.timer.ellapsed()) def main(): win = gtk.Window(gtk.WINDOW_TOPLEVEL) t = SliderPuzzleUI(win) gtk.main() return 0 if __name__ == "__main__": main() sugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/setup.py0000644000175000017500000000014310716617376024325 0ustar janijani#!/usr/bin/env python from sugar.activity import bundlebuilder bundlebuilder.start("SliderPuzzle") sugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/SliderPuzzleActivity.py0000644000175000017500000003403310743343012027322 0ustar janijani# Copyright 2007 World Wide Workshop Foundation # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # # If you find this activity useful or end up using parts of it in one of your # own creations we would love to hear from you at info@WorldWideWorkshop.org ! # from sugar.activity.activity import Activity, ActivityToolbox, get_bundle_path from gettext import gettext as _ from SliderPuzzleUI import SliderPuzzleUI from mamamedia_modules import TubeHelper import logging, os, sys import md5 logger = logging.getLogger('sliderpuzzle-activity') from mamamedia_modules import json, utils # game tube import zlib import time from cStringIO import StringIO from dbus import Interface, DBusException from dbus.service import method, signal from dbus.gobject_service import ExportedGObject from mamamedia_modules import GAME_IDLE, GAME_STARTED, GAME_FINISHED, GAME_QUIT SERVICE = "org.worldwideworkshop.olpc.SliderPuzzle.Tube" IFACE = SERVICE PATH = "/org/worldwideworkshop/olpc/SliderPuzzle/Tube" class GameTube (ExportedGObject): """ Manage the communication between cooperating activities """ def __init__(self, tube, is_initiator, activity): super(GameTube, self).__init__(tube, PATH) self.tube = tube self.activity = activity self.add_status_update_handler() self.get_buddy = activity._get_buddy self.syncd_once = False if is_initiator: self.add_hello_handler() self.add_need_image_handler() self.activity.ui.connect('game-state-changed', self.game_state_cb) else: self.add_re_sync_handler() self.Hello() self.tube.watch_participants(self.participant_change_cb) def participant_change_cb(self, added, removed): logger.debug('Adding participants: %r', added) logger.debug('Removing participants: %r', removed) @signal(dbus_interface=IFACE, signature='') def Hello(self): """Request that this player's Welcome method is called to bring it up to date with the game state. """ @signal(dbus_interface=IFACE, signature='') def NeedImage(self): """Player needs actual binary image. """ @signal(dbus_interface=IFACE, signature='s') def ReSync (self, state): """ signal a reshufle, possibly with a new image """ @signal(dbus_interface=IFACE, signature='sbu') def StatusUpdate (self, status, clock_running, ellapsed_time): """ signal a reshufle, possibly with a new image """ logger.debug("Status Update to %s, %s, %i" % (status, str(clock_running), ellapsed_time)) def add_hello_handler(self): self.tube.add_signal_receiver(self.hello_cb, 'Hello', IFACE, path=PATH, sender_keyword='sender') def add_need_image_handler(self): self.tube.add_signal_receiver(self.need_image_cb, 'NeedImage', IFACE, path=PATH, sender_keyword='sender') def add_re_sync_handler (self): self.tube.add_signal_receiver(self.re_sync_cb, 'ReSync', IFACE, path=PATH, sender_keyword='sender') def add_status_update_handler(self): self.tube.add_signal_receiver(self.status_update_cb, 'StatusUpdate', IFACE, path=PATH, sender_keyword='sender') def game_state_cb (self, obj, state): if state == GAME_STARTED[0]: self.ReSync(self.activity.frozen.freeze()) def hello_cb(self, obj=None, sender=None): """Tell the newcomer what's going on.""" logger.debug('Newcomer %s has joined', sender) game = self.activity.ui.game f = self.activity.frozen if sender != self.activity.get_bus_name(): self.tube.get_object(sender, PATH).Welcome(f.freeze(), dbus_interface=IFACE) else: self.ReSync(f.freeze()) self.activity.ui._set_control_area() def need_image_cb (self, sender=None): """Send current image to peer as binary data.""" if self.activity.ui.get_game_state()[1] <= GAME_IDLE[1]: return logger.debug('Sending image to %s', sender) img = self.activity.ui.game.get_image_as_png() #img = file(imgfile, 'rb').read() #img = self.activity.ui.game.image.get_pixbuf() t = time.time() compressed = zlib.compress(img, 9) # We will be sending the image, 24K at a time (my tests put the high water at 48K) logger.debug("was %d, is %d. compressed to %d%% in %0.4f seconds" % (len(img), len(compressed), len(compressed)*100/len(img), time.time() - t)) part_size = 24*1024 parts = len(compressed) / part_size self.tube.get_object(sender, PATH).ImageSync([], 0, dbus_interface=IFACE) for i in range(parts+1): self.tube.get_object(sender, PATH).ImageSync(compressed[i*part_size:(i+1)*part_size], i+1, dbus_interface=IFACE) self.tube.get_object(sender, PATH).ImageDetailsSync(self.activity.frozen.freeze(), dbus_interface=IFACE) def re_sync_cb (self, state, sender=None): # new grid and possibly image too if self.syncd_once: return logger.debug("resync state: '%s' (%s)" % (state, type(state))) self.syncd_once = self.activity.frozen.thaw(str(state), tube=self) def status_update_cb (self, status, clock_running, ellapsed_time, sender=None): to = self.tube.get_object(sender, PATH) logger.debug("Status Update from %s: %s, %s, %i" % (sender, status, str(clock_running), ellapsed_time)) buddy = self.get_buddy(self.tube.bus_name_to_handle[sender]) nick, stat = self.activity.ui.buddy_panel.update_player(buddy, status, bool(clock_running), int(ellapsed_time)) if buddy != self.activity.owner: self.activity.ui.set_message(_("Buddy '%s' changed status: %s") % (nick, stat), frommesh=True) @method(dbus_interface=IFACE, in_signature='s', out_signature='') def Welcome(self, state): """ """ logger.debug("Welcome..."); logger.debug("state: '%s' (%s)" % (state, type(state))) self.activity.frozen.thaw(str(state), tube=self) @method(dbus_interface=IFACE, in_signature='ayn', out_signature='', byte_arrays=True) def ImageSync (self, image_part, part_nr): """ """ logger.debug("Received image part #%d, length %d" % (part_nr, len(image_part))) self.activity.ui.set_message(_("Waiting for Puzzle image to be transferred...")) if part_nr == 1: self.image = StringIO() self.image.write(image_part) elif part_nr > 1: self.image.write(image_part) @method(dbus_interface=IFACE, in_signature='s', out_signature='', byte_arrays=True) def ImageDetailsSync (self, state): """ Signals end of image and shares the rest of the needed data to create the image remotely.""" logger.debug("Receive end of image sync") self.syncd_once = self.activity.frozen.thaw(str(state), forced_image=zlib.decompress(self.image.getvalue()), tube=self) class FrozenState (object): """ Keep everything about a game state here so we can easily store our state in the Journal or send it to mesh peers """ def __init__ (self, slider_ui): self.slider_ui = slider_ui self._lock = False self.sync() def sync (self, *args): """ reads the current state for the slider_ui and keeps it """ if self._lock: return logger.debug("sync'ing game state") self.frozen = json.write(self.slider_ui._freeze(journal=False)) #self.nr_pieces = self.slider_ui.game.get_nr_pieces() #self.category_path = self.slider_ui.thumb.get_image_dir() ##self.image_path = self.slider_ui.game.filename ##if self.slider_ui.thumb.is_myownpath(): ## self.image_path = os.path.basename(self.image_path) #self.thumb_state = self.slider_ui.thumb._freeze() ##self.image_digest = self.slider_ui.game.image_digest #self.game_state = self.slider_ui.game._freeze(journal=False) ##logger.debug("sync game_state: %s" % str(self.game_state)) ##logger.debug("sync category: %s image: %s (md5: %s)" % (self.category_path, self.image_path, self.image_digest)) def apply (self): """ Apply the saved state to the running game """ self.slider_ui._thaw(json.read(self.frozen)) #self.slider_ui.thumb._thaw(self.thumb_state) #self.slider_ui.set_nr_pieces(None, self.nr_pieces) #self.slider_ui.game._thaw(self.game_state) def freeze (self): """return a json version of the kept data""" return self.frozen #return json.write({ # 'nr_pieces': self.nr_pieces, # #'image_path': self.image_path, # 'thumb_state': self.thumb_state, # #'image_digest': self.image_digest, # 'game_state': self.game_state, # }) def thaw (self, state=None, tube=None, forced_image=None): """ store the previously saved state """ try: self._lock = True #found = False if state is not None: self.frozen = state #state = self.freeze() #for k,v in json.read(state).items(): # if hasattr(self, k): # #logger.debug("%s=%s" % (k,str(v))) # setattr(self, k, v) # self.slider_ui.thumb._thaw(self.thumb_state) # self.slider_ui.set_nr_pieces(None, self.nr_pieces) # self.slider_ui.game._thaw(self.game_state) #logger.debug("thaw game_state: %s" % str(self.game_state)) if forced_image is not None: self.slider_ui.game.set_image_from_str(forced_image) self.slider_ui.thumb.load_pb(self.slider_ui.game.image) self.apply() elif tube is not None: tube.NeedImage() else: self.apply() #if self.image_path: # if self.image_path == os.path.basename(self.image_path): # # MyOwnPath based image... # #if forced_image is not None: # # name = 'image_' + self.image_path # # while os.path.exists(os.path.join(self.slider_ui.thumb.myownpath, name)): # # name = '_' + name # # f = file(os.path.join(self.slider_ui.thumb.myownpath, name), 'wb') # # f.write(forced_image) # # f.close() # # self.slider_ui.thumb.set_image_dir(os.path.join(self.slider_ui.thumb.myownpath, name)) # # self.slider_ui.set_nr_pieces(None, self.nr_pieces) # # self.slider_ui.game._thaw(self.game_state) # # #logger.debug("thaw game_state: %s" % str(self.game_state)) # # found = True # #else: # # for link, name, digest in self.slider_ui.thumb.gather_myownpath_images(): # # if digest == self.image_digest: # # logger.debug("Found the image in myownpath!") # # self.slider_ui.thumb.set_image_dir(os.path.join(self.slider_ui.thumb.myownpath, link)) # # self.slider_ui.set_nr_pieces(None, self.nr_pieces) # # self.slider_ui.game._thaw(self.game_state) # # logger.debug("thaw game_state: %s" % str(self.game_state)) # # found = True # # break # # if not found: # logger.debug("Don't know the image, so request it") # if tube is not None: # tube.NeedImage() # elif os.path.exists(self.image_path) and md5.new(file(self.image_path, 'rb').read()).hexdigest() == self.image_digest: # logger.debug("We have the image!") # self.slider_ui.thumb.set_image_dir(self.image_path) # #self.slider_ui.game.load_image(self.image_path) # self.slider_ui.set_nr_pieces(None, self.nr_pieces) # self.slider_ui.game._thaw(self.game_state) # logger.debug("thaw game_state: %s" % str(self.game_state)) # else: # logger.debug("Don't know the image, so request it") # if tube is not None: # tube.NeedImage() #else: # logger.debug("No image...") return True finally: self._lock = False class SliderPuzzleActivity(Activity, TubeHelper): def __init__(self, handle): Activity.__init__(self, handle) logger.debug('Starting Slider Puzzle activity... %s' % str(get_bundle_path())) os.chdir(get_bundle_path()) self.connect('destroy', self._destroy_cb) toolbox = ActivityToolbox(self) self.set_toolbox(toolbox) toolbox.show() title_widget = toolbox._activity_toolbar.title title_widget.set_size_request(title_widget.get_layout().get_pixel_size()[0] + 20, -1) self.ui = SliderPuzzleUI(self) self.set_canvas(self.ui) self.show_all() self.frozen = FrozenState(self.ui) self.ui.game.connect('shuffled', self.frozen.sync) TubeHelper.__init__(self, tube_class=GameTube, service=SERVICE) def _destroy_cb(self, data=None): return True # TubeHelper mixin stuff @utils.trace def shared_cb (self): self.ui.buddy_panel.add_player(self.owner) def joined_cb (self): self.ui.set_readonly() @utils.trace def new_tube_cb (self): self.ui.set_contest_mode(True) def buddy_joined_cb (self, buddy): nick = self.ui.buddy_panel.add_player(buddy) self.ui.set_message(_("Buddy '%s' joined the game!") % (nick), frommesh=True) def buddy_left_cb (self, buddy): nick = self.ui.buddy_panel.remove_player(buddy) self.ui.set_message(_("Buddy '%s' left the game!") % (nick), frommesh=True) # Journal integration def read_file(self, file_path): f = open(file_path, 'r') try: session_data = f.read() finally: f.close() #logging.debug('Trying to set session: %s.' % session_data) print "Setting session" self.ui._thaw(json.read(session_data)) print "Done setting session" def write_file(self, file_path): session_data = json.write(self.ui._freeze()) f = open(file_path, 'w') try: f.write(session_data) finally: f.close() sugar-sliderpuzzle-activity-5.orig/SliderPuzzle.activity/MANIFEST0000644000175000017500000000407110716617376023750 0ustar janijaniSliderPuzzleActivity.py SliderPuzzleUI.py SliderPuzzleWidget.py setup.py mamamedia_modules.py i18n_misc_strings.py icons/logo.png images/default_thumb.svg images/Animals/image_chmk_h250_w250_lg.gif images/Animals/image_djstf_h250_w411_lg.gif images/Animals/image_drti_h250_w322_lg.gif images/Animals/image_howl_h250_w250_lg.gif images/Animals/image_hsnr_h250_w421_lg.gif images/Animals/image_justi_h250_w333_lg.gif images/Animals/image_kili_h250_w387_lg.gif images/Animals/image_mdic_h250_w250_lg.gif images/Animals/image_mrfg_h250_w333_lg.gif images/Animals/image_nimo_h250_w299_lg.gif images/Animals/image_skat_h250_w363_lg.gif images/Animals/thumb.gif images/Music/image_devin_music_w333_lg.gif images/Music/image_tbtn_h250_w365_lg.gif images/Music/image_weird_h250_w384_lg.gif images/Music/image_wpwa_h250_w250_lg.gif images/Music/thumb.gif images/Sequencing Puzzles/image_Letters.sequence images/Sequencing Puzzles/image_Numbers.sequence images/Sequencing Puzzles/thumb.svg images/Space/image_aisc_h250_w313_lg.gif images/Space/image_esim_h250_w250_lg.gif images/Space/image_tral_h250_w404_lg.gif images/Space/thumb.gif po/SliderPuzzle.pot po/pt.po po/es.po po/ko.po lessons/0Overview/default.abw lessons/0Overview/_es.abw lessons/0Overview/_pt.abw lessons/Lesson 1/default.abw lessons/Lesson 1/_es.abw lessons/Lesson 1/_pt.abw lessons/Lesson 2/default.abw lessons/Lesson 2/_es.abw lessons/Lesson 2/_pt.abw lessons/Lesson 3/default.abw lessons/Lesson 3/_es.abw lessons/Lesson 4/default.abw lessons/Lesson 4/_es.abw lessons/Lesson 4/_pt.abw lessons/Lesson 5/default.abw lessons/Lesson 5/_es.abw lessons/Lesson 6/default.abw lessons/Lesson 6/_es.abw lessons/Lesson 6/_pt.abw lessons/Lesson 7/default.abw lessons/Lesson 7/_es.abw mmm_modules/borderframe.py mmm_modules/buddy_panel.py mmm_modules/i18n.py mmm_modules/image_category.py mmm_modules/__init__.py mmm_modules/json.py mmm_modules/notebook_reader.py mmm_modules/timer.py mmm_modules/tube_helper.py mmm_modules/utils.py mamamedia_icons/arrow_left.png mamamedia_icons/arrow_right.png mamamedia_icons/circle-check.svg mamamedia_icons/circle-x.svg