 {"id":660552,"date":"2024-04-30T15:43:42","date_gmt":"2024-04-30T22:43:42","guid":{"rendered":"https:\/\/www.sfmoma.org\/?page_id=660552"},"modified":"2024-05-10T10:40:04","modified_gmt":"2024-05-10T17:40:04","slug":"art-of-noise-sound-memory-matching-game","status":"publish","type":"page","link":"https:\/\/www.sfmoma.org\/art-of-noise-sound-memory-matching-game\/","title":{"rendered":"Art of Noise Sound Memory Matching Game"},"content":{"rendered":"Are you ready to listen closely and match swiftly? Below is an auditory memory game featuring sound objects from the <a href=\"https:\/\/www.sfmoma.org\/exhibition\/art-of-noise\/\"><em>Art of Noise<\/em><\/a> exhibition. This is a race against the clock to match all the pairs! There are three modes in the game:\r\n\r\n<ol style=\"margin-top:10px;\">\r\n<li><strong>Audio Mode:<\/strong> Rely solely on sound to find the pairs. Matching a sound reveals the corresponding object. But be careful&mdash;you only get ten incorrect matches before it&#8217;s game over!<\/li>\r\n<li><strong>Audio + Visual Mode:<\/strong> As each sound plays, its object image is also revealed. While this mode provides more clues, you have less time and fewer attempts to match the pairs.<\/li>\r\n<li><strong>Exploration Mode:<\/strong> Freely explore each object and listen to its sounds at your leisure.<\/li>\r\n<\/ol>\r\nCan you match all the pairs before time runs out? Let the art of noise guide you to victory!\r\n\r\n<hr \/>\r\n<head>\r\n<title>Art of Noise Sound Memory Game<\/title>\r\n<style>\r\n.game-board {\r\n  display: grid;\r\n  grid-template-columns: repeat(4, 100px);\r\n  grid-gap: 10px;\r\n  margin-top: 20px;\r\n  justify-content: center;\r\n}\r\n.card {\r\n  width: 100px;\r\n  height: 100px;\r\n  background-color: #005eb8;\r\n  display: flex;\r\n  justify-content: center;\r\n  align-items: center;\r\n  color: white;\r\n  font-size: 20px;\r\n  cursor: pointer;\r\n  border: 3px solid #004c96;\r\n  border-radius: 10px;\r\n  box-shadow: 3px 3px #003b75;\r\n  transition: all 0.1s ease;\r\n}\r\n@media (max-width:600px) {\r\n.game-board {\r\n  display: grid;\r\n  grid-template-columns: repeat(4, 75px);\r\n  grid-gap: 9px;\r\n  margin-top: 20px;\r\n  justify-content: center;\r\n}\r\n.card {\r\n  width: 75px;\r\n  height: 75px;\r\n  background-color: #005eb8;\r\n  display: flex;\r\n  justify-content: center;\r\n  align-items: center;\r\n  color: white;\r\n  font-size: 20px;\r\n  cursor: pointer;\r\n  border: 3px solid #004c96;\r\n  border-radius: 10px;\r\n  box-shadow: 3px 3px #003b75;\r\n  transition: all 0.1s ease;\r\n}\r\n.modal-content {\r\nwidth: 80%;\r\nmargin: 20% auto;\r\npadding: 10px;\r\n}\r\n}\r\n.card:active {\r\nbox-shadow: 1px 1px #003b75;\r\ntransform: translate(2px, 2px);\r\n}\r\n.card.active {\r\nborder-color: #F46B57;\r\n}\r\n.card.incorrect {\r\nanimation: flash 0.5s ease-out;\r\n}\r\n@keyframes flash {\r\n0%, 100% {background-color: transparent;}\r\n50% { background-color:red;}\r\n}\r\n.waveform {\r\ndisplay: none;\r\njustify-content: space-around;\r\nalign-items: center;\r\nheight: 20px;\r\nwidth: 100%;\r\noverflow: hidden;\r\n}\r\n.bar {\r\nwidth: 4px;\r\nheight: 5px;\r\nbackground-color: #ffffff;\r\nanimation: wave 1.5s ease-in-out infinite;\r\n}\r\n@keyframes wave {\r\n0%, 100% { height: 5px;}\r\n25% {height: 10px;}\r\n50% {height: 20px;}\r\n75% {height: 10px;}\r\n}\r\n.bar:nth-child(2n) {\r\nanimation-delay: -1.2s;\r\n}\r\n.bar:nth-child(3n) {\r\nanimation-delay: -0.9s;\r\n}\r\n.modal {\r\ndisplay: none;\r\nposition: fixed;\r\nz-index:1;\r\nleft:0;\r\ntop:0;\r\nwidth: 100%;\r\nheight:100%;\r\noverflow:auto;\r\nbackground-color: rgb(0,0,0);\r\nbackground-color: rgba(0,0,0,0.4);\r\n}\r\n.modal-content {\r\nbackground-color: #fefefe;\r\nmargin: 15% auto;\r\npadding: 20px;\r\nborder: 1px solid #888;\r\ntext-align:center;\r\nwidth: 50%;\r\npadding-top:10px;\r\n}\r\n#modalText {\r\nmargin-top: 30px;\r\n}\r\n.close {\r\ncolor: #aaa;\r\nfloat: right;\r\nfont-size: 28px;\r\nfont-weight: bold;\r\n}\r\n.close:hover,\r\n.close:focus {\r\ncolor: black;\r\ntext-decoration: none;\r\ncursor: pointer;\r\n}\r\n.card.matched {\r\n  pointer-events: none;\r\n  background-size: cover;\r\n  background-position: center;\r\n}\r\n#timerDisplay, #moveCounterDisplay #incorrectMatchesDisplay {\r\nfont-size: 20px;\r\nmargin-bottom: 10px;\r\nfont-family: SFMOMADisplayRegular, Arial, Verdana, sans-serif;\r\n}\r\n<\/style>\r\n<\/head>\r\n<body>\r\n<div style=\"margin-bottom: 20px;\">\r\n<label for=\"modeSelect\">Change Game Mode:<\/label>\r\n<select id=\"modeSelect\">\r\n<option value=\"hard\" selected>Audio<\/option>\r\n<option value=\"easy\">Audio + Visual<\/option>\r\n<option value=\"exploration\">Exploration<\/option>\r\n<\/select>\r\n<button id=\"changeModeButton\">Change Mode<\/button>\r\n<\/div>\r\n<div id=\"gameModal\" class=\"modal\">\r\n<div class=\"modal-content\">\r\n<span class=\"close\">&times;<\/span>\r\n<p id=\"modalText\">Choose a mode to play again:<\/p>\r\n<button id=\"buttonHard\">Audio Mode<\/button>\r\n<button id=\"buttonEasy\">Audio + Visual Mode<\/button>\r\n<button id=\"buttonExploration\">Exploration Mode<\/button>\r\n<\/div><\/div>\r\n<div id=\"timerDisplay\"><\/div>\r\n<div id=\"moveCounterDisplay\"><\/div>\r\n<div id=\"incorrectMatchesDisplay\"><\/div>\r\n<div id=\"gameBoard\" class=\"game-board\"><\/div>\r\n<script>\r\ndocument.addEventListener('DOMContentLoaded', () => {\r\nconst modal =\r\ndocument.getElementById('gameModal');\r\nconst gameBoard =\r\ndocument.getElementById('gameBoard');\r\nconst timerDisplay =\r\ndocument.getElementById('timerDisplay');\r\nconst moveCounterDisplay =\r\ndocument.getElementById('moveCounterDisplay');\r\nconst incorrectMatchesDisplay =\r\ndocument.getElementById('incorrectMatchesDisplay');\r\nconst modalText =\r\ndocument.getElementById('modalText');\r\nconst closeBtn =\r\ndocument.getElementsByClassName(\"close\")[0];\r\nconst modeSelect =\r\ndocument.getElementById(\"modeSelect\");\r\nconst changeModeButton =\r\ndocument.getElementById(\"changeModeButton\");\r\ndocument.querySelector(\"#buttonHard\").addEventListener('click',function() {\r\nrestartGame('hard');\r\n});\r\ndocument.querySelector(\"#buttonEasy\").addEventListener('click',function() {\r\nrestartGame('easy');\r\n});\r\ndocument.querySelector(\"#buttonExploration\").addEventListener('click',function() {\r\nrestartGame('exploration');\r\n});\r\nchangeModeButton.addEventListener('click', () => {\r\ncurrentMode = modeSelect.value;\r\nconsole.log(\"Mode changed to: \" + currentMode);\r\nrestartGame(currentMode);\r\n});\r\ncloseBtn.onclick = function() {\r\nmodal.style.display = \"none\";\r\nexplorationMode = true;\r\nmodeSelect.value = 'exploration';\r\ncurrentMode = 'exploration';\r\nconsole.log(\"Exploration mode activated\");\r\n};\r\nfunction showModal(message) {\r\nmodalText.textContent = message;\r\nmodal.style.display = \"block\";\r\n}\r\nlet currentMode = \"hard\";\r\nlet cardClicked = -1;\r\nlet matchesFound = 0;\r\nlet gameTime = 120;\r\nlet wrongMatches = 0;\r\nlet incorrectMatches = 0;\r\nlet moves = 0;\r\nlet currentAudio = null;\r\nlet gameEnded = false;\r\nlet timer;\r\nlet isFirstCardClicked = false;\r\nlet explorationMode = false;\r\nlet previousCard = null;\r\ntimerDisplay.textContent = `Time left: ${gameTime} seconds`;\r\nmoveCounterDisplay.textContent = `Moves: ${moves}`;\r\nincorrectMatchesDisplay.textContent = `Incorrect Matches: ${incorrectMatches}`;\r\nconst cards = [\r\n{sound: 'https:\/\/d1hhug17qm51in.cloudfront.net\/www-media\/2024\/04\/29165358\/AoNGameSound1.mp3', image: 'https:\/\/d1hhug17qm51in.cloudfront.net\/www-media\/2024\/04\/29165356\/AoNGameSound1.jpg'},\r\n{sound: 'https:\/\/d1hhug17qm51in.cloudfront.net\/www-media\/2024\/04\/29165401\/AoNGameSound2.mp3', image: 'https:\/\/d1hhug17qm51in.cloudfront.net\/www-media\/2024\/04\/29165359\/AoNGameSound2.jpg'},\r\n{sound: 'https:\/\/d1hhug17qm51in.cloudfront.net\/www-media\/2024\/04\/29165405\/AonGameSound3.mp3', image: 'https:\/\/d1hhug17qm51in.cloudfront.net\/www-media\/2024\/04\/29165403\/AoNGameSound3.jpg'},\r\n{sound: 'https:\/\/d1hhug17qm51in.cloudfront.net\/www-media\/2024\/04\/29165409\/AoNGameSound4.mp3', image: 'https:\/\/d1hhug17qm51in.cloudfront.net\/www-media\/2024\/04\/29165407\/AoNGameSound4.jpg'},\r\n{sound: 'https:\/\/d1hhug17qm51in.cloudfront.net\/www-media\/2024\/04\/29165413\/AoNGameSound5.mp3', image: 'https:\/\/d1hhug17qm51in.cloudfront.net\/www-media\/2024\/04\/29165411\/AoNGameSound5.jpg'},\r\n{sound: 'https:\/\/d1hhug17qm51in.cloudfront.net\/www-media\/2024\/04\/29165416\/AoNGameSound6.mp3', image: 'https:\/\/d1hhug17qm51in.cloudfront.net\/www-media\/2024\/04\/29165415\/AoNGameSound6.jpg'},\r\n{sound: 'https:\/\/d1hhug17qm51in.cloudfront.net\/www-media\/2024\/04\/29165420\/AoNGameSound7.mp3', image: 'https:\/\/d1hhug17qm51in.cloudfront.net\/www-media\/2024\/04\/29165418\/AoNGameSound7.jpg'},\r\n{sound: 'https:\/\/d1hhug17qm51in.cloudfront.net\/www-media\/2024\/04\/29165424\/AonGameSound8.mp3', image: 'https:\/\/d1hhug17qm51in.cloudfront.net\/www-media\/2024\/04\/29165422\/AoNGameSound8.jpg'},\r\n];\r\nlet cardItems = [...cards, ...cards].sort(() => Math.random() - 0.5);\r\ncardItems.forEach((cardItem, index) => {\r\nconst card = document.createElement('div');\r\ncard.classList.add('card');\r\ncard.dataset.sound = cardItem.sound;\r\ncard.dataset.image = cardItem.image;\r\ncard.dataset.index = index;\r\nconst waveform =\r\ndocument.createElement('div');\r\nwaveform.classList.add('waveform');\r\nfor (let i = 0; i < 5; i++) {\r\nconst bar =\r\ndocument.createElement('div');\r\nbar.classList.add('bar');\r\nwaveform.appendChild(bar);\r\n}\r\ncard.appendChild(waveform);\r\ncard.addEventListener('click', () =>\r\nhandleCardClick(card));\r\ngameBoard.appendChild(card);\r\n});\r\nfunction startTimer() {\r\nif (currentMode === 'hard') {\r\ngameTime = 120;\r\n} else {\r\ngameTime = 90;\r\n}\r\ntimer = setInterval(() => {\r\nif (gameTime <= 0) {\r\nclearInterval(timer);\r\ngameEnded = true;\r\ndisableAllCards();\r\nstopCurrentAudio();\r\nshowModal('Time is up! Choose a mode to try again:');\r\n} else {\r\ngameTime--;\r\ntimerDisplay.textContent = `Time left: ${gameTime} seconds`;\r\n}\r\n},1000);\r\nconsole.log(\"Timer started with new interval.\");\r\n}\r\nfunction updateUIVisibility() {\r\nif (currentMode === 'exploration') {\r\ntimerDisplay.textContent = 'Time left: No timer in exploration mode';\r\nmoveCounterDisplay.textContent = 'Moves: N\/A';\r\nincorrectMatchesDisplay.textContent = 'Incorrect Matches: N\/A';\r\n} else {\r\ntimerDisplay.textContent = `Time left: ${gameTime} seconds`;\r\nmoveCounterDisplay.textContent = `Moves: ${moves}`;\r\nincorrectMatchesDisplay.textContent = `Incorrect Matches: ${incorrectMatches}`;\r\n}\r\n}\r\nfunction stopCurrentAudio() {\r\nif (currentAudio) {\r\ncurrentAudio.pause();\r\ncurrentAudio.currentTime = 0;\r\n}\r\ndocument.querySelectorAll('.waveform').forEach(wave => wave.style.display = 'none');\r\n}\r\nfunction resetGame() {\r\nconsole.log(\"Starting resetGame function\");\r\nclearInterval(timer);\r\nif (currentMode === 'hard') {\r\ngameTime = 120;\r\n} else {\r\ngameTime = 90;\r\n}\r\nstopCurrentAudio();\r\ncardClicked = -1;\r\nmatchesFound = 0;\r\nwrongMatches = 0;\r\nincorrectMatches = 0;\r\nmoves = 0;\r\ncurrentAudio = null;\r\ngameEnded = false;\r\nisFirstCardClicked = false;\r\ngameBoard.innerHTML = '';\r\ntimerDisplay.textContent = `Time left: ${gameTime} seconds`;\r\nmoveCounterDisplay.textContent = `Moves: ${moves}`;\r\nincorrectMatchesDisplay.textContent = `Incorrect Matches: ${incorrectMatches}`;\r\nupdateUIVisibility();\r\nconsole.log(\"resetGame function completed\");\r\n}\r\nfunction initializeGame() {\r\nconsole.log(\"Starting initializeGame function\");\r\ncardItems = [...cards, ...cards].sort(() => Math.random() - 0.5);\r\ncardItems.forEach((cardItem, index) => {\r\nconst card = document.createElement('div');\r\ncard.classList.add('card');\r\ncard.dataset.sound = cardItem.sound;\r\ncard.dataset.image = cardItem.image;\r\ncard.dataset.index = index;\r\nconst waveform =\r\ndocument.createElement('div');\r\nwaveform.classList.add('waveform');\r\nfor (let i = 0; i < 5; i++) {\r\nconst bar =\r\ndocument.createElement('div');\r\nbar.classList.add('bar');\r\nwaveform.appendChild(bar);\r\n}\r\ncard.appendChild(waveform);\r\ncard.addEventListener('click', () =>\r\nhandleCardClick(card));\r\ngameBoard.appendChild(card);\r\n});\r\nconsole.log(\"initializeGame function completed\");\r\n}\r\nfunction restartGame(mode) {\r\nconsole.log(\"restarting game in mode:\", mode);\r\ncurrentMode = mode;\r\nmodeSelect.value = mode;\r\nresetGame();\r\ninitializeGame();\r\nmodal.style.display = 'none';\r\nexplorationMode = false;\r\nconsole.log(\"Modal should be hidden now, game reset in mode: \" + mode);\r\n}\r\nfunction handleCardClick(card) {\r\nif (currentMode === \"exploration\" || explorationMode) {\r\nif (currentAudio) {\r\ncurrentAudio.pause();\r\ncurrentAudio.currentTime = 0;\r\ndocument.querySelectorAll('.waveform').forEach(wave => wave.style.display = 'none');\r\n}\r\ncurrentAudio = new\r\nAudio(card.dataset.sound);\r\nconst waveform =\r\ncard.querySelector('.waveform');\r\nwaveform.style.display = 'flex';\r\ncurrentAudio.play();\r\ncurrentAudio.onended = () => {\r\nwaveform.style.display = 'none';\r\n};\r\nif ( !card.classList.contains('matched')) {\r\ncard.style.backgroundImage =\r\n`url('${card.dataset.image}')`;\r\ncard.classList.add('revealed');\r\ncard.style.backgroundSize = 'cover';\r\ncard.style.backgroundPosition = 'center';\r\ncard.style.backgroundRepeat = 'no-repeat';\r\n}\r\n} else if (currentMode === \"easy\") {\r\nif (gameEnded) return;\r\nif (!isFirstCardClicked) {\r\nstartTimer();\r\nisFirstCardClicked = true;\r\n}\r\nif (currentAudio) {\r\ncurrentAudio.pause();\r\ncurrentAudio.currentTime = 0;\r\ndocument.querySelectorAll('.waveform').forEach(wave => wave.style.display = 'none');\r\nif (previousCard && previousCard !== card && !previousCard.classList.contains('matched')) {\r\npreviousCard.style.backgroundImage = 'none';\r\n}\r\n}\r\nconst sound = new\r\nAudio(card.dataset.sound);\r\nsound.play();\r\ncurrentAudio = sound;\r\ncard.querySelector('.waveform').style.display = 'flex';\r\ncard.style.backgroundImage = `url('${card.dataset.image}')`;\r\ncard.style.backgroundSize = 'cover';\r\ncard.style.backgroundPosition = 'center';\r\ncard.style.backgroundRepeat = 'no-repeat';\r\npreviousCard = card;\r\ncurrentAudio.onended = () => {\r\ncard.querySelector('.waveform').style.display = 'none';\r\nif (previousCard === card && !card.classList.contains('matched')) {\r\ncard.style.backgroundImage = 'none';\r\n}\r\n};\r\nif (cardClicked < 0) {\r\ncardClicked = card.dataset.index;\r\ncard.classList.add('active');\r\n} else {\r\nmoves++;\r\nmoveCounterDisplay.textContent = `Moves: ${moves}`;\r\nif ( ! ( card.dataset.sound !== cardItems[cardClicked].sound || card.dataset.index === cardClicked ) ) {\r\nconst matchedCards = [card, document.querySelector(`[data-index=\"${cardClicked}\"]`)];\r\nmatchedCards.forEach(matchedCard => {\r\nmatchedCard.classList.add('matched');\r\nmatchedCard.classList.remove('active');\r\nmatchedCard.style.backgroundImage = `url('${matchedCard.dataset.image}')`;\r\n});\r\nmatchesFound++;\r\nif (matchesFound === cards.length)\r\n{\r\ngameEnded = true;\r\nclearInterval(timer);\r\nstopCurrentAudio();\r\nsetTimeout(() => {\r\nshowModal('Congratulations! You found all matches. Choose a mode to play again:');\r\n}, 500);\r\n}\r\n} else {\r\nwrongMatches++;\r\nconst firstCard =\r\ndocument.querySelector(`[data-index=\"${cardClicked}\"]`);\r\nfirstCard.classList.add('incorrect');\r\ncard.classList.add('incorrect');\r\nsetTimeout(() => {\r\nfirstCard.classList.remove('incorrect','active');\r\ncard.classList.remove('incorrect','active');\r\n}, 500);\r\nincorrectMatches++;\r\nincorrectMatchesDisplay.textContent = `Incorrect Matches: ${incorrectMatches}`;\r\nif (wrongMatches === 8) {\r\ngameEnded = true;\r\nclearInterval(timer);\r\nstopCurrentAudio();\r\nshowModal('Game over! Too many wrong matches. Choose a mode to try again:');\r\n}\r\n}\r\ntimerDisplay.textContent = `Time left: ${gameTime} seconds`;\r\ncardClicked = -1;\r\n}\r\n} else {\r\nif (gameEnded) return;\r\nif (!isFirstCardClicked) {\r\nstartTimer();\r\nisFirstCardClicked = true;\r\n}\r\nif (currentAudio) {\r\ncurrentAudio.pause();\r\ncurrentAudio.currentTime = 0;\r\ndocument.querySelectorAll('.waveform').forEach(wave => wave.style.display = 'none');\r\n}\r\nconst sound = new\r\nAudio(card.dataset.sound);\r\nsound.play();\r\ncurrentAudio = sound;\r\ncard.querySelector ('.waveform').style.display = 'flex';\r\ncurrentAudio.onended = () => {\r\ncard.querySelector ('.waveform').style.display = 'none';\r\n}\r\nif (cardClicked < 0) {\r\ncardClicked = card.dataset.index;\r\ncard.classList.add('active');\r\n} else {\r\nmoves++;\r\nmoveCounterDisplay.textContent = `Moves: ${moves}`;\r\nif ( ! ( card.dataset.sound !== cardItems[cardClicked].sound || card.dataset.index === cardClicked ) ) {\r\nconst matchedCards = [card, document.querySelector(`[data-index=\"${cardClicked}\"]`)];\r\nmatchedCards.forEach(matchedCard => {\r\nmatchedCard.classList.add('matched');\r\nmatchedCard.classList.remove('active');\r\nmatchedCard.style.backgroundImage = `url('${matchedCard.dataset.image}')`;\r\n});\r\nmatchesFound++;\r\nif (matchesFound === cards.length)\r\n{\r\ngameEnded = true;\r\nclearInterval(timer);\r\nstopCurrentAudio();\r\nsetTimeout(() => {\r\nshowModal('Congratulations! You found all matches. Choose a mode to play again:');\r\n}, 500);\r\n}\r\n} else {\r\nwrongMatches++;\r\nconst firstCard = \r\ndocument.querySelector(`[data-index=\"${cardClicked}\"]`);\r\nfirstCard.classList.add('incorrect');\r\ncard.classList.add('incorrect');\r\nsetTimeout(() => {\r\nfirstCard.classList.remove('incorrect','active');\r\ncard.classList.remove('incorrect','active');\r\n},500);\r\nincorrectMatches++;\r\nincorrectMatchesDisplay.textContent = `Incorrect Matches: ${incorrectMatches}`;\r\nif (wrongMatches === 10) {\r\ngameEnded = true;\r\nclearInterval(timer);\r\nstopCurrentAudio();\r\nshowModal('Game over! Too many wrong matches. Choose a mode to try again:');\r\n}\r\n}\r\ntimerDisplay.textContent = `Time left: ${gameTime} seconds`;\r\ncardClicked = -1;\r\n}\r\n}\r\n}\r\nfunction disableAllCards() {\r\nconst cards =\r\ndocument.querySelectorAll('.card');\r\ncards.forEach(card => {\r\ncard.removeEventListener('click', handleCardClick);\r\n});\r\n}\r\n});\r\n<\/script>\r\n<\/body>","protected":false},"excerpt":{"rendered":"Are you ready to listen closely and match swiftly? Below is an auditory memory game featuring sound objects from the Art of Noise exhibition. This is a race against the clock to match all the pairs! There are three modes in the game: Audio Mode: Rely solely on sound to find the pairs. Matching a [&hellip;]","protected":false},"author":1485,"featured_media":680060,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_acf_changed":false,"_lmt_disableupdate":"no","_lmt_disable":"","ep_exclude_from_search":false,"footnotes":"","_wp_rev_ctl_limit":""},"coauthors":[1743],"class_list":["post-660552","page","type-page","status-publish","has-post-thumbnail","hentry","theme-play-interact","no-wpautop"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.sfmoma.org\/wp-json\/wp\/v2\/pages\/660552","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.sfmoma.org\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.sfmoma.org\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.sfmoma.org\/wp-json\/wp\/v2\/users\/1485"}],"replies":[{"embeddable":true,"href":"https:\/\/www.sfmoma.org\/wp-json\/wp\/v2\/comments?post=660552"}],"version-history":[{"count":0,"href":"https:\/\/www.sfmoma.org\/wp-json\/wp\/v2\/pages\/660552\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.sfmoma.org\/wp-json\/wp\/v2\/media\/680060"}],"wp:attachment":[{"href":"https:\/\/www.sfmoma.org\/wp-json\/wp\/v2\/media?parent=660552"}],"wp:term":[{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.sfmoma.org\/wp-json\/wp\/v2\/coauthors?post=660552"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}