seawolf2357 commited on
Commit
e2255ea
·
verified ·
1 Parent(s): 616e960

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +170 -155
app.py CHANGED
@@ -12,7 +12,7 @@ def fetch_trending_spaces(offset=0, limit=72):
12
  try:
13
  # Simple data fetching
14
  url = "https://huggingface.co/api/spaces"
15
- params = {"limit": 500} # Get max 500
16
 
17
  # Increase timeout
18
  response = requests.get(url, params=params, timeout=30)
@@ -206,8 +206,7 @@ if __name__ == '__main__':
206
 
207
  # Create index.html file
208
  with open('templates/index.html', 'w', encoding='utf-8') as f:
209
- f.write('''
210
- <!DOCTYPE html>
211
  <html lang="en">
212
  <head>
213
  <meta charset="UTF-8">
@@ -527,9 +526,12 @@ if __name__ == '__main__':
527
  position: relative;
528
  }
529
 
 
530
  .grid-content iframe {
531
- width: 100%;
532
- height: 100%;
 
 
533
  border: none;
534
  border-radius: 0;
535
  }
@@ -550,17 +552,18 @@ if __name__ == '__main__':
550
  }
551
 
552
  .error-emoji {
553
- font-size: 5rem;
554
- margin-bottom: 1rem;
555
  animation: bounce 1s infinite alternate;
 
556
  }
557
 
558
  @keyframes bounce {
559
  from {
560
- transform: translateY(0px);
561
  }
562
  to {
563
- transform: translateY(-10px);
564
  }
565
  }
566
 
@@ -730,6 +733,14 @@ if __name__ == '__main__':
730
  height: 300px;
731
  }
732
  }
 
 
 
 
 
 
 
 
733
  </style>
734
  </head>
735
  <body>
@@ -825,7 +836,123 @@ if __name__ == '__main__':
825
  staticModeAttempted: {}, // Track which spaces have attempted static mode
826
  statsVisible: false,
827
  chartInstance: null,
828
- topOwners: []
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
829
  };
830
 
831
  // Random emoji list for 404 errors
@@ -852,90 +979,7 @@ if __name__ == '__main__':
852
  '🍱', '🍘', '🍙', '🍚', '🍛', '🍜', '🍝', '🍠', '🍢', '🍣',
853
  '🍤', '🍥', '🥮', '🍡', '🥟', '🥠', '🥡', '🦀', '🦞', '🦐',
854
  '🦑', '🦪', '🍦', '🍧', '🍨', '🍩', '🍪', '🎂', '🍰', '🧁',
855
- '🥧', '🍫', '🍬', '🍭', '🍮', '🍯', '🍼', '🥛', '☕', '🍵',
856
- '🍶', '🍾', '🍷', '🍸', '🍹', '🍺', '🍻', '🥂', '🥃', '🥤',
857
- '🧃', '🧉', '🧊', '🥢', '🍽️', '🍴', '🥄', '🔪', '🏺', '🌍',
858
- '🌎', '🌏', '🌐', '🗺️', '🗾', '🧭', '🏔️', '⛰️', '🌋', '🗻',
859
- '🏕️', '🏖️', '🏜️', '🏝️', '🏞️', '🏟️', '🏛️', '🏗️', '🧱', '🏘️',
860
- '🏚️', '🏠', '🏡', '🏢', '🏣', '🏤', '🏥', '🏦', '🏨', '🏩',
861
- '🏪', '🏫', '🏬', '🏭', '🏯', '🏰', '💒', '🗼', '🗽', '⛪',
862
- '🕌', '🛕', '🕍', '⛩️', '🕋', '⛲', '⛺', '🌁', '🌃', '🏙️',
863
- '🌄', '🌅', '🌆', '🌇', '🌉', '♨️', '🎠', '🎡', '🎢', '💈',
864
- '🎪', '🚂', '🚃', '🚄', '🚅', '🚆', '🚇', '🚈', '🚉', '🚊',
865
- '🚝', '🚞', '🚋', '🚌', '🚍', '🚎', '🚐', '🚑', '🚒', '🚓',
866
- '🚔', '🚕', '🚖', '🚗', '🚘', '🚙', '🚚', '🚛', '🚜', '🏎️',
867
- '🏍️', '🛵', '🦽', '🦼', '🛺', '🚲', '🛴', '🛹', '🚏', '🛣️',
868
- '🛤️', '🛢️', '⛽', '🚨', '🚥', '🚦', '🛑', '🚧', '⚓', '⛵',
869
- '🛶', '🚤', '🛳️', '⛴️', '🛥️', '🚢', '✈️', '🛩️', '🛫', '🛬',
870
- '🪂', '💺', '🚁', '🚟', '🚠', '🚡', '🛰️', '🚀', '🛸', '🛎️',
871
- '🧳', '⌛', '⏳', '⌚', '⏰', '⏱️', '⏲️', '🕰️', '🕛', '🕧',
872
- '🕐', '🕜', '🕑', '🕝', '🕒', '🕞', '🕓', '🕟', '🕔', '🕠',
873
- '🕕', '🕡', '🕖', '🕢', '🕗', '🕣', '🕘', '🕤', '🕙', '🕥',
874
- '🕚', '🕦', '🌑', '🌒', '🌓', '🌔', '🌕', '🌖', '🌗', '🌘',
875
- '🌙', '🌚', '🌛', '🌜', '🌡️', '☀️', '🌝', '🌞', '🪐', '⭐',
876
- '🌟', '🌠', '🌌', '☁️', '⛅', '⛈️', '🌤️', '🌥️', '🌦️', '🌧️',
877
- '🌨️', '🌩️', '🌪️', '🌫️', '🌬️', '🌀', '🌈', '🌂', '☂️', '☔',
878
- '⛱️', '⚡', '❄️', '☃️', '⛄', '☄️', '🔥', '💧', '🌊', '🎃',
879
- '🎄', '🎆', '🎇', '🧨', '✨', '🎈', '🎉', '🎊', '🎋', '🎍',
880
- '🎎', '🎏', '🎐', '🎑', '🧧', '🎀', '🎁', '🎗️', '🎟️', '🎫',
881
- '🎖️', '🏆', '🏅', '🥇', '🥈', '🥉', '⚽', '⚾', '🥎', '🏀',
882
- '🏐', '🏈', '🏉', '🎾', '🥏', '🎳', '🏏', '🏑', '🏒', '🥍',
883
- '🏓', '🏸', '🥊', '🥋', '🥅', '⛳', '⛸️', '🎣', '🤿', '🎽',
884
- '🎿', '🛷', '🥌', '🎯', '🪀', '🪁', '🎱', '🔮', '🧿', '🎮',
885
- '🕹️', '🎰', '🎲', '🧩', '🧸', '♠️', '♥️', '♦️', '♣️', '♟️',
886
- '🃏', '🀄', '🎴', '🎭', '🖼️', '🎨', '🧵', '🧶', '👓', '🕶️',
887
- '🥽', '🥼', '🦺', '👔', '👕', '👖', '🧣', '🧤', '🧥', '🧦',
888
- '👗', '👘', '🥻', '🩱', '🩲', '🩳', '👙', '👚', '👛', '👜',
889
- '👝', '🛍️', '🎒', '👞', '👟', '🥾', '🥿', '👠', '👡', '🩰',
890
- '👢', '👑', '👒', '🎩', '🎓', '🧢', '⛑️', '📿', '💄', '💍',
891
- '💎', '🔇', '🔈', '🔉', '🔊', '📢', '📣', '📯', '🔔', '🔕',
892
- '🎼', '🎵', '🎶', '🎙️', '🎚️', '🎛️', '🎤', '🎧', '📻', '🎷',
893
- '🎸', '🎹', '🎺', '🎻', '🪕', '🥁', '📱', '📲', '☎️', '📞',
894
- '📟', '📠', '🔋', '🔌', '💻', '🖥️', '🖨️', '⌨️', '🖱️', '🖲️',
895
- '💽', '💾', '💿', '📀', '🧮', '🎥', '🎞️', '📽️', '🎬', '📺',
896
- '📷', '📸', '📹', '📼', '🔍', '🔎', '🕯️', '💡', '🔦', '🏮',
897
- '🪔', '📔', '📕', '📖', '📗', '📘', '📙', '📚', '📓', '📒',
898
- '📃', '📜', '📄', '📰', '🗞️', '📑', '🔖', '🏷️', '💰', '💴',
899
- '💵', '💶', '💷', '💸', '💳', '🧾', '💹', '✉️', '📧', '📨',
900
- '📩', '📤', '📥', '📦', '📫', '📪', '📬', '📭', '📮', '🗳️',
901
- '✏️', '✒️', '🖋️', '🖊️', '🖌️', '🖍️', '📝', '💼', '📁', '📂',
902
- '🗂️', '📅', '📆', '🗒️', '🗓️', '📇', '📈', '📉', '📊', '📋',
903
- '📌', '📍', '📎', '🖇️', '📏', '📐', '✂️', '🗃️', '🗄️', '🗑️',
904
- '🔒', '🔓', '🔏', '🔐', '🔑', '🗝️', '🔨', '🪓', '⛏️', '⚒️',
905
- '🛠️', '🗡️', '⚔️', '🔫', '🏹', '🛡️', '🔧', '🔩', '⚙️', '🗜️',
906
- '⚖️', '🦯', '🔗', '⛓️', '🧰', '🧲', '⚗️', '🧪', '🧫', '🧬',
907
- '🔬', '🔭', '📡', '💉', '🩸', '💊', '🩹', '🩺', '🚪', '🛏️',
908
- '🛋️', '🪑', '🚽', '🚿', '🛁', '🪒', '🧴', '🧷', '🧹', '🧺',
909
- '🧻', '🧼', '🧽', '🧯', '🛒', '🚬', '⚰️', '⚱️', '🗿', '🏧',
910
- '🚮', '🚰', '♿', '🚹', '🚺', '🚻', '🚼', '🚾', '🛂', '🛃',
911
- '🛄', '🛅', '⚠️', '🚸', '⛔', '🚫', '🚳', '🚭', '🚯', '🚱',
912
- '🚷', '📵', '🔞', '☢️', '☣️', '⬆️', '↗️', '➡️', '↘️', '⬇️',
913
- '↙️', '⬅️', '↖️', '↕️', '↔️', '↩️', '↪️', '⤴️', '⤵️', '🔃',
914
- '🔄', '🔙', '🔚', '🔛', '🔜', '🔝', '🛐', '⚛️', '🕉️', '✡️',
915
- '☸️', '☯️', '✝️', '☦️', '☪️', '☮️', '🕎', '🔯', '♈', '♉',
916
- '♊', '♋', '♌', '♍', '♎', '♏', '♐', '♑', '♒', '♓', '⛎',
917
- '🔀', '🔁', '🔂', '▶️', '⏩', '⏭️', '⏯️', '◀️', '⏪', '⏮️',
918
- '🔼', '⏫', '🔽', '⏬', '⏸️', '⏹️', '⏺️', '⏏️', '🎦', '🔅',
919
- '🔆', '📶', '📳', '📴', '♀️', '♂️', '⚧️', '✖️', '➕', '➖',
920
- '➗', '♾️', '‼️', '⁉️', '❓', '❔', '❕', '❗', '〰️', '💱',
921
- '💲', '⚕️', '♻️', '⚜️', '🔱', '📛', '🔰', '⭕', '✅', '☑️',
922
- '✔️', '❌', '❎', '➰', '➿', '〽️', '✳️', '✴️', '❇️', '©️',
923
- '®️', '™️', '#️⃣', '*️⃣', '0️⃣', '1️⃣', '2️⃣', '3️⃣', '4️⃣', '5️⃣',
924
- '6️⃣', '7️⃣', '8️⃣', '9️⃣', '🔟', '🔠', '🔡', '🔢', '🔣', '🔤',
925
- '🅰️', '🆎', '🅱️', '🆑', '🆒', '🆓', 'ℹ️', '🆔', 'Ⓜ️', '🆕',
926
- '🆖', '🅾️', '🆗', '🅿️', '🆘', '🆙', '🆚', '🈁', '🈂️', '🈷️',
927
- '🈶', '🈯', '🉐', '🈹', '🈚', '🈲', '🉑', '🈸', '🈴', '🈳',
928
- '㊗️', '㊙️', '🈺', '🈵', '🔴', '🟠', '🟡', '🟢', '🔵', '🟣',
929
- '🟤', '⚫', '⚪', '🟥', '🟧', '🟨', '🟩', '🟦', '🟪', '🟫',
930
- '⬛', '⬜', '◼️', '◻️', '◾', '◽', '▪️', '▫️', '🔶', '🔷',
931
- '🔸', '🔹', '🔺', '🔻', '💠', '🔘', '🔳', '🔲', '🏁', '🚩',
932
- '🎌', '🏴', '🏳️', '🏳️‍🌈', '🏴‍☠️', '🇦🇨', '🇦🇩', '🇦🇪', '🇦🇫', '🇦🇬',
933
- '🇦🇮', '🇦🇱', '🇦🇲', '🇦🇴', '🇦🇶', '🇦🇷', '🇦🇸', '🇦🇹', '🇦🇺', '🇦🇼',
934
- '🇦🇽', '🇦🇿', '🇧🇦', '🇧🇧', '🇧🇩', '🇧🇪', '🇧🇫', '🇧🇬', '🇧🇭', '🇧🇮',
935
- '🇧🇯', '🇧🇱', '🇧🇲', '🇧🇳', '🇧🇴', '🇧🇶', '🇧🇷', '🇧🇸', '🇧🇹', '🇧🇻',
936
- '🇧🇼', '🇧🇾', '🇧🇿', '🇨🇦', '🇨🇨', '🇨🇩', '🇨🇫', '🇨🇬', '🇨🇭', '🇨🇮',
937
- '🇨🇰', '🇨🇱', '🇨🇲', '🇨🇳', '🇨🇴', '🇨🇵', '🇨🇷', '🇨🇺', '🇨🇻', '🇨🇼',
938
- '🇨🇽', '🇨🇾', '🇨🇿'
939
  ];
940
 
941
  // Display loading indicator
@@ -1063,6 +1107,17 @@ if __name__ == '__main__':
1063
  title: {
1064
  display: true,
1065
  text: 'Creator ID'
 
 
 
 
 
 
 
 
 
 
 
1066
  }
1067
  }
1068
  }
@@ -1199,21 +1254,6 @@ if __name__ == '__main__':
1199
  errorMessage.textContent = `"${title}" space couldn't be loaded`;
1200
  errorPlaceholder.appendChild(errorMessage);
1201
 
1202
- // Try static site version button
1203
- const directStaticLink = document.createElement('a');
1204
- directStaticLink.href = `https://${owner}-${name}.hf.space/index.html`;
1205
- directStaticLink.target = '_blank';
1206
- directStaticLink.textContent = 'Try Static Version';
1207
- directStaticLink.style.color = '#3182ce';
1208
- directStaticLink.style.marginTop = '10px';
1209
- directStaticLink.style.display = 'inline-block';
1210
- directStaticLink.style.padding = '8px 16px';
1211
- directStaticLink.style.background = '#ebf8ff';
1212
- directStaticLink.style.borderRadius = '5px';
1213
- directStaticLink.style.fontWeight = '600';
1214
- directStaticLink.style.marginRight = '10px';
1215
- errorPlaceholder.appendChild(directStaticLink);
1216
-
1217
  // Direct HF link
1218
  const directLink = document.createElement('a');
1219
  directLink.href = `https://huggingface.co/spaces/${owner}/${name}`;
@@ -1323,59 +1363,34 @@ if __name__ == '__main__':
1323
  iframe.setAttribute('frameborder', '0');
1324
  iframe.loading = 'lazy'; // Lazy load iframes for better performance
1325
 
 
 
 
 
1326
  // Track this space
1327
  const spaceKey = `${owner}/${name}`;
1328
- state.staticModeAttempted[spaceKey] = false;
 
 
 
 
 
1329
 
1330
- // Handle iframe loading errors
1331
  iframe.onerror = function() {
1332
- if (!state.staticModeAttempted[spaceKey]) {
1333
- // Try static mode
1334
- state.staticModeAttempted[spaceKey] = true;
1335
- iframe.src = directUrl + '/index.html';
1336
- } else {
1337
- // If static mode also failed, show error with random emoji
1338
- handleIframeError(iframe, owner, name, title);
1339
- }
1340
  };
1341
 
1342
- // Advanced error handling for iframe load
1343
- iframe.onload = function() {
1344
- try {
1345
- // Try to access iframe content to check if it loaded properly
1346
- const iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
1347
- // Check if we got a 404 page or other error by looking for certain elements
1348
- const isErrorPage = iframeDoc.title.includes('404') ||
1349
- iframeDoc.body.textContent.includes('404') ||
1350
- iframeDoc.body.textContent.includes('not found');
1351
-
1352
- if (isErrorPage) {
1353
- // For 404 errors, show random emoji
1354
- if (!state.staticModeAttempted[spaceKey]) {
1355
- // Try static mode first
1356
- state.staticModeAttempted[spaceKey] = true;
1357
- iframe.src = directUrl + '/index.html';
1358
- } else {
1359
- // If static mode already attempted and still failing, show random emoji
1360
- handleIframeError(iframe, owner, name, title);
1361
- }
1362
- }
1363
- } catch (e) {
1364
- // Cross-origin errors are expected, this generally means the iframe loaded
1365
- // If we need to check for static mode, we do it based on other signals
1366
-
1367
- // We can try detecting failed loads by using a timer and checking if the iframe content is visible
1368
- setTimeout(() => {
1369
- // This is a basic heuristic - if the iframe still has no visible content after 5s, try static mode
1370
- if (!state.staticModeAttempted[spaceKey] &&
1371
- (iframe.clientHeight < 10 || iframe.clientWidth < 10)) {
1372
- state.staticModeAttempted[spaceKey] = true;
1373
- iframe.src = directUrl + '/index.html';
1374
- }
1375
- }, 5000);
1376
  }
1377
- };
1378
 
 
1379
  iframeContainer.appendChild(iframe);
1380
  content.appendChild(iframeContainer);
1381
 
@@ -1463,4 +1478,4 @@ if __name__ == '__main__':
1463
  ''')
1464
 
1465
  # Use port 7860 for Huggingface Spaces
1466
- app.run(host='0.0.0.0', port=7860)
 
12
  try:
13
  # Simple data fetching
14
  url = "https://huggingface.co/api/spaces"
15
+ params = {"limit": 10000} # Get max 10000 to fetch more spaces
16
 
17
  # Increase timeout
18
  response = requests.get(url, params=params, timeout=30)
 
206
 
207
  # Create index.html file
208
  with open('templates/index.html', 'w', encoding='utf-8') as f:
209
+ f.write('''<!DOCTYPE html>
 
210
  <html lang="en">
211
  <head>
212
  <meta charset="UTF-8">
 
526
  position: relative;
527
  }
528
 
529
+ /* Apply 70% scaling to iframes */
530
  .grid-content iframe {
531
+ transform: scale(0.7);
532
+ transform-origin: top left;
533
+ width: 142.857%;
534
+ height: 142.857%;
535
  border: none;
536
  border-radius: 0;
537
  }
 
552
  }
553
 
554
  .error-emoji {
555
+ font-size: 6rem;
556
+ margin-bottom: 1.5rem;
557
  animation: bounce 1s infinite alternate;
558
+ text-shadow: 0 10px 20px rgba(0,0,0,0.1);
559
  }
560
 
561
  @keyframes bounce {
562
  from {
563
+ transform: translateY(0px) scale(1);
564
  }
565
  to {
566
+ transform: translateY(-15px) scale(1.1);
567
  }
568
  }
569
 
 
733
  height: 300px;
734
  }
735
  }
736
+
737
+ .error-emoji-detector {
738
+ position: fixed;
739
+ top: -9999px;
740
+ left: -9999px;
741
+ z-index: -1;
742
+ opacity: 0;
743
+ }
744
  </style>
745
  </head>
746
  <body>
 
836
  staticModeAttempted: {}, // Track which spaces have attempted static mode
837
  statsVisible: false,
838
  chartInstance: null,
839
+ topOwners: [],
840
+ iframeStatuses: {} // Track iframe loading status
841
+ };
842
+
843
+ // Advanced iframe loader for better error detection
844
+ const iframeLoader = {
845
+ checkQueue: {},
846
+ maxAttempts: 5, // Try multiple times
847
+ checkInterval: 5000, // Check every 5 seconds
848
+
849
+ // Start checking iframe loading status
850
+ startChecking: function(iframe, owner, name, title, spaceKey) {
851
+ // Initialize tracking
852
+ this.checkQueue[spaceKey] = {
853
+ iframe: iframe,
854
+ owner: owner,
855
+ name: name,
856
+ title: title,
857
+ attempts: 0,
858
+ status: 'loading'
859
+ };
860
+
861
+ // Start recursive checking
862
+ this.checkIframeStatus(spaceKey);
863
+ },
864
+
865
+ // Check iframe loading status
866
+ checkIframeStatus: function(spaceKey) {
867
+ if (!this.checkQueue[spaceKey]) return;
868
+
869
+ const item = this.checkQueue[spaceKey];
870
+ const iframe = item.iframe;
871
+
872
+ // If already processed, stop checking
873
+ if (item.status !== 'loading') {
874
+ delete this.checkQueue[spaceKey];
875
+ return;
876
+ }
877
+
878
+ // Increment attempt counter
879
+ item.attempts++;
880
+
881
+ try {
882
+ // 1. Check if iframe was removed from DOM
883
+ if (!iframe || !iframe.parentNode) {
884
+ delete this.checkQueue[spaceKey];
885
+ return;
886
+ }
887
+
888
+ // 2. Check if content has loaded
889
+ try {
890
+ const hasContent = iframe.contentWindow &&
891
+ iframe.contentWindow.document &&
892
+ iframe.contentWindow.document.body;
893
+
894
+ // 2.1 If content exists and has actual content loaded
895
+ if (hasContent && iframe.contentWindow.document.body.innerHTML.length > 100) {
896
+ // Check if it contains error text
897
+ const bodyText = iframe.contentWindow.document.body.textContent.toLowerCase();
898
+ if (bodyText.includes('forbidden') ||
899
+ bodyText.includes('404') ||
900
+ bodyText.includes('not found') ||
901
+ bodyText.includes('error')) {
902
+ item.status = 'error';
903
+ handleIframeError(iframe, item.owner, item.name, item.title);
904
+ } else {
905
+ item.status = 'success';
906
+ }
907
+ delete this.checkQueue[spaceKey];
908
+ return;
909
+ }
910
+ } catch(e) {
911
+ // Cross-origin access errors are expected - might be normal loading
912
+ }
913
+
914
+ // 3. Check iframe's visible size
915
+ const rect = iframe.getBoundingClientRect();
916
+ if (rect.width > 50 && rect.height > 50 && item.attempts > 2) {
917
+ // If it has sufficient size, mark as success
918
+ item.status = 'success';
919
+ delete this.checkQueue[spaceKey];
920
+ return;
921
+ }
922
+
923
+ // 4. If we've reached max attempts
924
+ if (item.attempts >= this.maxAttempts) {
925
+ // Final check: is iframe visible?
926
+ if (iframe.offsetWidth > 0 && iframe.offsetHeight > 0) {
927
+ // If visible, mark as success
928
+ item.status = 'success';
929
+ } else {
930
+ // If still not visible, mark as error
931
+ item.status = 'error';
932
+ handleIframeError(iframe, item.owner, item.name, item.title);
933
+ }
934
+ delete this.checkQueue[spaceKey];
935
+ return;
936
+ }
937
+
938
+ // Schedule next check with exponential backoff
939
+ const nextDelay = this.checkInterval * Math.pow(1.5, item.attempts - 1);
940
+ setTimeout(() => this.checkIframeStatus(spaceKey), nextDelay);
941
+
942
+ } catch (e) {
943
+ console.error('Error checking iframe status:', e);
944
+
945
+ // If error occurs, try a few more times
946
+ if (item.attempts >= this.maxAttempts) {
947
+ item.status = 'error';
948
+ handleIframeError(iframe, item.owner, item.name, item.title);
949
+ delete this.checkQueue[spaceKey];
950
+ } else {
951
+ // Try again
952
+ setTimeout(() => this.checkIframeStatus(spaceKey), this.checkInterval);
953
+ }
954
+ }
955
+ }
956
  };
957
 
958
  // Random emoji list for 404 errors
 
979
  '🍱', '🍘', '🍙', '🍚', '🍛', '🍜', '🍝', '🍠', '🍢', '🍣',
980
  '🍤', '🍥', '🥮', '🍡', '🥟', '🥠', '🥡', '🦀', '🦞', '🦐',
981
  '🦑', '🦪', '🍦', '🍧', '🍨', '🍩', '🍪', '🎂', '🍰', '🧁',
982
+ '🥧', '🍫', '🍬', '🍭', '🍮', '🍯', '🍼', '🥛', '☕', '🍵'
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
983
  ];
984
 
985
  // Display loading indicator
 
1107
  title: {
1108
  display: true,
1109
  text: 'Creator ID'
1110
+ },
1111
+ // Ensure all labels are shown without gaps
1112
+ ticks: {
1113
+ autoSkip: false,
1114
+ font: function(context) {
1115
+ // Adjust font size to fit all labels if needed
1116
+ const defaultSize = 11;
1117
+ return {
1118
+ size: labels.length > 20 ? defaultSize - 1 : defaultSize
1119
+ };
1120
+ }
1121
  }
1122
  }
1123
  }
 
1254
  errorMessage.textContent = `"${title}" space couldn't be loaded`;
1255
  errorPlaceholder.appendChild(errorMessage);
1256
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1257
  // Direct HF link
1258
  const directLink = document.createElement('a');
1259
  directLink.href = `https://huggingface.co/spaces/${owner}/${name}`;
 
1363
  iframe.setAttribute('frameborder', '0');
1364
  iframe.loading = 'lazy'; // Lazy load iframes for better performance
1365
 
1366
+ // Unique ID for this iframe
1367
+ const iframeId = `iframe-${owner}-${name}`;
1368
+ iframe.id = iframeId;
1369
+
1370
  // Track this space
1371
  const spaceKey = `${owner}/${name}`;
1372
+ state.iframeStatuses[spaceKey] = 'loading';
1373
+
1374
+ // Use the advanced loader for better error detection
1375
+ iframe.onload = function() {
1376
+ iframeLoader.startChecking(iframe, owner, name, title, spaceKey);
1377
+ };
1378
 
1379
+ // Direct error handling
1380
  iframe.onerror = function() {
1381
+ handleIframeError(iframe, owner, name, title);
1382
+ state.iframeStatuses[spaceKey] = 'error';
 
 
 
 
 
 
1383
  };
1384
 
1385
+ // Final fallback - if nothing has happened after 30 seconds, show error
1386
+ setTimeout(() => {
1387
+ if (state.iframeStatuses[spaceKey] === 'loading') {
1388
+ handleIframeError(iframe, owner, name, title);
1389
+ state.iframeStatuses[spaceKey] = 'error';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1390
  }
1391
+ }, 30000);
1392
 
1393
+ // Add iframe to container
1394
  iframeContainer.appendChild(iframe);
1395
  content.appendChild(iframeContainer);
1396
 
 
1478
  ''')
1479
 
1480
  # Use port 7860 for Huggingface Spaces
1481
+ app.run(host='0.0.0.0', port=7860)