(function () {
window.DENO_DOC_SEARCH_INDEX = {"kind":"search","nodes":[{"id":"namespace_port","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"PORT","file":"api/config.ts","doc":"The port the server listens on (GERBEUR_PORT, default 8000).","url":"./api/config.ts/~/PORT.html","deprecated":false},{"id":"namespace_smtps_url","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"SMTPS_URL","file":"api/config.ts","doc":"The smtps:// URL of the server email-service.ts sends mail through (GERBEUR_SMTPS_URL). When it is empty, no email is sent: sign-up sends no welcome, a password reset request does nothing, and there are no digests.","url":"./api/config.ts/~/SMTPS_URL.html","deprecated":false},{"id":"namespace_email_enabled","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"EMAIL_ENABLED","file":"api/config.ts","doc":"Whether the instance sends email, which is whether SMTPS_URL is set. email-service.ts opens its transport by it, and index.html tells the client, whose settings show the digest switches disabled without it.","url":"./api/config.ts/~/EMAIL_ENABLED.html","deprecated":false},{"id":"namespace_from_email","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"FROM_EMAIL","file":"api/config.ts","doc":"The From address of every email (GERBEUR_FROM_EMAIL), as an address or as Name
. email-service.ts refuses to load without it when SMTPS_URL is set.","url":"./api/config.ts/~/FROM_EMAIL.html","deprecated":false},{"id":"namespace_welcome_email_body","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"WELCOME_EMAIL_BODY","file":"api/config.ts","doc":"The Markdown of the welcome email sent on registration (GERBEUR_WELCOME_EMAIL_BODY), or null for the built-in one in the EMAIL_LOCALE. api/mail/welcome.ts replaces {{site_name}} and {{username}} in it.","url":"./api/config.ts/~/WELCOME_EMAIL_BODY.html","deprecated":false},{"id":"namespace_email_locale","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"EMAIL_LOCALE","file":"api/config.ts","doc":"The language of every email (GERBEUR_EMAIL_LOCALE). The interface picks each visitor's language in their browser, which the server never learns, so the emails take the instance's. A value that isn't a locale means the source one, English.","url":"./api/config.ts/~/EMAIL_LOCALE.html","deprecated":false},{"id":"namespace_default_style","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"DEFAULT_STYLE","file":"api/config.ts","doc":"The instance's style (GERBEUR_DEFAULT_STYLE). The site shows it until a visitor or their account picks one, through index.html, and the emails that aren't a user's own (the welcome and the password reset) are drawn in it. A value that isn't a style means BASE_STYLE.","url":"./api/config.ts/~/DEFAULT_STYLE.html","deprecated":false},{"id":"namespace_jwt_secret","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"JWT_SECRET","file":"api/config.ts","doc":"The key lib/jwt.ts signs and verifies tokens with (GERBEUR_JWT_SECRET). The server refuses to start without it.","url":"./api/config.ts/~/JWT_SECRET.html","deprecated":false},{"id":"namespace_listen_host","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"LISTEN_HOST","file":"api/config.ts","doc":"The interface the server binds to (GERBEUR_LISTEN_HOST). The default, 0.0.0.0, lets Docker forward the port; 127.0.0.1 keeps it to loopback.","url":"./api/config.ts/~/LISTEN_HOST.html","deprecated":false},{"id":"namespace_public_url","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"PUBLIC_URL","file":"api/config.ts","doc":"The URL visitors reach the server at (GERBEUR_PUBLIC_URL), without a trailing slash. Behind a reverse proxy it must be the outside URL: it is an allowed origin, it tells links to this site's own pages from other links, and it prefixes the image URLs in their previews.","url":"./api/config.ts/~/PUBLIC_URL.html","deprecated":false},{"id":"namespace_frontend_url","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"FRONTEND_URL","file":"api/config.ts","doc":"Points password reset links and the Open Graph tags' page URLs at the frontend when it isn't served from PUBLIC_URL, as with a separate Vite server, and allows it as an origin. It is GERBEUR_FRONTEND_URL, without a trailing slash.","url":"./api/config.ts/~/FRONTEND_URL.html","deprecated":false},{"id":"namespace_db_path","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"DB_PATH","file":"api/config.ts","doc":"The SQLite database file (GERBEUR_DB_PATH). api/test/setup.ts points it at a throwaway file before anything opens the database.","url":"./api/config.ts/~/DB_PATH.html","deprecated":false},{"id":"namespace_uploads_dir","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"UPLOADS_DIR","file":"api/config.ts","doc":"The directory uploads are stored under (GERBEUR_UPLOADS_DIR). Each kind has its subdirectory below, created by the first upload, and each file is named after the id of what it belongs to.","url":"./api/config.ts/~/UPLOADS_DIR.html","deprecated":false},{"id":"namespace_dumps_dir","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"DUMPS_DIR","file":"api/config.ts","doc":"Holds the file of each file dump.","url":"./api/config.ts/~/DUMPS_DIR.html","deprecated":false},{"id":"namespace_avatars_dir","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"AVATARS_DIR","file":"api/config.ts","doc":"Holds each user's avatar.","url":"./api/config.ts/~/AVATARS_DIR.html","deprecated":false},{"id":"namespace_playlist_images_dir","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"PLAYLIST_IMAGES_DIR","file":"api/config.ts","doc":"Holds each playlist's cover.","url":"./api/config.ts/~/PLAYLIST_IMAGES_DIR.html","deprecated":false},{"id":"namespace_attachments_dir","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"ATTACHMENTS_DIR","file":"api/config.ts","doc":"Holds the images pasted into chat messages, comments, dump notes and descriptions. The startup tasks purge those nothing links to.","url":"./api/config.ts/~/ATTACHMENTS_DIR.html","deprecated":false},{"id":"namespace_thumbnails_dir","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"THUMBNAILS_DIR","file":"api/config.ts","doc":"Holds the thumbnails a poster uploads (-custom) and those the thumbnails route generates from file dumps.","url":"./api/config.ts/~/THUMBNAILS_DIR.html","deprecated":false},{"id":"namespace_scaled_dir","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"SCALED_DIR","file":"api/config.ts","doc":"Holds the scaled-down copies of the images above, which lib/ffmpeg.ts makes as they are first asked for, each at its upload's path with its width. It can be emptied at any time: the copies are made again.","url":"./api/config.ts/~/SCALED_DIR.html","deprecated":false},{"id":"namespace_max_image_size_bytes","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"MAX_IMAGE_SIZE_BYTES","file":"api/config.ts","doc":"Caps the size of an image upload, in bytes, for avatars, covers, thumbnails and attachments. lib/upload.ts states it in megabytes in its error.","url":"./api/config.ts/~/MAX_IMAGE_SIZE_BYTES.html","deprecated":false},{"id":"namespace_dump_allowed_mime_prefixes","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"DUMP_ALLOWED_MIME_PREFIXES","file":"api/config.ts","doc":"The MIME type prefixes a file dump may have. dump-service also accepts the exact types of DUMP_ALLOWED_MIME_TYPES.","url":"./api/config.ts/~/DUMP_ALLOWED_MIME_PREFIXES.html","deprecated":false},{"id":"namespace_dump_allowed_mime_types","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"DUMP_ALLOWED_MIME_TYPES","file":"api/config.ts","doc":"The documents and archives a file dump may be, beyond the prefixes.","url":"./api/config.ts/~/DUMP_ALLOWED_MIME_TYPES.html","deprecated":false},{"id":"namespace_pagination_default_limit","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"PAGINATION_DEFAULT_LIMIT","file":"api/config.ts","doc":"The page size when a request names none.","url":"./api/config.ts/~/PAGINATION_DEFAULT_LIMIT.html","deprecated":false},{"id":"namespace_pagination_max_limit","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"PAGINATION_MAX_LIMIT","file":"api/config.ts","doc":"The largest page size a request may ask for.","url":"./api/config.ts/~/PAGINATION_MAX_LIMIT.html","deprecated":false},{"id":"namespace_orphaned_attachments_retention_hours","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"ORPHANED_ATTACHMENTS_RETENTION_HOURS","file":"api/config.ts","doc":"How long an attachment nothing links to is kept before startup purges it.","url":"./api/config.ts/~/ORPHANED_ATTACHMENTS_RETENTION_HOURS.html","deprecated":false},{"id":"namespace_unused_invites_retention_days","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"UNUSED_INVITES_RETENTION_DAYS","file":"api/config.ts","doc":"How long an invite stays usable. invite-service refuses an older one, and the startup tasks purge it.","url":"./api/config.ts/~/UNUSED_INVITES_RETENTION_DAYS.html","deprecated":false},{"id":"namespace_community_refresh_minutes","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"COMMUNITY_REFRESH_MINUTES","file":"api/config.ts","doc":"How often, in minutes, the /community page's figures are recomputed (GERBEUR_COMMUNITY_REFRESH_MINUTES), 15 by default.","url":"./api/config.ts/~/COMMUNITY_REFRESH_MINUTES.html","deprecated":false},{"id":"namespace_og_site_name","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"OG_SITE_NAME","file":"api/config.ts","doc":"The site's name (GERBEUR_SITE_NAME). It is filled into index.html, the OG tags, the icons' manifest and the emails.","url":"./api/config.ts/~/OG_SITE_NAME.html","deprecated":false},{"id":"namespace_site_emoji","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"SITE_EMOJI","file":"api/config.ts","doc":"The emoji that serves as the site's logo (GERBEUR_SITE_EMOJI). The icons script draws the favicons from it, and index.html carries it to the app's header, so changing it needs a restart but no rebuild.","url":"./api/config.ts/~/SITE_EMOJI.html","deprecated":false},{"id":"namespace_bandcampplayer","kind":[{"char":"T","kind":"TypeAlias","title":"Type Alias"}],"name":"BandcampPlayer","file":"api/config.ts","doc":"How the frontend plays Bandcamp. \"embed\" uses Bandcamp's iframe, which can't autoplay. \"native\" resolves the page's streams through GET /api/bandcamp/tracks and plays them in the app's player, which autoplays and queues an album's tracks.","url":"./api/config.ts/~/BandcampPlayer.html","deprecated":false},{"id":"namespace_bandcamp_player","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"BANDCAMP_PLAYER","file":"api/config.ts","doc":"How the frontend plays Bandcamp (GERBEUR_BANDCAMP_PLAYER), passed to it in index.html. Any value but \"native\" means \"embed\", so a typo falls back to the player that always works.","url":"./api/config.ts/~/BANDCAMP_PLAYER.html","deprecated":false},{"id":"namespace_theme_color","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"THEME_COLOR","file":"api/config.ts","doc":"The background of the generated Apple touch icon, the manifest's colors, and the accent of previews of this site's own pages. index.html's theme-color tags don't follow it.","url":"./api/config.ts/~/THEME_COLOR.html","deprecated":false},{"id":"namespace_allowed_origins","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"ALLOWED_ORIGINS","file":"api/config.ts","doc":"The origins that CORS in main.ts and the WebSocket route accept. They are PUBLIC_URL, FRONTEND_URL and the comma-separated GERBEUR_ALLOWED_ORIGINS.","url":"./api/config.ts/~/ALLOWED_ORIGINS.html","deprecated":false},{"id":"namespace_federation_allow_private","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"FEDERATION_ALLOW_PRIVATE","file":"api/config.ts","doc":"Lets federated sign-in reach instances on private addresses, localhost among them, and over plain http (GERBEUR_FEDERATION_ALLOW_PRIVATE=1), so that two instances on one machine can trust each other in development. Off, remote/gerbeur-instance.ts reaches only public https instances, since an identity is only as safe as the connection it came over.","url":"./api/config.ts/~/FEDERATION_ALLOW_PRIVATE.html","deprecated":false},{"id":"namespace_federation","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"FEDERATION","file":"api/config.ts","doc":"Which ways federated sign-in goes, each on unless set to 0.incoming (GERBEUR_FEDERATION_INCOMING): users of other instances sign in here. Off, the login and register pages offer no other instance, /manage lists only the blocked ones, which this instance's users can't sign in to (and none with outgoing off too), federation-service.ts refuses their sign-ins, and the accounts that came from one are signed out (getSessionState) until it is on again. Their homes' events are still applied, so that none is lost meanwhile.outgoing (GERBEUR_FEDERATION_OUTGOING): this instance's users sign in to others. Off, identity-provider-service.ts lets no instance sign them in, and its metadata says so, which the others check before sending anyone here to sign in. The settings page lists no instances, since at startup main.ts withdraws every grant they gave, which signs them out there.index.html tells the client both. An object, so that the tests can turn one off for a while.","url":"./api/config.ts/~/FEDERATION.html","deprecated":false},{"id":"namespace_federation","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"FEDERATION.incoming","file":"api/config.ts","doc":"","url":"./api/config.ts/~/FEDERATION.incoming.html","deprecated":false},{"id":"namespace_federation","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"FEDERATION.outgoing","file":"api/config.ts","doc":"","url":"./api/config.ts/~/FEDERATION.outgoing.html","deprecated":false},{"id":"namespace_db","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"db","file":"api/db/connection.ts","doc":"Serves every query of the server, as its only connection. Its queries are synchronous, so each one blocks the event loop while it runs.","url":"./api/db/connection.ts/~/db.html","deprecated":false},{"id":"namespace_transaction","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"transaction","file":"api/db/connection.ts","doc":"Runs fn in a transaction, so its writes commit together, in one commit rather than one each, and a throw rolls them all back and rethrows. A call inside another joins the outer transaction. fn must be synchronous: an await would commit before the rest of it runs.","url":"./api/db/connection.ts/~/transaction.html","deprecated":false},{"id":"namespace_runmigrations","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"runMigrations","file":"api/db/migrate.ts","doc":"Applies each migration db hasn't recorded yet, in order, each in its own transaction.","url":"./api/db/migrate.ts/~/runMigrations.html","deprecated":false},{"id":"namespace_up","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"up","file":"api/db/migrations/0001_comment_likes.ts","doc":"Run once by runMigrations. Existing comments start with no likes, and a database made from schema.sql already has both.","url":"./api/db/migrations/0001_comment_likes.ts/~/up.html","deprecated":false},{"id":"namespace_up","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"up","file":"api/db/migrations/0002_dump_thumbnail.ts","doc":"Run once by runMigrations. Existing dumps keep their fetched thumbnails, and a database made from schema.sql already has the column.","url":"./api/db/migrations/0002_dump_thumbnail.ts/~/up.html","deprecated":false},{"id":"namespace_up","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"up","file":"api/db/migrations/0003_dump_backlinks.ts","doc":"Run once by runMigrations. It doesn't scan the notes and comments already posted, so their links are recorded only once they are edited.","url":"./api/db/migrations/0003_dump_backlinks.ts/~/up.html","deprecated":false},{"id":"namespace_up","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"up","file":"api/db/migrations/0004_user_roles.ts","doc":"Run once by runMigrations. Every user becomes a user, except those with is_admin set, who become admins.","url":"./api/db/migrations/0004_user_roles.ts/~/up.html","deprecated":false},{"id":"namespace_up","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"up","file":"api/db/migrations/0005_drop_is_admin.ts","doc":"Run once by runMigrations, after 0004. A database made from schema.sql never had the column.","url":"./api/db/migrations/0005_drop_is_admin.ts/~/up.html","deprecated":false},{"id":"namespace_up","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"up","file":"api/db/migrations/0006_categories.ts","doc":"Run once by runMigrations. Existing dumps start in no category, and a database made from schema.sql already has both tables.","url":"./api/db/migrations/0006_categories.ts/~/up.html","deprecated":false},{"id":"namespace_up","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"up","file":"api/db/migrations/0007_password_reset_tokens.ts","doc":"Run once by runMigrations. A database made from schema.sql already has the table.","url":"./api/db/migrations/0007_password_reset_tokens.ts/~/up.html","deprecated":false},{"id":"namespace_up","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"up","file":"api/db/migrations/0008_chat_messages.ts","doc":"Run once by runMigrations. A database made from schema.sql already has the table.","url":"./api/db/migrations/0008_chat_messages.ts/~/up.html","deprecated":false},{"id":"namespace_up","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"up","file":"api/db/migrations/0009_chat_reply.ts","doc":"Run once by runMigrations. Existing messages reply to nothing, and a database made from schema.sql already has the column.","url":"./api/db/migrations/0009_chat_reply.ts/~/up.html","deprecated":false},{"id":"namespace_up","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"up","file":"api/db/migrations/0010_youtube_embed_start.ts","doc":"Run once by runMigrations. It leaves alone an embed URL that already has a start, and a row whose rich_content doesn't parse.","url":"./api/db/migrations/0010_youtube_embed_start.ts/~/up.html","deprecated":false},{"id":"namespace_up","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"up","file":"api/db/migrations/0011_split_favicon_thumbnail.ts","doc":"Run once by runMigrations. It leaves alone a row that already has a faviconUrl, and one whose rich_content doesn't parse. 0012 undoes its mistakes.","url":"./api/db/migrations/0011_split_favicon_thumbnail.ts/~/up.html","deprecated":false},{"id":"namespace_up","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"up","file":"api/db/migrations/0012_fix_favicon_reclassification.ts","doc":"Run once by runMigrations. It moves a faviconUrl back to thumbnailUrl only when 0011's rule takes it for an icon and this one doesn't. That also catches the ones a later fetch stored that this rule doesn't recognise, such as a logo.svg. It then moves the icons 0011 missed.","url":"./api/db/migrations/0012_fix_favicon_reclassification.ts/~/up.html","deprecated":false},{"id":"namespace_up","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"up","file":"api/db/migrations/0013_dump_url_canonical.ts","doc":"Run once by runMigrations. It fills only the keys still NULL, and leaves NULL a URL that isn't http(s).","url":"./api/db/migrations/0013_dump_url_canonical.ts/~/up.html","deprecated":false},{"id":"namespace_up","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"up","file":"api/db/migrations/0014_chat_read_state.ts","doc":"Run once by runMigrations. Existing users start with every message read, instead of the whole history unread. A user created later starts with a NULL chat_read_at, which chat-service reads as the user's creation time.","url":"./api/db/migrations/0014_chat_read_state.ts/~/up.html","deprecated":false},{"id":"namespace_up","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"up","file":"api/db/migrations/0015_token_revocation.ts","doc":"Run once by runMigrations. Existing users start with NULL, which revokes no token.","url":"./api/db/migrations/0015_token_revocation.ts/~/up.html","deprecated":false},{"id":"namespace_up","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"up","file":"api/db/migrations/0016_performance_indexes.ts","doc":"Run once by runMigrations. A database made from schema.sql already has these indexes.","url":"./api/db/migrations/0016_performance_indexes.ts/~/up.html","deprecated":false},{"id":"namespace_up","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"up","file":"api/db/migrations/0017_case_insensitive_users.ts","doc":"Run once by runMigrations. It refuses to run, naming the clashes, when two accounts already share a name or an address in some case: which one keeps it is for whoever runs the site to decide, by editing one of them.","url":"./api/db/migrations/0017_case_insensitive_users.ts/~/up.html","deprecated":false},{"id":"namespace_up","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"up","file":"api/db/migrations/0018_attachment_resource_type.ts","doc":"Run once by runMigrations. Existing bound attachments get the type of the table that holds their resource; one whose resource is gone gets none, and the startup purge deletes it. A database made from schema.sql already has the column.","url":"./api/db/migrations/0018_attachment_resource_type.ts/~/up.html","deprecated":false},{"id":"namespace_up","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"up","file":"api/db/migrations/0019_user_settings.ts","doc":"Run once by runMigrations. Existing users get no row, so they start with the defaults, digests on, like a new account.","url":"./api/db/migrations/0019_user_settings.ts/~/up.html","deprecated":false},{"id":"namespace_up","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"up","file":"api/db/migrations/0020_digest_schedule.ts","doc":"Run once by runMigrations. Every user present gets both cadences, with a first period that ends at some hour of the coming week or month, picked from their id: the digests start trickling out after the deploy instead of all leaving a week later. Users created later are scheduled by the service when it first sees them.","url":"./api/db/migrations/0020_digest_schedule.ts/~/up.html","deprecated":false},{"id":"namespace_up","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"up","file":"api/db/migrations/0021_page_urls.ts","doc":"Run once by runMigrations. On a database made from schema.sql the tables and indexes exist and there is nothing to re-slug or rewrite.","url":"./api/db/migrations/0021_page_urls.ts/~/up.html","deprecated":false},{"id":"namespace_up","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"up","file":"api/db/migrations/0022_reserve_community.ts","doc":"Run once by runMigrations.","url":"./api/db/migrations/0022_reserve_community.ts/~/up.html","deprecated":false},{"id":"namespace_up","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"up","file":"api/db/migrations/0023_mention_everyone.ts","doc":"Run once by runMigrations. The messages that a moderator or an admin already sent with @everyone get the flag, so that editing one later doesn't notify everyone of an old message; none is notified now. A user named everyone, in any case, is renamed to the first free everyone_2, everyone_3…, with no alias left behind, and an alias everyone is dropped. Both are logged.","url":"./api/db/migrations/0023_mention_everyone.ts/~/up.html","deprecated":false},{"id":"namespace_up","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"up","file":"api/db/migrations/0024_federation.ts","doc":"Run once by runMigrations. Nothing exists to convert, since every account so far is local, but authorize and federation become the pages of a sign-in, so a category that had one as its slug is renamed.","url":"./api/db/migrations/0024_federation.ts/~/up.html","deprecated":false},{"id":"namespace_up","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"up","file":"api/db/migrations/0025_playlist_categories.ts","doc":"Run once by runMigrations. Every existing category becomes a dump category, filing the same dumps.SQLite can't change a table's UNIQUE constraints in place, so categories is rebuilt. foreign_keys can't be switched off inside the runner's transaction, and dropping categories would then empty dump_categories through its cascade, so both are read, dropped child first, made anew as in schema.sql, and refilled. A database made from schema.sql already has the kind column and is left as it is.","url":"./api/db/migrations/0025_playlist_categories.ts/~/up.html","deprecated":false},{"id":"namespace_runstartuptasks","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"runStartupTasks","file":"api/db/startup.ts","doc":"Runs after the migrations, each time the server starts. It deletes used or expired reset tokens, invites past their validity, and attachments nothing links to or whose resource is gone. On an instance with no users, it creates the user admin with the password admin, which whoever installs it must change.","url":"./api/db/startup.ts/~/runStartupTasks.html","deprecated":false},{"id":"namespace_apistatus","kind":[{"char":"T","kind":"TypeAlias","title":"Type Alias"}],"name":"APIStatus","file":"api/lib/api-exception.ts","doc":"Passed to an APIException; any other status is a type error.","url":"./api/lib/api-exception.ts/~/APIStatus.html","deprecated":false},{"id":"namespace_apiexception","kind":[{"char":"c","kind":"Class","title":"Class"}],"name":"APIException","file":"api/lib/api-exception.ts","doc":"Thrown by a route, a service or a remote fetch to answer the request with an error. The error middleware sends it as an APIFailure, message included, so the message must be fit for the user. Use 401 for a caller who isn't signed in, 403 for one who is but may not, and 404 rather than 403 when the caller mustn't learn that the thing exists.","url":"./api/lib/api-exception.ts/~/APIException.html","deprecated":false},{"id":"namespace_apiexception","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"APIException.prototype.code","file":"api/lib/api-exception.ts","doc":"","url":"./api/lib/api-exception.ts/~/APIException.prototype.code.html","deprecated":false},{"id":"namespace_apiexception","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"APIException.prototype.status","file":"api/lib/api-exception.ts","doc":"","url":"./api/lib/api-exception.ts/~/APIException.prototype.status.html","deprecated":false},{"id":"namespace_authenticate","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"authenticate","file":"api/lib/auth.ts","doc":"Returns the payload of a valid session token, or null. Besides the signature and expiry, it refuses a token whose user is gone or which predates a password change. The returned role comes from the database, not the token, since a token lasts 7 days and a role can change under it.","url":"./api/lib/auth.ts/~/authenticate.html","deprecated":false},{"id":"namespace_authenticatemedia","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"authenticateMedia","file":"api/lib/auth.ts","doc":"Returns the user id behind the ?token= of a file, thumbnail or playlist cover URL, or null when it isn't valid. A session token is accepted too, for clients from before media tokens.","url":"./api/lib/auth.ts/~/authenticateMedia.html","deprecated":false},{"id":"namespace_parseoptionalauth","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"parseOptionalAuth","file":"api/lib/auth.ts","doc":"Returns the caller's user id on a route open to anonymous callers, or null when the request has no token. A placeholder such as Bearer undefined counts as no token. An invalid token throws instead of reading as anonymous, so that a stale session gets a 401 the client signs out on, rather than a misleading 404 on a private resource.","url":"./api/lib/auth.ts/~/parseOptionalAuth.html","deprecated":false},{"id":"namespace_youtubehost","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"youtubeHost","file":"api/lib/canonical-url.ts","doc":"Returns u's host in lower case and without \"www.\", when it is one of YouTube's (youtu.be aside), and null otherwise. The YouTube preview provider uses it too, so both agree on what a YouTube link is.","url":"./api/lib/canonical-url.ts/~/youtubeHost.html","deprecated":false},{"id":"namespace_youtubevideoid","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"youtubeVideoId","file":"api/lib/canonical-url.ts","doc":"Returns the id of the video a YouTube URL points at, in any of the shapes people paste (youtu.be/ID, /watch?v=ID, /embed/ID, /shorts/ID, /live/ID), and null for any other URL. host is lower case, without \"www.\". The canonical key drops the timestamp, since the same video linked at 2:30 is still a repost; the YouTube provider reads it separately.","url":"./api/lib/canonical-url.ts/~/youtubeVideoId.html","deprecated":false},{"id":"namespace_canonicalizeurl","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"canonicalizeUrl","file":"api/lib/canonical-url.ts","doc":"Returns the canonical key of raw, or null when it isn't an http(s) URL. A YouTube video or playlist becomes one fixed URL whatever shape it came in.","url":"./api/lib/canonical-url.ts/~/canonicalizeUrl.html","deprecated":false},{"id":"namespace_rgba","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"Rgba","file":"api/lib/css-color.ts","doc":"An sRGB color with its alpha, each channel 0–255 and alpha 0–1.","url":"./api/lib/css-color.ts/~/Rgba.html","deprecated":false},{"id":"namespace_rgba","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Rgba.r","file":"api/lib/css-color.ts","doc":"","url":"./api/lib/css-color.ts/~/Rgba.r.html","deprecated":false},{"id":"namespace_rgba","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Rgba.g","file":"api/lib/css-color.ts","doc":"","url":"./api/lib/css-color.ts/~/Rgba.g.html","deprecated":false},{"id":"namespace_rgba","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Rgba.b","file":"api/lib/css-color.ts","doc":"","url":"./api/lib/css-color.ts/~/Rgba.b.html","deprecated":false},{"id":"namespace_rgba","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Rgba.a","file":"api/lib/css-color.ts","doc":"","url":"./api/lib/css-color.ts/~/Rgba.a.html","deprecated":false},{"id":"namespace_parsecsscolor","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"parseCssColor","file":"api/lib/css-color.ts","doc":"Returns the color text writes as a hex (3, 4, 6 or 8 digits), an rgb() or rgba() of numbers or percentages, or one of the common names; undefined for any other form. Channels out of range are clamped.","url":"./api/lib/css-color.ts/~/parseCssColor.html","deprecated":false},{"id":"namespace_hexof","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"hexOf","file":"api/lib/css-color.ts","doc":"Writes color as a lowercase #rrggbb, its alpha dropped.","url":"./api/lib/css-color.ts/~/hexOf.html","deprecated":false},{"id":"namespace_resolvemediadump","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"resolveMediaDump","file":"api/lib/dump-media.ts","doc":"Returns dump dumpId as the viewer of ctx's ?token= may see it, and the Cache-Control its media get: kept for good under a URL naming the file's current version (?v=, as dumpFileVersion gives), revalidated under any other, and never in a shared cache for a private dump. It also keeps the token out of the Referer of whatever the response links to.","url":"./api/lib/dump-media.ts/~/resolveMediaDump.html","deprecated":false},{"id":"namespace_generatedpaths","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"generatedPaths","file":"api/lib/ffmpeg.ts","doc":"Returns where the still and the waveform generated from dump dumpId's upload are kept.","url":"./api/lib/ffmpeg.ts/~/generatedPaths.html","deprecated":false},{"id":"namespace_scaledformat","kind":[{"char":"T","kind":"TypeAlias","title":"Type Alias"}],"name":"ScaledFormat","file":"api/lib/ffmpeg.ts","doc":"The formats a scaled copy comes in: WebP for a browser, and a JPEG or a PNG for what doesn't read it, as some mail clients don't.","url":"./api/lib/ffmpeg.ts/~/ScaledFormat.html","deprecated":false},{"id":"namespace_scaledimagepath","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"scaledImagePath","file":"api/lib/ffmpeg.ts","doc":"Returns where the copy of the upload at srcPath scaled to width is kept, in format: under SCALED_DIR, at the upload's own path below UPLOADS_DIR.","url":"./api/lib/ffmpeg.ts/~/scaledImagePath.html","deprecated":false},{"id":"namespace_removescaledimages","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"removeScaledImages","file":"api/lib/ffmpeg.ts","doc":"Deletes the scaled copies of the upload at srcPath, once it is deleted. One that is replaced needs no call: its copies are made again, being older than it (ensureGenerated).","url":"./api/lib/ffmpeg.ts/~/removeScaledImages.html","deprecated":false},{"id":"namespace_removegeneratedmedia","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"removeGeneratedMedia","file":"api/lib/ffmpeg.ts","doc":"Deletes what was generated from dump dumpId's upload, once dump-service has replaced or deleted it. The routes make them again from a new one.","url":"./api/lib/ffmpeg.ts/~/removeGeneratedMedia.html","deprecated":false},{"id":"namespace_videostill","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"videoStill","file":"api/lib/ffmpeg.ts","doc":"Writes a 320-pixel-wide JPEG still of a video, one second in.","url":"./api/lib/ffmpeg.ts/~/videoStill.html","deprecated":false},{"id":"namespace_imagetraits","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"ImageTraits","file":"api/lib/ffmpeg.ts","doc":"What scaleImage is told of the image it scales, which scalableImage (lib/upload.ts) reads from its first bytes.","url":"./api/lib/ffmpeg.ts/~/ImageTraits.html","deprecated":false},{"id":"namespace_imagetraits","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ImageTraits.orientation","file":"api/lib/ffmpeg.ts","doc":"The EXIF orientation to turn the image by, 1 when it is upright.","url":"./api/lib/ffmpeg.ts/~/ImageTraits.orientation.html","deprecated":false},{"id":"namespace_imagetraits","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ImageTraits.animated","file":"api/lib/ffmpeg.ts","doc":"Whether its frames are an animation, as a GIF's are. A still may hold more than one image too, a phone's JPEG carrying a gain map or a depth map after the photo, and ffmpeg reads each as a frame.","url":"./api/lib/ffmpeg.ts/~/ImageTraits.animated.html","deprecated":false},{"id":"namespace_scaleimage","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"scaleImage","file":"api/lib/ffmpeg.ts","doc":"Writes a copy of an image at most width wide, never wider than the image itself, as a WebP unless format names another. WebP keeps a PNG's transparency and a GIF's animation, at a fraction of either's bytes.","url":"./api/lib/ffmpeg.ts/~/scaleImage.html","deprecated":false},{"id":"namespace_scaleimagebytes","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"scaleImageBytes","file":"api/lib/ffmpeg.ts","doc":"Returns bytes, an image held in memory, scaled as scaleImage does, or null when it can't be, because ffmpeg is missing or failed. The image proxy scales what it fetched with it, and keeps the result itself.","url":"./api/lib/ffmpeg.ts/~/scaleImageBytes.html","deprecated":false},{"id":"namespace_audiowaveform","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"audioWaveform","file":"api/lib/ffmpeg.ts","doc":"Writes the waveform of the audio file srcPath as the waveform route's whole response, so the route serves it as a file, with its ETag.","url":"./api/lib/ffmpeg.ts/~/audioWaveform.html","deprecated":false},{"id":"namespace_ensuregenerated","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"ensureGenerated","file":"api/lib/ffmpeg.ts","doc":"Makes outPath with generate unless it exists. Resolves false when it can't be made, because ffmpeg is missing or failed.With srcPath, the file it is made from, outPath takes that file's date, and is made again when the two differ: an upload replaced in place, as an avatar or a cover is, gets new copies without anyone deleting the old. Without it, the caller deletes outPath when its source changes.","url":"./api/lib/ffmpeg.ts/~/ensureGenerated.html","deprecated":false},{"id":"namespace_sweepgeneratedmedia","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"sweepGeneratedMedia","file":"api/lib/ffmpeg.ts","doc":"Deletes the generated files nothing serves any more, and returns how many: the scaled copies of an upload that is gone, which the services' own removals missed or never made, as for a user's avatar; the previews of image dumps under their former name, .preview.jpg or .png, which the scaled copies replaced; and the temporary files a generation left unfinished. Nothing else of THUMBNAILS_DIR is touched, the custom thumbnails kept there being uploads.","url":"./api/lib/ffmpeg.ts/~/sweepGeneratedMedia.html","deprecated":false},{"id":"namespace_generatedmediasweepjob","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"generatedMediaSweepJob","file":"api/lib/ffmpeg.ts","doc":"Runs sweepGeneratedMedia a minute after the server starts, which clears what a new version no longer uses as soon as it is deployed, then once a day. main.ts starts it.","url":"./api/lib/ffmpeg.ts/~/generatedMediaSweepJob.html","deprecated":false},{"id":"namespace_loadindexhtml","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"loadIndexHtml","file":"api/lib/index-html.ts","doc":"Returns ${root}/index.html with the site name, emoji, icon version, Bandcamp player mode, default style, and whether email and each way of federated sign-in are on filled in.","url":"./api/lib/index-html.ts/~/loadIndexHtml.html","deprecated":false},{"id":"namespace_createpasswordresettoken","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"createPasswordResetToken","file":"api/lib/jwt.ts","doc":"Signs a password reset token for userId, valid for an hour. The token isn't single-use by itself: requestPasswordReset stores it, and resetPassword marks it used.","url":"./api/lib/jwt.ts/~/createPasswordResetToken.html","deprecated":false},{"id":"namespace_verifypasswordresettoken","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"verifyPasswordResetToken","file":"api/lib/jwt.ts","doc":"Returns the payload of a password reset token, or null when it is invalid, expired or another kind of token. Whether it was used is the caller's check.","url":"./api/lib/jwt.ts/~/verifyPasswordResetToken.html","deprecated":false},{"id":"namespace_createjwt","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"createJWT","file":"api/lib/jwt.ts","doc":"Signs a session token carrying payload, valid for 7 days. issueTokens issues it on sign-up, sign-in and password change, and the client sends it as a bearer token.","url":"./api/lib/jwt.ts/~/createJWT.html","deprecated":false},{"id":"namespace_issuetokens","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"issueTokens","file":"api/lib/jwt.ts","doc":"Returns a new session token and media token for user, as sign-up (POST /api/users), sign-in (POST /api/sessions) and a password change (PUT /api/me/password) answer them.","url":"./api/lib/jwt.ts/~/issueTokens.html","deprecated":false},{"id":"namespace_createmediatoken","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"createMediaToken","file":"api/lib/jwt.ts","doc":"Signs a media token for userId, valid for 7 days. Media elements can't send an Authorization header, so the URLs of private files, thumbnails and playlist covers carry this token as ?token=, where it lands in logs and browser history. It only reads media, so a leaked URL doesn't expose the account.","url":"./api/lib/jwt.ts/~/createMediaToken.html","deprecated":false},{"id":"namespace_verifymediatoken","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"verifyMediaToken","file":"api/lib/jwt.ts","doc":"Returns the user id and issue time of a media token, or null when it is invalid, expired or another kind of token.","url":"./api/lib/jwt.ts/~/verifyMediaToken.html","deprecated":false},{"id":"namespace_verifyjwt","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"verifyJWT","file":"api/lib/jwt.ts","doc":"Returns the payload of a session token whose signature and expiry are valid, or null. Call authenticate (lib/auth.ts) instead, which also checks the token against its user.","url":"./api/lib/jwt.ts/~/verifyJWT.html","deprecated":false},{"id":"namespace_createunsubscribetoken","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"createUnsubscribeToken","file":"api/lib/jwt.ts","doc":"Signs the token of a digest's unsubscribe link, which turns off cadence for userId without signing in. It never expires, so the link in an old email still works; turning the digest back on doesn't revoke it, which is harmless since all it can do is turn it off again.","url":"./api/lib/jwt.ts/~/createUnsubscribeToken.html","deprecated":false},{"id":"namespace_verifyunsubscribetoken","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"verifyUnsubscribeToken","file":"api/lib/jwt.ts","doc":"Returns the user and cadence of an unsubscribe token, or null when it is invalid or another kind of token.","url":"./api/lib/jwt.ts/~/verifyUnsubscribeToken.html","deprecated":false},{"id":"namespace_instancesigningkey","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"InstanceSigningKey","file":"api/lib/jwt.ts","doc":"An instance's key, ready to sign, from importInstanceKey. Its kid names the public half in the instance's JWKS.","url":"./api/lib/jwt.ts/~/InstanceSigningKey.html","deprecated":false},{"id":"namespace_instancesigningkey","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"InstanceSigningKey.kid","file":"api/lib/jwt.ts","doc":"","url":"./api/lib/jwt.ts/~/InstanceSigningKey.kid.html","deprecated":false},{"id":"namespace_instancesigningkey","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"InstanceSigningKey.privateKey","file":"api/lib/jwt.ts","doc":"","url":"./api/lib/jwt.ts/~/InstanceSigningKey.privateKey.html","deprecated":false},{"id":"namespace_generateinstancekey","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"generateInstanceKey","file":"api/lib/jwt.ts","doc":"Returns a new Ed25519 key pair as JWKs, with a random kid, for instance-key-service.ts to store when the instance has none. The public JWK carries the kid, alg and use a JWKS entry needs.","url":"./api/lib/jwt.ts/~/generateInstanceKey.html","deprecated":false},{"id":"namespace_importinstancekey","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"importInstanceKey","file":"api/lib/jwt.ts","doc":"Returns the stored private JWK privateJwk as a key to sign with.","url":"./api/lib/jwt.ts/~/importInstanceKey.html","deprecated":false},{"id":"namespace_signinstancetoken","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"signInstanceToken","file":"api/lib/jwt.ts","doc":"Signs payload with the instance's key, from issuer (this instance) to audience (the instance it is for), valid for expiresIn, with a random jti. The identity tokens of POST /api/oauth/tokens and the events of the outbox are signed with it.","url":"./api/lib/jwt.ts/~/signInstanceToken.html","deprecated":false},{"id":"namespace_verifyinstancetoken","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"verifyInstanceToken","file":"api/lib/jwt.ts","doc":"Returns the payload of token once its signature checks against jwks, the keys of issuer, and it is addressed to audience and unexpired.","url":"./api/lib/jwt.ts/~/verifyInstanceToken.html","deprecated":false},{"id":"namespace_likepattern","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"likePattern","file":"api/lib/like.ts","doc":"Returns the pattern matching text that contains query, or that starts with it when where is \"prefix\". The SQL must read LIKE ? ESCAPE '\\', which the LIKE fragment spells.","url":"./api/lib/like.ts/~/likePattern.html","deprecated":false},{"id":"namespace_like","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"LIKE","file":"api/lib/like.ts","doc":"Spells LIKE ? ESCAPE '\\', for a likePattern parameter.","url":"./api/lib/like.ts/~/LIKE.html","deprecated":false},{"id":"namespace_parsepagination","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"parsePagination","file":"api/lib/pagination.ts","doc":"Reads the page and limit query parameters of a list route. It never fails: a missing or invalid page reads as 1, and limit is kept between 1 and PAGINATION_MAX_LIMIT.","url":"./api/lib/pagination.ts/~/parsePagination.html","deprecated":false},{"id":"namespace_page","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"Page","file":"api/lib/pagination.ts","doc":"Returned to the routes by the services' list functions, and sent as PaginatedData.","url":"./api/lib/pagination.ts/~/Page.html","deprecated":false},{"id":"namespace_page","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Page.items","file":"api/lib/pagination.ts","doc":"","url":"./api/lib/pagination.ts/~/Page.items.html","deprecated":false},{"id":"namespace_page","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Page.hasMore","file":"api/lib/pagination.ts","doc":"","url":"./api/lib/pagination.ts/~/Page.hasMore.html","deprecated":false},{"id":"namespace_pageof","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"pageOf","file":"api/lib/pagination.ts","doc":"Turns rows fetched with LIMIT limit + 1 into a page. The extra row, when it comes back, is dropped and tells that another page follows, which spares a COUNT(*) over the whole list.","url":"./api/lib/pagination.ts/~/pageOf.html","deprecated":false},{"id":"namespace_hashpassword","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"hashPassword","file":"api/lib/password.ts","doc":"Hashes password with scrypt and a random salt, as hash.salt in hex, for users.password_hash.","url":"./api/lib/password.ts/~/hashPassword.html","deprecated":false},{"id":"namespace_verifypassword","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"verifyPassword","file":"api/lib/password.ts","doc":"Checks password against a hash made by hashPassword.","url":"./api/lib/password.ts/~/verifyPassword.html","deprecated":false},{"id":"namespace_can","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"can","file":"api/lib/permissions.ts","doc":"Checks whether the caller's role grants permission. The role is the live one authenticate put in the payload, not the token's.","url":"./api/lib/permissions.ts/~/can.html","deprecated":false},{"id":"namespace_playlistmember","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"PlaylistMember","file":"api/lib/playlist-members.ts","doc":"The fields of a playlist's dump that isMemberVisibleTo needs. A Dump has them. For its broadcasts, the playlist service reads only these.","url":"./api/lib/playlist-members.ts/~/PlaylistMember.html","deprecated":false},{"id":"namespace_playlistmember","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PlaylistMember.id","file":"api/lib/playlist-members.ts","doc":"","url":"./api/lib/playlist-members.ts/~/PlaylistMember.id.html","deprecated":false},{"id":"namespace_playlistmember","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PlaylistMember.isPrivate","file":"api/lib/playlist-members.ts","doc":"","url":"./api/lib/playlist-members.ts/~/PlaylistMember.isPrivate.html","deprecated":false},{"id":"namespace_playlistmember","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PlaylistMember.userId","file":"api/lib/playlist-members.ts","doc":"The dump's poster, not the playlist's owner.","url":"./api/lib/playlist-members.ts/~/PlaylistMember.userId.html","deprecated":false},{"id":"namespace_ismembervisibleto","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"isMemberVisibleTo","file":"api/lib/playlist-members.ts","doc":"Checks whether viewerId may see member in playlist. A public dump is visible to all. A private dump is visible only to the playlist's owner, and only if they posted it: moderators don't see it, and neither does the owner once someone else's dump in their playlist goes private. A null or undefined viewerId is a signed-out viewer.","url":"./api/lib/playlist-members.ts/~/isMemberVisibleTo.html","deprecated":false},{"id":"namespace_datedplaylistmember","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"DatedPlaylistMember","file":"api/lib/playlist-members.ts","doc":"The fields of a playlist's dump that dumpFiguresFor needs: those that tell who may see it, and when it was added. The playlist service reads them for its broadcasts.","url":"./api/lib/playlist-members.ts/~/DatedPlaylistMember.html","deprecated":false},{"id":"namespace_datedplaylistmember","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DatedPlaylistMember.addedAt","file":"api/lib/playlist-members.ts","doc":"","url":"./api/lib/playlist-members.ts/~/DatedPlaylistMember.addedAt.html","deprecated":false},{"id":"namespace_visible_dump_figures","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"VISIBLE_DUMP_FIGURES","file":"api/lib/playlist-members.ts","doc":"The dump_count and last_dump_at columns of a query on playlists p: how many of the playlist's dumps the viewer may see, by isMemberVisibleTo's rule, and when the latest of them was added, null without any. Both read the viewer's id, or \"\" for a signed-out one, as ?1: it is the query's first parameter, and each ? after it takes the next.","url":"./api/lib/playlist-members.ts/~/VISIBLE_DUMP_FIGURES.html","deprecated":false},{"id":"namespace_dumpfiguresfor","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"dumpFiguresFor","file":"api/lib/playlist-members.ts","doc":"Returns what playlist says of its dumps to the viewer, members being all of them: the dumpCount and lastDumpAt that VISIBLE_DUMP_FIGURES reads in a query. The WebSocket service puts them on the playlist each socket is sent.","url":"./api/lib/playlist-members.ts/~/dumpFiguresFor.html","deprecated":false},{"id":"namespace_ratelimit","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"RateLimit","file":"api/lib/rate-limit.ts","doc":"Passed to takeToken by each limited action, which declares its own as a constant.","url":"./api/lib/rate-limit.ts/~/RateLimit.html","deprecated":false},{"id":"namespace_ratelimit","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"RateLimit.capacity","file":"api/lib/rate-limit.ts","doc":"How many tokens a full bucket holds, and so the largest burst.","url":"./api/lib/rate-limit.ts/~/RateLimit.capacity.html","deprecated":false},{"id":"namespace_ratelimit","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"RateLimit.refill","file":"api/lib/rate-limit.ts","doc":"Tokens regained per second.","url":"./api/lib/rate-limit.ts/~/RateLimit.refill.html","deprecated":false},{"id":"namespace_taketoken","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"takeToken","file":"api/lib/rate-limit.ts","doc":"Takes one token from key's bucket, or returns false when it is empty. The caller picks the key, such as typing:, and keys by user or account so that more tabs or parallel requests don't buy more tokens.","url":"./api/lib/rate-limit.ts/~/takeToken.html","deprecated":false},{"id":"namespace_ratelimitsweepjob","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"rateLimitSweepJob","file":"api/lib/rate-limit.ts","doc":"Drops the buckets untouched for an hour, every minute. Every limit in use refills within the hour, so such a bucket is full and dropping it changes nothing. main.ts starts it.","url":"./api/lib/rate-limit.ts/~/rateLimitSweepJob.html","deprecated":false},{"id":"namespace_reserved_slugs","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"RESERVED_SLUGS","file":"api/lib/reserved-slugs.ts","doc":"Lists the top-level path segments a category slug may not take: the feed tabs (/hot), the SPA's own pages (src/App.tsx), and api, ws, assets and emojibase, which the server answers before the SPA. Keep it in step with the route table and the build's top-level folders.","url":"./api/lib/reserved-slugs.ts/~/RESERVED_SLUGS.html","deprecated":false},{"id":"namespace_isreservedslug","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"isReservedSlug","file":"api/lib/reserved-slugs.ts","doc":"Checks whether slug is one of the RESERVED_SLUGS.","url":"./api/lib/reserved-slugs.ts/~/isReservedSlug.html","deprecated":false},{"id":"namespace_renamereservedcategories","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"renameReservedCategories","file":"api/lib/reserved-slugs.ts","doc":"Renames each category whose slug is now reserved, such as hot, to the first of -2, -3… that is free, and logs it. Migration 0021 runs it for v4's words, 0022 for community, 0024 for authorize and federation, and 0025 for playlists.It reads every category: until 0025 gave categories a kind, each was a dump category, and 0025 makes no other. A later migration that reserves more words must leave the playlist categories alone, and limit it to kind = 'dump', which the earlier ones can't, having no such column.","url":"./api/lib/reserved-slugs.ts/~/renameReservedCategories.html","deprecated":false},{"id":"namespace_job","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"Job","file":"api/lib/scheduler.ts","doc":"A recurring task, exported by its module for main.ts to start.","url":"./api/lib/scheduler.ts/~/Job.html","deprecated":false},{"id":"namespace_job","kind":[{"char":"m","kind":"Method","title":"Method"}],"name":"Job.run","file":"api/lib/scheduler.ts","doc":"Logs what it did itself, if anything; its errors are logged here.","url":"./api/lib/scheduler.ts/~/Job.run.html","deprecated":false},{"id":"namespace_job","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Job.name","file":"api/lib/scheduler.ts","doc":"Names it in the log, as [digest].","url":"./api/lib/scheduler.ts/~/Job.name.html","deprecated":false},{"id":"namespace_job","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Job.everyMs","file":"api/lib/scheduler.ts","doc":"How long from one run's start to the next.","url":"./api/lib/scheduler.ts/~/Job.everyMs.html","deprecated":false},{"id":"namespace_job","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Job.firstAfterMs","file":"api/lib/scheduler.ts","doc":"How long after the start the first run waits, everyMs by default.","url":"./api/lib/scheduler.ts/~/Job.firstAfterMs.html","deprecated":false},{"id":"namespace_startjobs","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"startJobs","file":"api/lib/scheduler.ts","doc":"Starts running each of jobs on its own timer. A run still going when the next is due makes that one skip, and a run that throws or rejects is logged and the next one runs anyway.","url":"./api/lib/scheduler.ts/~/startJobs.html","deprecated":false},{"id":"namespace_isselfhost","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"isSelfHost","file":"api/lib/self-url.ts","doc":"Checks whether host (with its port, as URL.host gives it) is where this site is served, at its public URL or its frontend's.","url":"./api/lib/self-url.ts/~/isSelfHost.html","deprecated":false},{"id":"namespace_isselfurl","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"isSelfUrl","file":"api/lib/self-url.ts","doc":"Checks whether url links to one of this site's own dump, user or playlist pages, by parsePagePath; an editor doesn't count. Matched on the host as well as the path: /@bob on some other site is someone else's page, not ours.","url":"./api/lib/self-url.ts/~/isSelfUrl.html","deprecated":false},{"id":"namespace_servefileoptions","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"ServeFileOptions","file":"api/lib/serve-file.ts","doc":"Passed to serveFile by its caller, which knows the file's type and how long it may be cached.","url":"./api/lib/serve-file.ts/~/ServeFileOptions.html","deprecated":false},{"id":"namespace_servefileoptions","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ServeFileOptions.mime","file":"api/lib/serve-file.ts","doc":"","url":"./api/lib/serve-file.ts/~/ServeFileOptions.mime.html","deprecated":false},{"id":"namespace_servefileoptions","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ServeFileOptions.cacheControl","file":"api/lib/serve-file.ts","doc":"","url":"./api/lib/serve-file.ts/~/ServeFileOptions.cacheControl.html","deprecated":false},{"id":"namespace_servefileoptions","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ServeFileOptions.ranges","file":"api/lib/serve-file.ts","doc":"Answers a single Range: bytes=… with a 206. The files route sets it, so that audio and video can seek.","url":"./api/lib/serve-file.ts/~/ServeFileOptions.ranges.html","deprecated":false},{"id":"namespace_servefile","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"serveFile","file":"api/lib/serve-file.ts","doc":"Sends a file from disk with an ETag, answering 304 when the client already has it, and single byte ranges when ranges is set. It returns false, having sent nothing, when the file doesn't exist, and leaves the 404 to the caller.","url":"./api/lib/serve-file.ts/~/serveFile.html","deprecated":false},{"id":"namespace_emojitocodepoint","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"emojiToCodepoint","file":"api/lib/site-icons.ts","doc":"Returns the name Twemoji files emoji under: its codepoints in hex, joined with \"-\", without variation selectors (FE0F) unless the emoji is a ZWJ sequence. lib/index-html.ts also uses it as the icon URLs' cache-busting version.","url":"./api/lib/site-icons.ts/~/emojiToCodepoint.html","deprecated":false},{"id":"namespace_generatesiteiconsoptions","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"GenerateSiteIconsOptions","file":"api/lib/site-icons.ts","doc":"Passed to generateSiteIcons by api/scripts/generate-icons.ts, from the site's config.","url":"./api/lib/site-icons.ts/~/GenerateSiteIconsOptions.html","deprecated":false},{"id":"namespace_generatesiteiconsoptions","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"GenerateSiteIconsOptions.emoji","file":"api/lib/site-icons.ts","doc":"","url":"./api/lib/site-icons.ts/~/GenerateSiteIconsOptions.emoji.html","deprecated":false},{"id":"namespace_generatesiteiconsoptions","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"GenerateSiteIconsOptions.outDir","file":"api/lib/site-icons.ts","doc":"Created if missing.","url":"./api/lib/site-icons.ts/~/GenerateSiteIconsOptions.outDir.html","deprecated":false},{"id":"namespace_generatesiteiconsoptions","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"GenerateSiteIconsOptions.siteName","file":"api/lib/site-icons.ts","doc":"","url":"./api/lib/site-icons.ts/~/GenerateSiteIconsOptions.siteName.html","deprecated":false},{"id":"namespace_generatesiteiconsoptions","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"GenerateSiteIconsOptions.bgColor","file":"api/lib/site-icons.ts","doc":"Fills the Apple touch icon, and the manifest's theme and background.","url":"./api/lib/site-icons.ts/~/GenerateSiteIconsOptions.bgColor.html","deprecated":false},{"id":"namespace_generatesiteicons","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"generateSiteIcons","file":"api/lib/site-icons.ts","doc":"Writes favicon.svg, favicon.ico, favicon-x.png (16 to 512), apple-touch-icon.png and manifest.webmanifest into opts.outDir, the directory the site's static files are served from.","url":"./api/lib/site-icons.ts/~/generateSiteIcons.html","deprecated":false},{"id":"namespace_slugkind","kind":[{"char":"T","kind":"TypeAlias","title":"Type Alias"}],"name":"SlugKind","file":"api/lib/slugify.ts","doc":"A kind of item that has a slug under its owner.","url":"./api/lib/slugify.ts/~/SlugKind.html","deprecated":false},{"id":"namespace_slug_tables","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"SLUG_TABLES","file":"api/lib/slugify.ts","doc":"Where each SlugKind's slugs live.","url":"./api/lib/slugify.ts/~/SLUG_TABLES.html","deprecated":false},{"id":"namespace_slugholder","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"slugHolder","file":"api/lib/slugify.ts","doc":"Returns the id of the item whose current slug or alias is slug in userId's space for kind, or undefined when it is free.","url":"./api/lib/slugify.ts/~/slugHolder.html","deprecated":false},{"id":"namespace_uniqueslug","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"uniqueSlug","file":"api/lib/slugify.ts","doc":"Returns base, or base-2, base-3… cut to fit, whichever is free in userId's space for kind. base must be a valid slug, as slugify makes. The services take it on creating an item, the migration on re-slugging one, inside the transaction that writes it.","url":"./api/lib/slugify.ts/~/uniqueSlug.html","deprecated":false},{"id":"namespace_validateslug","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"validateSlug","file":"api/lib/slugify.ts","doc":"Throws a 400 unless slug is a valid slug, lowercase words of letters and digits joined by hyphens, at most max long. slug-service checks a dump's or a playlist's with it, and category-service a category's, with that kind's own limit.","url":"./api/lib/slugify.ts/~/validateSlug.html","deprecated":false},{"id":"namespace_routestaticfilesfrom","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"routeStaticFilesFrom","file":"api/lib/static.ts","doc":"Returns the middleware that serves a static file from the first of staticPaths that has it, and index.html of the first for any other path. Hashed build output is cached for a year, and a missing chunk is a 404. main.ts passes dist/ then public/.","url":"./api/lib/static.ts/~/routeStaticFilesFrom.html","deprecated":false},{"id":"namespace_ttlcache","kind":[{"char":"c","kind":"Class","title":"Class"}],"name":"TtlCache","file":"api/lib/ttl-cache.ts","doc":"A map whose entries expire ttlMs after they are written, holding maxEntries at most.","url":"./api/lib/ttl-cache.ts/~/TtlCache.html","deprecated":false},{"id":"namespace_ttlcache","kind":[{"char":"m","kind":"Method","title":"Method"}],"name":"TtlCache.prototype.get","file":"api/lib/ttl-cache.ts","doc":"Returns the value under key unless it is missing or expired.","url":"./api/lib/ttl-cache.ts/~/TtlCache.prototype.get.html","deprecated":false},{"id":"namespace_ttlcache","kind":[{"char":"m","kind":"Method","title":"Method"}],"name":"TtlCache.prototype.set","file":"api/lib/ttl-cache.ts","doc":"Stores value under key from now on, and returns it.","url":"./api/lib/ttl-cache.ts/~/TtlCache.prototype.set.html","deprecated":false},{"id":"namespace_ttlcache","kind":[{"char":"m","kind":"Method","title":"Method"}],"name":"TtlCache.prototype.delete","file":"api/lib/ttl-cache.ts","doc":"Removes key, or only when value is still what it holds, so a late failure can't remove the entry that replaced its own.","url":"./api/lib/ttl-cache.ts/~/TtlCache.prototype.delete.html","deprecated":false},{"id":"namespace_ttlcache","kind":[{"char":"m","kind":"Method","title":"Method"}],"name":"TtlCache.prototype.clear","file":"api/lib/ttl-cache.ts","doc":"Empties the cache, for the tests' reset between cases.","url":"./api/lib/ttl-cache.ts/~/TtlCache.prototype.clear.html","deprecated":false},{"id":"namespace_detectimagemime","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"detectImageMime","file":"api/lib/upload.ts","doc":"Returns the MIME type of a JPEG, PNG, GIF or WebP image from its magic bytes, or null for anything else. These four are the only image types accepted anywhere. The type the browser declared is never trusted, since the file is later served with the type found here.","url":"./api/lib/upload.ts/~/detectImageMime.html","deprecated":false},{"id":"namespace_validateimageupload","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"validateImageUpload","file":"api/lib/upload.ts","doc":"Checks an uploaded image's size and content, and returns its MIME type, which the route stores to serve the image with.","url":"./api/lib/upload.ts/~/validateImageUpload.html","deprecated":false},{"id":"namespace_scalableimage","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"ScalableImage","file":"api/lib/upload.ts","doc":"Returned by scalableImage, for scaleImage.","url":"./api/lib/upload.ts/~/ScalableImage.html","deprecated":false},{"id":"namespace_scalableimage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ScalableImage.compat","file":"api/lib/upload.ts","doc":"The format of its copy for a reader without WebP: a JPEG, or a PNG for an image that may be transparent, which a JPEG would fill with black.","url":"./api/lib/upload.ts/~/ScalableImage.compat.html","deprecated":false},{"id":"namespace_scalableimage","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"scalableImage","file":"api/lib/upload.ts","doc":"Returns how to scale the image whose first IMAGE_HEAD_BYTES are head, or null when it is to be served as it is: an animated WebP, which ffmpeg can't read, or anything but a JPEG, PNG, GIF, WebP or BMP.","url":"./api/lib/upload.ts/~/scalableImage.html","deprecated":false},{"id":"namespace_serveimage","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"serveImage","file":"api/lib/upload.ts","doc":"Sends the image at path, of type mime, with cacheControl: a WebP copy at most as wide as the request's ?w= names (shared/image.ts), or as defaultWidth without one, and the image as it is when the request names no width or the copy can't be made. With ?f=compat, the copy is a JPEG, or a PNG for an image that may be transparent, which the digest's emails ask for, since not every mail client reads WebP. Every route that answers one of the site's own images ends here, so each takes both. It resolves false, having sent nothing, when the file is missing.","url":"./api/lib/upload.ts/~/serveImage.html","deprecated":false},{"id":"namespace_serveuploadedfile","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"serveUploadedFile","file":"api/lib/upload.ts","doc":"Serves an uploaded image inline as mime, or scaled down as serveImage does, cached for cacheMaxAge seconds, and only by the browser when isPrivate. It answers 404 and resolves false when the file is missing. The caller checks first that the viewer may see it.","url":"./api/lib/upload.ts/~/serveUploadedFile.html","deprecated":false},{"id":"namespace_replaceuploadedfile","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"replaceUploadedFile","file":"api/lib/upload.ts","doc":"Writes data to filePath, replacing whatever is there only once the whole file is written, so a failed write leaves the old file whole. The upload routes call it before recording the new file, so that clients told of it never fetch it early.","url":"./api/lib/upload.ts/~/replaceUploadedFile.html","deprecated":false},{"id":"namespace_activitykind","kind":[{"char":"T","kind":"TypeAlias","title":"Type Alias"}],"name":"ActivityKind","file":"api/mail/digest.ts","doc":"The kinds of activity a weekly digest counts.","url":"./api/mail/digest.ts/~/ActivityKind.html","deprecated":false},{"id":"namespace_highlightkind","kind":[{"char":"T","kind":"TypeAlias","title":"Type Alias"}],"name":"HighlightKind","file":"api/mail/digest.ts","doc":"What a highlight of the weekly digest says happened.","url":"./api/mail/digest.ts/~/HighlightKind.html","deprecated":false},{"id":"namespace_digestdump","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"DigestDump","file":"api/mail/digest.ts","doc":"A dump in a digest's lists, with its links made absolute.","url":"./api/mail/digest.ts/~/DigestDump.html","deprecated":false},{"id":"namespace_digestdump","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DigestDump.title","file":"api/mail/digest.ts","doc":"","url":"./api/mail/digest.ts/~/DigestDump.title.html","deprecated":false},{"id":"namespace_digestdump","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DigestDump.url","file":"api/mail/digest.ts","doc":"","url":"./api/mail/digest.ts/~/DigestDump.url.html","deprecated":false},{"id":"namespace_digestdump","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DigestDump.poster","file":"api/mail/digest.ts","doc":"","url":"./api/mail/digest.ts/~/DigestDump.poster.html","deprecated":false},{"id":"namespace_digestdump","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DigestDump.domain","file":"api/mail/digest.ts","doc":"The link's host, or null for an upload.","url":"./api/mail/digest.ts/~/DigestDump.domain.html","deprecated":false},{"id":"namespace_digestdump","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DigestDump.thumbnail","file":"api/mail/digest.ts","doc":"An absolute image URL, or null to show no image.","url":"./api/mail/digest.ts/~/DigestDump.thumbnail.html","deprecated":false},{"id":"namespace_digestdump","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DigestDump.votes","file":"api/mail/digest.ts","doc":"","url":"./api/mail/digest.ts/~/DigestDump.votes.html","deprecated":false},{"id":"namespace_digestdump","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DigestDump.comments","file":"api/mail/digest.ts","doc":"","url":"./api/mail/digest.ts/~/DigestDump.comments.html","deprecated":false},{"id":"namespace_digestdump","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DigestDump.mine","file":"api/mail/digest.ts","doc":"Posted by the reader, which the lists mark.","url":"./api/mail/digest.ts/~/DigestDump.mine.html","deprecated":false},{"id":"namespace_digestdump","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DigestDump.addedTo","file":"api/mail/digest.ts","doc":"The followed playlist it was added to, when that's why it's listed.","url":"./api/mail/digest.ts/~/DigestDump.addedTo.html","deprecated":false},{"id":"namespace_digesthighlight","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"DigestHighlight","file":"api/mail/digest.ts","doc":"One line of the weekly digest's \"For you\", made from a notification.","url":"./api/mail/digest.ts/~/DigestHighlight.html","deprecated":false},{"id":"namespace_digesthighlight","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DigestHighlight.kind","file":"api/mail/digest.ts","doc":"","url":"./api/mail/digest.ts/~/DigestHighlight.kind.html","deprecated":false},{"id":"namespace_digesthighlight","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DigestHighlight.who","file":"api/mail/digest.ts","doc":"Who did it.","url":"./api/mail/digest.ts/~/DigestHighlight.who.html","deprecated":false},{"id":"namespace_digesthighlight","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DigestHighlight.target","file":"api/mail/digest.ts","doc":"What they did it on, absent for a follow of the reader or the chat. Its url is null once it is deleted, and the title then shows unlinked.","url":"./api/mail/digest.ts/~/DigestHighlight.target.html","deprecated":false},{"id":"namespace_digesthighlight","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DigestHighlight.target.title","file":"api/mail/digest.ts","doc":"","url":"./api/mail/digest.ts/~/DigestHighlight.target.title.html","deprecated":false},{"id":"namespace_digesthighlight","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DigestHighlight.target.url","file":"api/mail/digest.ts","doc":"","url":"./api/mail/digest.ts/~/DigestHighlight.target.url.html","deprecated":false},{"id":"namespace_digesthighlight","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DigestHighlight.quote","file":"api/mail/digest.ts","doc":"The comment or message, flattened and shortened.","url":"./api/mail/digest.ts/~/DigestHighlight.quote.html","deprecated":false},{"id":"namespace_digesthighlight","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DigestHighlight.at","file":"api/mail/digest.ts","doc":"","url":"./api/mail/digest.ts/~/DigestHighlight.at.html","deprecated":false},{"id":"namespace_digestcontent","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"DigestContent","file":"api/mail/digest.ts","doc":"Passed to renderDigestEmail by digest-service.ts. Each section is null when it has nothing to show, and is left out; the service sends nothing when all of them are.","url":"./api/mail/digest.ts/~/DigestContent.html","deprecated":false},{"id":"namespace_digestcontent","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DigestContent.cadence","file":"api/mail/digest.ts","doc":"","url":"./api/mail/digest.ts/~/DigestContent.cadence.html","deprecated":false},{"id":"namespace_digestcontent","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DigestContent.from","file":"api/mail/digest.ts","doc":"The period covered, from from to to.","url":"./api/mail/digest.ts/~/DigestContent.from.html","deprecated":false},{"id":"namespace_digestcontent","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DigestContent.to","file":"api/mail/digest.ts","doc":"","url":"./api/mail/digest.ts/~/DigestContent.to.html","deprecated":false},{"id":"namespace_digestcontent","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DigestContent.reader","file":"api/mail/digest.ts","doc":"","url":"./api/mail/digest.ts/~/DigestContent.reader.html","deprecated":false},{"id":"namespace_digestcontent","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DigestContent.activity","file":"api/mail/digest.ts","doc":"Weekly only.","url":"./api/mail/digest.ts/~/DigestContent.activity.html","deprecated":false},{"id":"namespace_digestcontent","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DigestContent.network","file":"api/mail/digest.ts","doc":"Weekly only.","url":"./api/mail/digest.ts/~/DigestContent.network.html","deprecated":false},{"id":"namespace_digestcontent","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DigestContent.top","file":"api/mail/digest.ts","doc":"","url":"./api/mail/digest.ts/~/DigestContent.top.html","deprecated":false},{"id":"namespace_digestcontent","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DigestContent.community","file":"api/mail/digest.ts","doc":"","url":"./api/mail/digest.ts/~/DigestContent.community.html","deprecated":false},{"id":"namespace_digestcontent","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DigestContent.links","file":"api/mail/digest.ts","doc":"","url":"./api/mail/digest.ts/~/DigestContent.links.html","deprecated":false},{"id":"namespace_digestcontent","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DigestContent.links.notifications","file":"api/mail/digest.ts","doc":"","url":"./api/mail/digest.ts/~/DigestContent.links.notifications.html","deprecated":false},{"id":"namespace_digestcontent","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DigestContent.links.followed","file":"api/mail/digest.ts","doc":"","url":"./api/mail/digest.ts/~/DigestContent.links.followed.html","deprecated":false},{"id":"namespace_digestcontent","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DigestContent.links.chat","file":"api/mail/digest.ts","doc":"","url":"./api/mail/digest.ts/~/DigestContent.links.chat.html","deprecated":false},{"id":"namespace_digestcontent","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DigestContent.links.community","file":"api/mail/digest.ts","doc":"The community page's view of the cadence's period.","url":"./api/mail/digest.ts/~/DigestContent.links.community.html","deprecated":false},{"id":"namespace_digestcontent","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DigestContent.links.settings","file":"api/mail/digest.ts","doc":"","url":"./api/mail/digest.ts/~/DigestContent.links.settings.html","deprecated":false},{"id":"namespace_digestcontent","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DigestContent.links.unsubscribe","file":"api/mail/digest.ts","doc":"The one-click page that turns this cadence off.","url":"./api/mail/digest.ts/~/DigestContent.links.unsubscribe.html","deprecated":false},{"id":"namespace_renderdigestemail","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"renderDigestEmail","file":"api/mail/digest.ts","doc":"Returns the digest content describes, written as Markdown and drawn in look, with its subject and hidden preheader.","url":"./api/mail/digest.ts/~/renderDigestEmail.html","deprecated":false},{"id":"namespace_i18n","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"i18n","file":"api/mail/i18n.ts","doc":"Translates the emails' messages, in EMAIL_LOCALE. Every catalog is loaded, so a test can activate another language.","url":"./api/mail/i18n.ts/~/i18n.html","deprecated":false},{"id":"namespace_renderedemail","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"RenderedEmail","file":"api/mail/layout.ts","doc":"Returned by each template to its caller, which hands it to sendEmail with a recipient.","url":"./api/mail/layout.ts/~/RenderedEmail.html","deprecated":false},{"id":"namespace_renderedemail","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"RenderedEmail.subject","file":"api/mail/layout.ts","doc":"","url":"./api/mail/layout.ts/~/RenderedEmail.subject.html","deprecated":false},{"id":"namespace_renderedemail","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"RenderedEmail.html","file":"api/mail/layout.ts","doc":"","url":"./api/mail/layout.ts/~/RenderedEmail.html.html","deprecated":false},{"id":"namespace_renderedemail","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"RenderedEmail.text","file":"api/mail/layout.ts","doc":"The plain-text part, for clients that show no HTML. It is Markdown, so it reads as text and renders as the email's outline.","url":"./api/mail/layout.ts/~/RenderedEmail.text.html","deprecated":false},{"id":"namespace_emaillook","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"EmailLook","file":"api/mail/layout.ts","doc":"Passed to EmailKit, made by lookOf: the instance's style for the emails that aren't a user's own, their settings for a digest.","url":"./api/mail/layout.ts/~/EmailLook.html","deprecated":false},{"id":"namespace_emaillook","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"EmailLook.style","file":"api/mail/layout.ts","doc":"","url":"./api/mail/layout.ts/~/EmailLook.style.html","deprecated":false},{"id":"namespace_emaillook","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"EmailLook.scheme","file":"api/mail/layout.ts","doc":"","url":"./api/mail/layout.ts/~/EmailLook.scheme.html","deprecated":false},{"id":"namespace_lookof","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"lookOf","file":"api/mail/layout.ts","doc":"Returns the look of a reader's settings. An unset style is the instance's, as on the site, and an unset scheme the system's; with no settings at all, as for the welcome and reset emails, both are.","url":"./api/mail/layout.ts/~/lookOf.html","deprecated":false},{"id":"namespace_paletterole","kind":[{"char":"T","kind":"TypeAlias","title":"Type Alias"}],"name":"PaletteRole","file":"api/mail/layout.ts","doc":"Names a color of an EmailPalette, as EmailKit.paint takes it, so that the dark block can recolor the element by the same name.","url":"./api/mail/layout.ts/~/PaletteRole.html","deprecated":false},{"id":"namespace_esc","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"esc","file":"api/mail/layout.ts","doc":"Escapes value for HTML text and attributes. Everything users wrote (names, titles, quotes) goes through it, since none of it may become markup.","url":"./api/mail/layout.ts/~/esc.html","deprecated":false},{"id":"namespace_escmd","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"escMd","file":"api/mail/layout.ts","doc":"Escapes value for Markdown, so that user text in a plain-text part (a title with * or [, say) stays text.","url":"./api/mail/layout.ts/~/escMd.html","deprecated":false},{"id":"namespace_mdlink","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"mdLink","file":"api/mail/layout.ts","doc":"Returns a Markdown link to url labelled with text, escaped.","url":"./api/mail/layout.ts/~/mdLink.html","deprecated":false},{"id":"namespace_emailkit","kind":[{"char":"c","kind":"Class","title":"Class"}],"name":"EmailKit","file":"api/mail/layout.ts","doc":"Draws an email in one EmailLook. A template writes the email as Markdown and hands it to EmailKit.render, which draws each block in the style. The block methods return HTML: text passed to them must already be escaped with esc.","url":"./api/mail/layout.ts/~/EmailKit.html","deprecated":false},{"id":"namespace_emailkit","kind":[{"char":"m","kind":"Method","title":"Method"}],"name":"EmailKit.prototype.fs","file":"api/mail/layout.ts","doc":"Returns px, scaled for the style, as a CSS length.","url":"./api/mail/layout.ts/~/EmailKit.prototype.fs.html","deprecated":false},{"id":"namespace_emailkit","kind":[{"char":"m","kind":"Method","title":"Method"}],"name":"EmailKit.prototype.paint","file":"api/mail/layout.ts","doc":"Returns the class and style attributes of an element colored by roles: fg for its text, bg for its fill, bd for its border. The classes let the dark block recolor it; css is the rest of its style.","url":"./api/mail/layout.ts/~/EmailKit.prototype.paint.html","deprecated":false},{"id":"namespace_emailkit","kind":[{"char":"m","kind":"Method","title":"Method"}],"name":"EmailKit.prototype.link","file":"api/mail/layout.ts","doc":"Returns a link to href around html, in the link color.","url":"./api/mail/layout.ts/~/EmailKit.prototype.link.html","deprecated":false},{"id":"namespace_emailkit","kind":[{"char":"m","kind":"Method","title":"Method"}],"name":"EmailKit.prototype.heading","file":"api/mail/layout.ts","doc":"Returns the email's heading, in the style's title type.","url":"./api/mail/layout.ts/~/EmailKit.prototype.heading.html","deprecated":false},{"id":"namespace_emailkit","kind":[{"char":"m","kind":"Method","title":"Method"}],"name":"EmailKit.prototype.para","file":"api/mail/layout.ts","doc":"Returns a paragraph. css adds to or overrides its style.","url":"./api/mail/layout.ts/~/EmailKit.prototype.para.html","deprecated":false},{"id":"namespace_emailkit","kind":[{"char":"m","kind":"Method","title":"Method"}],"name":"EmailKit.prototype.note","file":"api/mail/layout.ts","doc":"Returns a smaller paragraph in the muted color.","url":"./api/mail/layout.ts/~/EmailKit.prototype.note.html","deprecated":false},{"id":"namespace_emailkit","kind":[{"char":"m","kind":"Method","title":"Method"}],"name":"EmailKit.prototype.button","file":"api/mail/layout.ts","doc":"Returns a button linking to href.","url":"./api/mail/layout.ts/~/EmailKit.prototype.button.html","deprecated":false},{"id":"namespace_emailkit","kind":[{"char":"m","kind":"Method","title":"Method"}],"name":"EmailKit.prototype.pill","file":"api/mail/layout.ts","doc":"Returns a small uppercase pill, as on one's own dump in a list.","url":"./api/mail/layout.ts/~/EmailKit.prototype.pill.html","deprecated":false},{"id":"namespace_emailkit","kind":[{"char":"m","kind":"Method","title":"Method"}],"name":"EmailKit.prototype.image","file":"api/mail/layout.ts","doc":"Returns an image block, rounded as the style rounds images.","url":"./api/mail/layout.ts/~/EmailKit.prototype.image.html","deprecated":false},{"id":"namespace_emailkit","kind":[{"char":"m","kind":"Method","title":"Method"}],"name":"EmailKit.prototype.subhead","file":"api/mail/layout.ts","doc":"Returns a small bold heading inside a section.","url":"./api/mail/layout.ts/~/EmailKit.prototype.subhead.html","deprecated":false},{"id":"namespace_emailkit","kind":[{"char":"m","kind":"Method","title":"Method"}],"name":"EmailKit.prototype.section","file":"api/mail/layout.ts","doc":"Returns a section of the card: a divider in the style's rule (none before the first), an uppercase title in the accent color, and html.","url":"./api/mail/layout.ts/~/EmailKit.prototype.section.html","deprecated":false},{"id":"namespace_emailkit","kind":[{"char":"m","kind":"Method","title":"Method"}],"name":"EmailKit.prototype.render","file":"api/mail/layout.ts","doc":"Returns the email written as markdown: the Markdown itself is the plain-text part, and its blocks, drawn in this kit's style, are the HTML. Each template writes its email once this way. The blocks map as follows.# Title is the heading; an *emphasised* paragraph above it, the eyebrow. Elsewhere an emphasised paragraph is a note.## Section starts a section, with its divider; ### Name a subhead.A link alone in a paragraph is a button, an image alone a wide image, and a fenced block a box for a raw link.A list item whose text starts with an image, then a link, is a row with that thumbnail and the link as its title; what follows is its detail, and an emphasised word right after the link a pill. Other items are sentences, where emphasis marks the date. A numbered list ranks its rows, and a quote under an item is set as one.A bold number is a figure.What follows the last --- is the footer.","url":"./api/mail/layout.ts/~/EmailKit.prototype.render.html","deprecated":false},{"id":"namespace_emailkit","kind":[{"char":"m","kind":"Method","title":"Method"}],"name":"EmailKit.prototype.inline","file":"api/mail/layout.ts","doc":"","url":"./api/mail/layout.ts/~/EmailKit.prototype.inline.html","deprecated":false},{"id":"namespace_emailkit","kind":[{"char":"m","kind":"Method","title":"Method"}],"name":"EmailKit.prototype.blocks","file":"api/mail/layout.ts","doc":"Draws the body's blocks, gathering each ## section with its content.","url":"./api/mail/layout.ts/~/EmailKit.prototype.blocks.html","deprecated":false},{"id":"namespace_emailkit","kind":[{"char":"m","kind":"Method","title":"Method"}],"name":"EmailKit.prototype.list","file":"api/mail/layout.ts","doc":"Draws a list as rows, ranked when it is numbered.","url":"./api/mail/layout.ts/~/EmailKit.prototype.list.html","deprecated":false},{"id":"namespace_emailkit","kind":[{"char":"m","kind":"Method","title":"Method"}],"name":"EmailKit.prototype.eyebrow","file":"api/mail/layout.ts","doc":"Returns the small uppercase line above the heading.","url":"./api/mail/layout.ts/~/EmailKit.prototype.eyebrow.html","deprecated":false},{"id":"namespace_emailkit","kind":[{"char":"m","kind":"Method","title":"Method"}],"name":"EmailKit.prototype.quote","file":"api/mail/layout.ts","doc":"Returns a quoted comment or message.","url":"./api/mail/layout.ts/~/EmailKit.prototype.quote.html","deprecated":false},{"id":"namespace_emailkit","kind":[{"char":"m","kind":"Method","title":"Method"}],"name":"EmailKit.prototype.linkBox","file":"api/mail/layout.ts","doc":"Returns a raw link set in a box, for clients that break buttons.","url":"./api/mail/layout.ts/~/EmailKit.prototype.linkBox.html","deprecated":false},{"id":"namespace_emailkit","kind":[{"char":"m","kind":"Method","title":"Method"}],"name":"EmailKit.prototype.document","file":"api/mail/layout.ts","doc":"Returns the whole HTML document: the brand, the card holding body, and the footer. preheader is the hidden first line inboxes show beside the subject.","url":"./api/mail/layout.ts/~/EmailKit.prototype.document.html","deprecated":false},{"id":"namespace_emailkit","kind":[{"char":"m","kind":"Method","title":"Method"}],"name":"EmailKit.prototype.darkCss","file":"api/mail/layout.ts","doc":"Returns the CSS that recolors every painted element in dark mode, or nothing off the \"auto\" scheme.","url":"./api/mail/layout.ts/~/EmailKit.prototype.darkCss.html","deprecated":false},{"id":"namespace_emailkit","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"EmailKit.prototype.style","file":"api/mail/layout.ts","doc":"The style being drawn.","url":"./api/mail/layout.ts/~/EmailKit.prototype.style.html","deprecated":false},{"id":"namespace_emailkit","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"EmailKit.prototype.palette","file":"api/mail/layout.ts","doc":"The palette inlined into the HTML.","url":"./api/mail/layout.ts/~/EmailKit.prototype.palette.html","deprecated":false},{"id":"namespace_emailkit","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"EmailKit.prototype.darkPalette","file":"api/mail/layout.ts","doc":"The palette that replaces it in dark mode, on the \"auto\" scheme only.","url":"./api/mail/layout.ts/~/EmailKit.prototype.darkPalette.html","deprecated":false},{"id":"namespace_emailkit","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"EmailKit.prototype.font","file":"api/mail/layout.ts","doc":"The font stack, for templates that set their own blocks.","url":"./api/mail/layout.ts/~/EmailKit.prototype.font.html","deprecated":false},{"id":"namespace_emailkit","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"EmailKit.prototype.mode","file":"api/mail/layout.ts","doc":"How inline draws emphasis and links, by where they sit.","url":"./api/mail/layout.ts/~/EmailKit.prototype.mode.html","deprecated":false},{"id":"namespace_emailkit","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"EmailKit.prototype.marked","file":"api/mail/layout.ts","doc":"Draws Markdown's inline tokens with the kit's colors.","url":"./api/mail/layout.ts/~/EmailKit.prototype.marked.html","deprecated":false},{"id":"namespace_renderpasswordresetemail","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"renderPasswordResetEmail","file":"api/mail/password-reset.ts","doc":"Returns the reset email of username, whose button opens resetUrl. The link stays usable for hours, which the email states.","url":"./api/mail/password-reset.ts/~/renderPasswordResetEmail.html","deprecated":false},{"id":"namespace_emailpalette","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"EmailPalette","file":"api/mail/styles.ts","doc":"The colors of one style in one scheme, by role, each read from a token of its theme. The optional ones carry a style's particular touches.","url":"./api/mail/styles.ts/~/EmailPalette.html","deprecated":false},{"id":"namespace_emailpalette","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"EmailPalette.outer","file":"api/mail/styles.ts","doc":"The page around the card (--color-bg).","url":"./api/mail/styles.ts/~/EmailPalette.outer.html","deprecated":false},{"id":"namespace_emailpalette","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"EmailPalette.card","file":"api/mail/styles.ts","doc":"The card holding the content (--color-surface).","url":"./api/mail/styles.ts/~/EmailPalette.card.html","deprecated":false},{"id":"namespace_emailpalette","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"EmailPalette.text","file":"api/mail/styles.ts","doc":"--color-text.","url":"./api/mail/styles.ts/~/EmailPalette.text.html","deprecated":false},{"id":"namespace_emailpalette","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"EmailPalette.sec","file":"api/mail/styles.ts","doc":"--color-text-secondary.","url":"./api/mail/styles.ts/~/EmailPalette.sec.html","deprecated":false},{"id":"namespace_emailpalette","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"EmailPalette.muted","file":"api/mail/styles.ts","doc":"--color-text-muted.","url":"./api/mail/styles.ts/~/EmailPalette.muted.html","deprecated":false},{"id":"namespace_emailpalette","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"EmailPalette.accent","file":"api/mail/styles.ts","doc":"Section titles, ranks and button fills (--color-accent).","url":"./api/mail/styles.ts/~/EmailPalette.accent.html","deprecated":false},{"id":"namespace_emailpalette","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"EmailPalette.link","file":"api/mail/styles.ts","doc":"--color-link.","url":"./api/mail/styles.ts/~/EmailPalette.link.html","deprecated":false},{"id":"namespace_emailpalette","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"EmailPalette.onAccent","file":"api/mail/styles.ts","doc":"Text on an accent fill (--color-on-accent).","url":"./api/mail/styles.ts/~/EmailPalette.onAccent.html","deprecated":false},{"id":"namespace_emailpalette","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"EmailPalette.rule","file":"api/mail/styles.ts","doc":"Dividers and hairlines (--color-border).","url":"./api/mail/styles.ts/~/EmailPalette.rule.html","deprecated":false},{"id":"namespace_emailpalette","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"EmailPalette.soft","file":"api/mail/styles.ts","doc":"Pills and the reset link's box, as the site's badges (--color-badge-bg).","url":"./api/mail/styles.ts/~/EmailPalette.soft.html","deprecated":false},{"id":"namespace_emailpalette","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"EmailPalette.quote","file":"api/mail/styles.ts","doc":"Quoted comments and messages (--color-text-secondary unless set).","url":"./api/mail/styles.ts/~/EmailPalette.quote.html","deprecated":false},{"id":"namespace_emailpalette","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"EmailPalette.date","file":"api/mail/styles.ts","doc":"Kanagawa's fujiGray dates; others use muted.","url":"./api/mail/styles.ts/~/EmailPalette.date.html","deprecated":false},{"id":"namespace_emailpalette","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"EmailPalette.brand","file":"api/mail/styles.ts","doc":"Kanagawa's oniViolet wordmark; others use text.","url":"./api/mail/styles.ts/~/EmailPalette.brand.html","deprecated":false},{"id":"namespace_emailpalette","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"EmailPalette.border","file":"api/mail/styles.ts","doc":"GeoCities' ridged border.","url":"./api/mail/styles.ts/~/EmailPalette.border.html","deprecated":false},{"id":"namespace_emailpalette","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"EmailPalette.shadow","file":"api/mail/styles.ts","doc":"Melange's warm card shadow, translucent.","url":"./api/mail/styles.ts/~/EmailPalette.shadow.html","deprecated":false},{"id":"namespace_emailpalette","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"EmailPalette.gradient","file":"api/mail/styles.ts","doc":"The colors of GeoCities' rainbow or Melange's spice, left to right.","url":"./api/mail/styles.ts/~/EmailPalette.gradient.html","deprecated":false},{"id":"namespace_emailstyle","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"EmailStyle","file":"api/mail/styles.ts","doc":"How a style draws an email. layout.ts builds every block from it, so adding a style to shared/theme.ts means adding its Recipe here.","url":"./api/mail/styles.ts/~/EmailStyle.html","deprecated":false},{"id":"namespace_emailstyle","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"EmailStyle.font","file":"api/mail/styles.ts","doc":"The theme's font stack (--font-body). Its first family is a web font only Apple's mail apps load, through webFont; other clients fall back along the stack.","url":"./api/mail/styles.ts/~/EmailStyle.font.html","deprecated":false},{"id":"namespace_emailstyle","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"EmailStyle.webFont","file":"api/mail/styles.ts","doc":"The Google Fonts family parameter of the web font, if it is one.","url":"./api/mail/styles.ts/~/EmailStyle.webFont.html","deprecated":false},{"id":"namespace_emailstyle","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"EmailStyle.scale","file":"api/mail/styles.ts","doc":"Multiplies every font size: Times sets its serif larger, Kanagawa its monospace smaller.","url":"./api/mail/styles.ts/~/EmailStyle.scale.html","deprecated":false},{"id":"namespace_emailstyle","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"EmailStyle.radius","file":"api/mail/styles.ts","doc":"Corner radii, in pixels: the card's as the site's cards (--radius-xl), the images' as its thumbnails (--radius-md), the buttons' as its buttons (--radius-lg), the pills' as its badges (--radius-sm). The avatars' is the email's own, since the site rounds them with a literal 50% that some styles square.","url":"./api/mail/styles.ts/~/EmailStyle.radius.html","deprecated":false},{"id":"namespace_emailstyle","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"EmailStyle.radius.card","file":"api/mail/styles.ts","doc":"","url":"./api/mail/styles.ts/~/EmailStyle.radius.card.html","deprecated":false},{"id":"namespace_emailstyle","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"EmailStyle.radius.img","file":"api/mail/styles.ts","doc":"","url":"./api/mail/styles.ts/~/EmailStyle.radius.img.html","deprecated":false},{"id":"namespace_emailstyle","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"EmailStyle.radius.btn","file":"api/mail/styles.ts","doc":"","url":"./api/mail/styles.ts/~/EmailStyle.radius.btn.html","deprecated":false},{"id":"namespace_emailstyle","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"EmailStyle.radius.pill","file":"api/mail/styles.ts","doc":"","url":"./api/mail/styles.ts/~/EmailStyle.radius.pill.html","deprecated":false},{"id":"namespace_emailstyle","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"EmailStyle.radius.avatar","file":"api/mail/styles.ts","doc":"","url":"./api/mail/styles.ts/~/EmailStyle.radius.avatar.html","deprecated":false},{"id":"namespace_emailstyle","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"EmailStyle.title","file":"api/mail/styles.ts","doc":"The heading: its size in pixels, weight, and Brutalist's uppercase and spacing.","url":"./api/mail/styles.ts/~/EmailStyle.title.html","deprecated":false},{"id":"namespace_emailstyle","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"EmailStyle.title.size","file":"api/mail/styles.ts","doc":"","url":"./api/mail/styles.ts/~/EmailStyle.title.size.html","deprecated":false},{"id":"namespace_emailstyle","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"EmailStyle.title.weight","file":"api/mail/styles.ts","doc":"","url":"./api/mail/styles.ts/~/EmailStyle.title.weight.html","deprecated":false},{"id":"namespace_emailstyle","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"EmailStyle.title.upper","file":"api/mail/styles.ts","doc":"","url":"./api/mail/styles.ts/~/EmailStyle.title.upper.html","deprecated":false},{"id":"namespace_emailstyle","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"EmailStyle.title.spacing","file":"api/mail/styles.ts","doc":"","url":"./api/mail/styles.ts/~/EmailStyle.title.spacing.html","deprecated":false},{"id":"namespace_emailstyle","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"EmailStyle.title.accent","file":"api/mail/styles.ts","doc":"","url":"./api/mail/styles.ts/~/EmailStyle.title.accent.html","deprecated":false},{"id":"namespace_emailstyle","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"EmailStyle.heavy","file":"api/mail/styles.ts","doc":"The weight of titles of items, figures and names.","url":"./api/mail/styles.ts/~/EmailStyle.heavy.html","deprecated":false},{"id":"namespace_emailstyle","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"EmailStyle.frame","file":"api/mail/styles.ts","doc":"How the card stands out from the page.","url":"./api/mail/styles.ts/~/EmailStyle.frame.html","deprecated":false},{"id":"namespace_emailstyle","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"EmailStyle.rule","file":"api/mail/styles.ts","doc":"The divider between sections; \"gradient\" draws the palette's.","url":"./api/mail/styles.ts/~/EmailStyle.rule.html","deprecated":false},{"id":"namespace_emailstyle","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"EmailStyle.bar","file":"api/mail/styles.ts","doc":"Draws the palette's gradient as a bar along the card's top.","url":"./api/mail/styles.ts/~/EmailStyle.bar.html","deprecated":false},{"id":"namespace_emailstyle","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"EmailStyle.linkUnderline","file":"api/mail/styles.ts","doc":"Underlines links, for styles whose links are the color of the text.","url":"./api/mail/styles.ts/~/EmailStyle.linkUnderline.html","deprecated":false},{"id":"namespace_emailstyle","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"EmailStyle.light","file":"api/mail/styles.ts","doc":"","url":"./api/mail/styles.ts/~/EmailStyle.light.html","deprecated":false},{"id":"namespace_emailstyle","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"EmailStyle.dark","file":"api/mail/styles.ts","doc":"","url":"./api/mail/styles.ts/~/EmailStyle.dark.html","deprecated":false},{"id":"namespace_email_styles","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"EMAIL_STYLES","file":"api/mail/styles.ts","doc":"Every style's email look, keyed by its name, read once at load.","url":"./api/mail/styles.ts/~/EMAIL_STYLES.html","deprecated":false},{"id":"namespace_scheme","kind":[{"char":"T","kind":"TypeAlias","title":"Type Alias"}],"name":"Scheme","file":"api/mail/theme-tokens.ts","doc":"A scheme a token is resolved for. \"auto\" is drawn from both.","url":"./api/mail/theme-tokens.ts/~/Scheme.html","deprecated":false},{"id":"namespace_themetokens","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"ThemeTokens","file":"api/mail/theme-tokens.ts","doc":"Returned by readTokens: the tokens of one style in one scheme, read as the kind of value each is.","url":"./api/mail/theme-tokens.ts/~/ThemeTokens.html","deprecated":false},{"id":"namespace_themetokens","kind":[{"char":"m","kind":"Method","title":"Method"}],"name":"ThemeTokens.value","file":"api/mail/theme-tokens.ts","doc":"Returns the resolved value of token, or throws when it isn't set.","url":"./api/mail/theme-tokens.ts/~/ThemeTokens.value.html","deprecated":false},{"id":"namespace_themetokens","kind":[{"char":"m","kind":"Method","title":"Method"}],"name":"ThemeTokens.color","file":"api/mail/theme-tokens.ts","doc":"Returns the color of token as #rrggbb. A translucent one is laid over over (another token) first, as it shows on the site; without over it stays rgba(), as a shadow's must.","url":"./api/mail/theme-tokens.ts/~/ThemeTokens.color.html","deprecated":false},{"id":"namespace_themetokens","kind":[{"char":"m","kind":"Method","title":"Method"}],"name":"ThemeTokens.stops","file":"api/mail/theme-tokens.ts","doc":"Returns the colors of the gradient token, in order, without positions.","url":"./api/mail/theme-tokens.ts/~/ThemeTokens.stops.html","deprecated":false},{"id":"namespace_themetokens","kind":[{"char":"m","kind":"Method","title":"Method"}],"name":"ThemeTokens.font","file":"api/mail/theme-tokens.ts","doc":"Returns the font stack of token, single-quoted for a style attribute. A family the site bundles as \"X Variable\" is named \"X\", as a mail client or Google Fonts knows it.","url":"./api/mail/theme-tokens.ts/~/ThemeTokens.font.html","deprecated":false},{"id":"namespace_themetokens","kind":[{"char":"m","kind":"Method","title":"Method"}],"name":"ThemeTokens.px","file":"api/mail/theme-tokens.ts","doc":"Returns the length of token in pixels.","url":"./api/mail/theme-tokens.ts/~/ThemeTokens.px.html","deprecated":false},{"id":"namespace_readtokens","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"readTokens","file":"api/mail/theme-tokens.ts","doc":"Returns the tokens of style in scheme, read from the site's stylesheets at the time of the call. styles.ts reads each style once, at load.","url":"./api/mail/theme-tokens.ts/~/readTokens.html","deprecated":false},{"id":"namespace_renderwelcomeemail","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"renderWelcomeEmail","file":"api/mail/welcome.ts","doc":"Returns the welcome email of username. The instance's body has {{username}} and {{site_name}} filled in; raw HTML in it passes through, since it comes from whoever runs the instance, never from a user.","url":"./api/mail/welcome.ts/~/renderWelcomeEmail.html","deprecated":false},{"id":"namespace_app","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"app","file":"api/main.ts","doc":"The whole server, exported so the tests' helpers can send it requests without listening.","url":"./api/main.ts/~/app.html","deprecated":false},{"id":"namespace_authstate","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"AuthState","file":"api/middleware/auth.ts","doc":"Set on ctx.state by authMiddleware for the handlers after it. user carries the caller's live role, not the one in their token.","url":"./api/middleware/auth.ts/~/AuthState.html","deprecated":false},{"id":"namespace_authstate","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"AuthState.user","file":"api/middleware/auth.ts","doc":"","url":"./api/middleware/auth.ts/~/AuthState.user.html","deprecated":false},{"id":"namespace_authcontext","kind":[{"char":"T","kind":"TypeAlias","title":"Type Alias"}],"name":"AuthContext","file":"api/middleware/auth.ts","doc":"The context type of a handler behind authMiddleware. Pass the route path, as in AuthContext<\"/:key/role\">, to keep ctx.params typed.","url":"./api/middleware/auth.ts/~/AuthContext.html","deprecated":false},{"id":"namespace_authmiddleware","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"authMiddleware","file":"api/middleware/auth.ts","doc":"Requires a valid session token in the Authorization header, and puts its payload in ctx.state.user for the rest of the route.","url":"./api/middleware/auth.ts/~/authMiddleware.html","deprecated":false},{"id":"namespace_requirepermission","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"requirePermission","file":"api/middleware/auth.ts","doc":"Returns a middleware that requires the caller to hold permission. It must run after authMiddleware, as in router.patch(path, authMiddleware, requirePermission(\"user:manage\"), …). The returned middleware throws an APIException (403) when the caller lacks the permission.","url":"./api/middleware/auth.ts/~/requirePermission.html","deprecated":false},{"id":"namespace_compressmiddleware","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"compressMiddleware","file":"api/middleware/compress.ts","doc":"Sends the response's JSON or text compressed, in brotli or gzip as the request accepts, when it is at least MIN_BYTES long. A response already encoded, a HEAD, and one marked no-transform go out as they are.","url":"./api/middleware/compress.ts/~/compressMiddleware.html","deprecated":false},{"id":"namespace_errormiddleware","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"errorMiddleware","file":"api/middleware/error.ts","doc":"Answers an APIException with its status, code and message. Anything else is logged with its stack and answered with a 500 SERVER_ERROR whose message gives nothing away.","url":"./api/middleware/error.ts/~/errorMiddleware.html","deprecated":false},{"id":"namespace_ogmiddleware","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"ogMiddleware","file":"api/middleware/og.ts","doc":"Serves index.html with the tags of the dump, user or public playlist a path names (parsePagePath), and passes the request on when it names none that exists or the visitor may see. A path naming one by a former name, a user's or a slug, or in another case, gets a 301 to its current path. The page's URL is on FRONTEND_URL and the images' on PUBLIC_URL, not on the request's origin, which a reverse proxy may have rewritten to an internal host or plain http.","url":"./api/middleware/og.ts/~/ogMiddleware.html","deprecated":false},{"id":"namespace_authpayload","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"AuthPayload","file":"api/model/auth.ts","doc":"Signed into a session token by createJWT, and returned by authenticate to the auth middleware as ctx.state.user. By then role is the user's live role, while username is still the one at issue time.","url":"./api/model/auth.ts/~/AuthPayload.html","deprecated":false},{"id":"namespace_authpayload","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"AuthPayload.userId","file":"api/model/auth.ts","doc":"","url":"./api/model/auth.ts/~/AuthPayload.userId.html","deprecated":false},{"id":"namespace_authpayload","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"AuthPayload.username","file":"api/model/auth.ts","doc":"","url":"./api/model/auth.ts/~/AuthPayload.username.html","deprecated":false},{"id":"namespace_authpayload","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"AuthPayload.role","file":"api/model/auth.ts","doc":"","url":"./api/model/auth.ts/~/AuthPayload.role.html","deprecated":false},{"id":"namespace_authpayload","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"AuthPayload.exp","file":"api/model/auth.ts","doc":"Seconds since the epoch.","url":"./api/model/auth.ts/~/AuthPayload.exp.html","deprecated":false},{"id":"namespace_authpayload","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"AuthPayload.iat","file":"api/model/auth.ts","doc":"Seconds since the epoch, compared with users.tokens_valid_after.","url":"./api/model/auth.ts/~/AuthPayload.iat.html","deprecated":false},{"id":"namespace_isauthpayload","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"isAuthPayload","file":"api/model/auth.ts","doc":"Checks whether obj is an AuthPayload. A media or reset token's payload, which has a purpose, never is.","url":"./api/model/auth.ts/~/isAuthPayload.html","deprecated":false},{"id":"namespace_passwordresetpayload","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"PasswordResetPayload","file":"api/model/auth.ts","doc":"Signed into a reset link's token by createPasswordResetToken, and returned by verifyPasswordResetToken to resetPassword.","url":"./api/model/auth.ts/~/PasswordResetPayload.html","deprecated":false},{"id":"namespace_passwordresetpayload","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PasswordResetPayload.purpose","file":"api/model/auth.ts","doc":"","url":"./api/model/auth.ts/~/PasswordResetPayload.purpose.html","deprecated":false},{"id":"namespace_passwordresetpayload","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PasswordResetPayload.userId","file":"api/model/auth.ts","doc":"","url":"./api/model/auth.ts/~/PasswordResetPayload.userId.html","deprecated":false},{"id":"namespace_passwordresetpayload","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PasswordResetPayload.exp","file":"api/model/auth.ts","doc":"Seconds since the epoch.","url":"./api/model/auth.ts/~/PasswordResetPayload.exp.html","deprecated":false},{"id":"namespace_ispasswordresetpayload","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"isPasswordResetPayload","file":"api/model/auth.ts","doc":"Checks whether obj is a PasswordResetPayload. It doesn't check exp, which jwtVerify has already enforced.","url":"./api/model/auth.ts/~/isPasswordResetPayload.html","deprecated":false},{"id":"namespace_categoryrow","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"CategoryRow","file":"api/model/category.ts","doc":"Returned by the category service's SELECTs on categories.","url":"./api/model/category.ts/~/CategoryRow.html","deprecated":false},{"id":"namespace_categoryrow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CategoryRow.id","file":"api/model/category.ts","doc":"","url":"./api/model/category.ts/~/CategoryRow.id.html","deprecated":false},{"id":"namespace_categoryrow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CategoryRow.kind","file":"api/model/category.ts","doc":"","url":"./api/model/category.ts/~/CategoryRow.kind.html","deprecated":false},{"id":"namespace_categoryrow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CategoryRow.slug","file":"api/model/category.ts","doc":"","url":"./api/model/category.ts/~/CategoryRow.slug.html","deprecated":false},{"id":"namespace_categoryrow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CategoryRow.name","file":"api/model/category.ts","doc":"","url":"./api/model/category.ts/~/CategoryRow.name.html","deprecated":false},{"id":"namespace_categoryrow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CategoryRow.position","file":"api/model/category.ts","doc":"Sorts the categories, lowest first.","url":"./api/model/category.ts/~/CategoryRow.position.html","deprecated":false},{"id":"namespace_categoryrow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CategoryRow.created_at","file":"api/model/category.ts","doc":"","url":"./api/model/category.ts/~/CategoryRow.created_at.html","deprecated":false},{"id":"namespace_categoryrow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CategoryRow.updated_at","file":"api/model/category.ts","doc":"","url":"./api/model/category.ts/~/CategoryRow.updated_at.html","deprecated":false},{"id":"namespace_iscategoryrow","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"isCategoryRow","file":"api/model/category.ts","doc":"Checks whether a row node:sqlite returned is a CategoryRow.","url":"./api/model/category.ts/~/isCategoryRow.html","deprecated":false},{"id":"namespace_categoryrowtoapi","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"categoryRowToApi","file":"api/model/category.ts","doc":"Converts row to the Category the category routes send.","url":"./api/model/category.ts/~/categoryRowToApi.html","deprecated":false},{"id":"namespace_chatmessagerow","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"ChatMessageRow","file":"api/model/chat.ts","doc":"Returned by chat-service's query, which joins each message to its author and to the message it replies to. reply_to_id is kept when the message it points to is deleted, while reply_to_author and reply_to_body then read null.","url":"./api/model/chat.ts/~/ChatMessageRow.html","deprecated":false},{"id":"namespace_chatmessagerow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ChatMessageRow.id","file":"api/model/chat.ts","doc":"","url":"./api/model/chat.ts/~/ChatMessageRow.id.html","deprecated":false},{"id":"namespace_chatmessagerow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ChatMessageRow.user_id","file":"api/model/chat.ts","doc":"","url":"./api/model/chat.ts/~/ChatMessageRow.user_id.html","deprecated":false},{"id":"namespace_chatmessagerow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ChatMessageRow.body","file":"api/model/chat.ts","doc":"","url":"./api/model/chat.ts/~/ChatMessageRow.body.html","deprecated":false},{"id":"namespace_chatmessagerow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ChatMessageRow.created_at","file":"api/model/chat.ts","doc":"","url":"./api/model/chat.ts/~/ChatMessageRow.created_at.html","deprecated":false},{"id":"namespace_chatmessagerow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ChatMessageRow.updated_at","file":"api/model/chat.ts","doc":"","url":"./api/model/chat.ts/~/ChatMessageRow.updated_at.html","deprecated":false},{"id":"namespace_chatmessagerow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ChatMessageRow.author_username","file":"api/model/chat.ts","doc":"","url":"./api/model/chat.ts/~/ChatMessageRow.author_username.html","deprecated":false},{"id":"namespace_chatmessagerow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ChatMessageRow.author_avatar_mime","file":"api/model/chat.ts","doc":"","url":"./api/model/chat.ts/~/ChatMessageRow.author_avatar_mime.html","deprecated":false},{"id":"namespace_chatmessagerow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ChatMessageRow.reply_to_id","file":"api/model/chat.ts","doc":"","url":"./api/model/chat.ts/~/ChatMessageRow.reply_to_id.html","deprecated":false},{"id":"namespace_chatmessagerow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ChatMessageRow.reply_to_author","file":"api/model/chat.ts","doc":"","url":"./api/model/chat.ts/~/ChatMessageRow.reply_to_author.html","deprecated":false},{"id":"namespace_chatmessagerow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ChatMessageRow.reply_to_body","file":"api/model/chat.ts","doc":"Cut to chat-service's REPLY_SNIPPET_LEN characters.","url":"./api/model/chat.ts/~/ChatMessageRow.reply_to_body.html","deprecated":false},{"id":"namespace_chatmessagerow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ChatMessageRow.mentions_everyone","file":"api/model/chat.ts","doc":"1 or 0.","url":"./api/model/chat.ts/~/ChatMessageRow.mentions_everyone.html","deprecated":false},{"id":"namespace_ischatmessagerow","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"isChatMessageRow","file":"api/model/chat.ts","doc":"Checks whether obj, a row read by chat-service, is a ChatMessageRow.","url":"./api/model/chat.ts/~/isChatMessageRow.html","deprecated":false},{"id":"namespace_chatmessagerowtoapi","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"chatMessageRowToApi","file":"api/model/chat.ts","doc":"Converts a row to the ChatMessage that chat-service returns, turning its timestamps into Dates and its nulls into absent fields.","url":"./api/model/chat.ts/~/chatMessageRowToApi.html","deprecated":false},{"id":"namespace_commentrow","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"CommentRow","file":"api/model/comment.ts","doc":"Returned by the comment service's SELECTs on comments, joined with users for the author_ columns.","url":"./api/model/comment.ts/~/CommentRow.html","deprecated":false},{"id":"namespace_commentrow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommentRow.id","file":"api/model/comment.ts","doc":"","url":"./api/model/comment.ts/~/CommentRow.id.html","deprecated":false},{"id":"namespace_commentrow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommentRow.dump_id","file":"api/model/comment.ts","doc":"","url":"./api/model/comment.ts/~/CommentRow.dump_id.html","deprecated":false},{"id":"namespace_commentrow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommentRow.user_id","file":"api/model/comment.ts","doc":"","url":"./api/model/comment.ts/~/CommentRow.user_id.html","deprecated":false},{"id":"namespace_commentrow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommentRow.parent_id","file":"api/model/comment.ts","doc":"It is null on a top-level comment.","url":"./api/model/comment.ts/~/CommentRow.parent_id.html","deprecated":false},{"id":"namespace_commentrow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommentRow.body","file":"api/model/comment.ts","doc":"","url":"./api/model/comment.ts/~/CommentRow.body.html","deprecated":false},{"id":"namespace_commentrow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommentRow.created_at","file":"api/model/comment.ts","doc":"","url":"./api/model/comment.ts/~/CommentRow.created_at.html","deprecated":false},{"id":"namespace_commentrow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommentRow.updated_at","file":"api/model/comment.ts","doc":"","url":"./api/model/comment.ts/~/CommentRow.updated_at.html","deprecated":false},{"id":"namespace_commentrow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommentRow.deleted","file":"api/model/comment.ts","doc":"1 once deleted. The body is emptied but the row stays, so its replies keep their place in the thread.","url":"./api/model/comment.ts/~/CommentRow.deleted.html","deprecated":false},{"id":"namespace_commentrow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommentRow.like_count","file":"api/model/comment.ts","doc":"","url":"./api/model/comment.ts/~/CommentRow.like_count.html","deprecated":false},{"id":"namespace_commentrow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommentRow.author_username","file":"api/model/comment.ts","doc":"","url":"./api/model/comment.ts/~/CommentRow.author_username.html","deprecated":false},{"id":"namespace_commentrow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommentRow.author_avatar_mime","file":"api/model/comment.ts","doc":"","url":"./api/model/comment.ts/~/CommentRow.author_avatar_mime.html","deprecated":false},{"id":"namespace_iscommentrow","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"isCommentRow","file":"api/model/comment.ts","doc":"Checks whether a row node:sqlite returned is a CommentRow.","url":"./api/model/comment.ts/~/isCommentRow.html","deprecated":false},{"id":"namespace_commentrowtoapi","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"commentRowToApi","file":"api/model/comment.ts","doc":"Converts row to the Comment the comment routes send and the WebSocket broadcasts.","url":"./api/model/comment.ts/~/commentRowToApi.html","deprecated":false},{"id":"namespace_dumprow","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"DumpRow","file":"api/model/dump.ts","doc":"Read from the dumps table with DUMP_SELECT_COLUMNS, or written back from a Dump by dumpApiToRow. It lacks url_canonical, which only the duplicate lookup reads.","url":"./api/model/dump.ts/~/DumpRow.html","deprecated":false},{"id":"namespace_dumprow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DumpRow.id","file":"api/model/dump.ts","doc":"","url":"./api/model/dump.ts/~/DumpRow.id.html","deprecated":false},{"id":"namespace_dumprow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DumpRow.kind","file":"api/model/dump.ts","doc":"","url":"./api/model/dump.ts/~/DumpRow.kind.html","deprecated":false},{"id":"namespace_dumprow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DumpRow.title","file":"api/model/dump.ts","doc":"","url":"./api/model/dump.ts/~/DumpRow.title.html","deprecated":false},{"id":"namespace_dumprow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DumpRow.comment","file":"api/model/dump.ts","doc":"","url":"./api/model/dump.ts/~/DumpRow.comment.html","deprecated":false},{"id":"namespace_dumprow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DumpRow.user_id","file":"api/model/dump.ts","doc":"","url":"./api/model/dump.ts/~/DumpRow.user_id.html","deprecated":false},{"id":"namespace_dumprow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DumpRow.created_at","file":"api/model/dump.ts","doc":"","url":"./api/model/dump.ts/~/DumpRow.created_at.html","deprecated":false},{"id":"namespace_dumprow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DumpRow.updated_at","file":"api/model/dump.ts","doc":"","url":"./api/model/dump.ts/~/DumpRow.updated_at.html","deprecated":false},{"id":"namespace_dumprow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DumpRow.slug","file":"api/model/dump.ts","doc":"Unique among its poster's dumps, and set on every row since 0021.","url":"./api/model/dump.ts/~/DumpRow.slug.html","deprecated":false},{"id":"namespace_dumprow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DumpRow.url","file":"api/model/dump.ts","doc":"The link as the poster submitted it.","url":"./api/model/dump.ts/~/DumpRow.url.html","deprecated":false},{"id":"namespace_dumprow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DumpRow.rich_content","file":"api/model/dump.ts","doc":"RichContent as JSON.","url":"./api/model/dump.ts/~/DumpRow.rich_content.html","deprecated":false},{"id":"namespace_dumprow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DumpRow.file_name","file":"api/model/dump.ts","doc":"","url":"./api/model/dump.ts/~/DumpRow.file_name.html","deprecated":false},{"id":"namespace_dumprow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DumpRow.file_mime","file":"api/model/dump.ts","doc":"","url":"./api/model/dump.ts/~/DumpRow.file_mime.html","deprecated":false},{"id":"namespace_dumprow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DumpRow.file_size","file":"api/model/dump.ts","doc":"","url":"./api/model/dump.ts/~/DumpRow.file_size.html","deprecated":false},{"id":"namespace_dumprow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DumpRow.vote_count","file":"api/model/dump.ts","doc":"","url":"./api/model/dump.ts/~/DumpRow.vote_count.html","deprecated":false},{"id":"namespace_dumprow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DumpRow.comment_count","file":"api/model/dump.ts","doc":"Computed by a subquery, which counts the comments that aren't deleted.","url":"./api/model/dump.ts/~/DumpRow.comment_count.html","deprecated":false},{"id":"namespace_dumprow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DumpRow.owner_username","file":"api/model/dump.ts","doc":"The poster's current name, computed by a subquery.","url":"./api/model/dump.ts/~/DumpRow.owner_username.html","deprecated":false},{"id":"namespace_dumprow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DumpRow.is_private","file":"api/model/dump.ts","doc":"","url":"./api/model/dump.ts/~/DumpRow.is_private.html","deprecated":false},{"id":"namespace_dumprow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DumpRow.custom_thumbnail_mime","file":"api/model/dump.ts","doc":"","url":"./api/model/dump.ts/~/DumpRow.custom_thumbnail_mime.html","deprecated":false},{"id":"namespace_dump_columns","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"DUMP_COLUMNS","file":"api/model/dump.ts","doc":"Lists the stored columns of DumpRow. A column added to the table must be added here, to DumpRow and to isDumpRow.","url":"./api/model/dump.ts/~/DUMP_COLUMNS.html","deprecated":false},{"id":"namespace_dump_select_columns","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"DUMP_SELECT_COLUMNS","file":"api/model/dump.ts","doc":"Selects a whole DumpRow, the stored columns and the computed comment_count and owner_username.","url":"./api/model/dump.ts/~/DUMP_SELECT_COLUMNS.html","deprecated":false},{"id":"namespace_dump_select_columns_aliased","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"DUMP_SELECT_COLUMNS_ALIASED","file":"api/model/dump.ts","doc":"Selects a whole DumpRow in a query that aliases dumps as d to join it with other tables.","url":"./api/model/dump.ts/~/DUMP_SELECT_COLUMNS_ALIASED.html","deprecated":false},{"id":"namespace_isdumprow","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"isDumpRow","file":"api/model/dump.ts","doc":"Checks whether obj, a row from a query, is a DumpRow. It checks each column's type, not that kind is url or file.","url":"./api/model/dump.ts/~/isDumpRow.html","deprecated":false},{"id":"namespace_dumprowtoapi","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"dumpRowToApi","file":"api/model/dump.ts","doc":"Converts a row to the API's Dump, parsing its preview's JSON. It leaves categoryIds out: the services add them with attachCategoryIds.","url":"./api/model/dump.ts/~/dumpRowToApi.html","deprecated":false},{"id":"namespace_dumpapitorow","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"dumpApiToRow","file":"api/model/dump.ts","doc":"Converts a Dump back to a row, for a service that writes an edited dump's columns.","url":"./api/model/dump.ts/~/dumpApiToRow.html","deprecated":false},{"id":"namespace_followrow","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"FollowRow","file":"api/model/follow.ts","doc":"Read by getFollowStatus. Exactly one of followed_user_id and followed_playlist_id is set, as the table's CHECK constraint requires.","url":"./api/model/follow.ts/~/FollowRow.html","deprecated":false},{"id":"namespace_followrow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"FollowRow.id","file":"api/model/follow.ts","doc":"","url":"./api/model/follow.ts/~/FollowRow.id.html","deprecated":false},{"id":"namespace_followrow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"FollowRow.follower_id","file":"api/model/follow.ts","doc":"","url":"./api/model/follow.ts/~/FollowRow.follower_id.html","deprecated":false},{"id":"namespace_followrow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"FollowRow.followed_user_id","file":"api/model/follow.ts","doc":"","url":"./api/model/follow.ts/~/FollowRow.followed_user_id.html","deprecated":false},{"id":"namespace_followrow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"FollowRow.followed_playlist_id","file":"api/model/follow.ts","doc":"","url":"./api/model/follow.ts/~/FollowRow.followed_playlist_id.html","deprecated":false},{"id":"namespace_followrow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"FollowRow.created_at","file":"api/model/follow.ts","doc":"","url":"./api/model/follow.ts/~/FollowRow.created_at.html","deprecated":false},{"id":"namespace_isfollowrow","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"isFollowRow","file":"api/model/follow.ts","doc":"Checks whether obj, a row getFollowStatus selected, is a FollowRow.","url":"./api/model/follow.ts/~/isFollowRow.html","deprecated":false},{"id":"namespace_inviterow","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"InviteRow","file":"api/model/invite.ts","doc":"Stored by createInvite, and read back by validateInvite when the invite link is opened or used to sign up.","url":"./api/model/invite.ts/~/InviteRow.html","deprecated":false},{"id":"namespace_inviterow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"InviteRow.token","file":"api/model/invite.ts","doc":"The random token the invite link carries, which is the primary key.","url":"./api/model/invite.ts/~/InviteRow.token.html","deprecated":false},{"id":"namespace_inviterow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"InviteRow.inviter_id","file":"api/model/invite.ts","doc":"Becomes the new user's invited_by.","url":"./api/model/invite.ts/~/InviteRow.inviter_id.html","deprecated":false},{"id":"namespace_inviterow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"InviteRow.used_at","file":"api/model/invite.ts","doc":"Set when an account is created with the invite.","url":"./api/model/invite.ts/~/InviteRow.used_at.html","deprecated":false},{"id":"namespace_inviterow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"InviteRow.created_at","file":"api/model/invite.ts","doc":"Starts the 7-day window in which the invite works.","url":"./api/model/invite.ts/~/InviteRow.created_at.html","deprecated":false},{"id":"namespace_isinviterow","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"isInviteRow","file":"api/model/invite.ts","doc":"Checks whether obj, a row validateInvite selected, is an InviteRow.","url":"./api/model/invite.ts/~/isInviteRow.html","deprecated":false},{"id":"namespace_notificationrow","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"NotificationRow","file":"api/model/notification.ts","doc":"Stored by the triggers of notification-service.ts, and read back by getNotificationsForUser.","url":"./api/model/notification.ts/~/NotificationRow.html","deprecated":false},{"id":"namespace_notificationrow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"NotificationRow.id","file":"api/model/notification.ts","doc":"","url":"./api/model/notification.ts/~/NotificationRow.id.html","deprecated":false},{"id":"namespace_notificationrow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"NotificationRow.user_id","file":"api/model/notification.ts","doc":"","url":"./api/model/notification.ts/~/NotificationRow.user_id.html","deprecated":false},{"id":"namespace_notificationrow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"NotificationRow.type","file":"api/model/notification.ts","doc":"A NotificationType, not checked by the guard.","url":"./api/model/notification.ts/~/NotificationRow.type.html","deprecated":false},{"id":"namespace_notificationrow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"NotificationRow.data","file":"api/model/notification.ts","doc":"The NotificationData as JSON, not checked by the guard.","url":"./api/model/notification.ts/~/NotificationRow.data.html","deprecated":false},{"id":"namespace_notificationrow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"NotificationRow.read","file":"api/model/notification.ts","doc":"0 or 1.","url":"./api/model/notification.ts/~/NotificationRow.read.html","deprecated":false},{"id":"namespace_notificationrow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"NotificationRow.created_at","file":"api/model/notification.ts","doc":"","url":"./api/model/notification.ts/~/NotificationRow.created_at.html","deprecated":false},{"id":"namespace_notificationrow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"NotificationRow.source_key","file":"api/model/notification.ts","doc":"Names the event that caused the notification. A unique index keeps a second row with the same (user_id, source_key) out; null allows duplicates.","url":"./api/model/notification.ts/~/NotificationRow.source_key.html","deprecated":false},{"id":"namespace_isnotificationrow","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"isNotificationRow","file":"api/model/notification.ts","doc":"Checks whether obj, a row getNotificationsForUser selected, is a NotificationRow.","url":"./api/model/notification.ts/~/isNotificationRow.html","deprecated":false},{"id":"namespace_notificationrowtoapi","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"notificationRowToApi","file":"api/model/notification.ts","doc":"Converts a row to the Notification the client gets.","url":"./api/model/notification.ts/~/notificationRowToApi.html","deprecated":false},{"id":"namespace_passwordresettokenrow","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"PasswordResetTokenRow","file":"api/model/password-reset.ts","doc":"Stored by requestPasswordReset when it emails a reset link, and read back by resetPassword when the link is used.","url":"./api/model/password-reset.ts/~/PasswordResetTokenRow.html","deprecated":false},{"id":"namespace_passwordresettokenrow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PasswordResetTokenRow.token","file":"api/model/password-reset.ts","doc":"The signed token itself, which the reset link carries.","url":"./api/model/password-reset.ts/~/PasswordResetTokenRow.token.html","deprecated":false},{"id":"namespace_passwordresettokenrow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PasswordResetTokenRow.user_id","file":"api/model/password-reset.ts","doc":"","url":"./api/model/password-reset.ts/~/PasswordResetTokenRow.user_id.html","deprecated":false},{"id":"namespace_passwordresettokenrow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PasswordResetTokenRow.expires_at","file":"api/model/password-reset.ts","doc":"Lets db/startup.ts purge old rows. The token's own exp is what ends the link.","url":"./api/model/password-reset.ts/~/PasswordResetTokenRow.expires_at.html","deprecated":false},{"id":"namespace_passwordresettokenrow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PasswordResetTokenRow.used_at","file":"api/model/password-reset.ts","doc":"Set when the link is used, and reset to null if the reset then fails.","url":"./api/model/password-reset.ts/~/PasswordResetTokenRow.used_at.html","deprecated":false},{"id":"namespace_ispasswordresettokenrow","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"isPasswordResetTokenRow","file":"api/model/password-reset.ts","doc":"Checks whether obj, a row resetPassword selected, is a PasswordResetTokenRow.","url":"./api/model/password-reset.ts/~/isPasswordResetTokenRow.html","deprecated":false},{"id":"namespace_playlistrow","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"PlaylistRow","file":"api/model/playlist.ts","doc":"Returned by the playlist and follow services' SELECTs on playlists, which join the owner's name as owner_username. A query may add the dump_count and last_dump_at columns (VISIBLE_DUMP_FIGURES), which playlistRowToApi carries over when present.","url":"./api/model/playlist.ts/~/PlaylistRow.html","deprecated":false},{"id":"namespace_playlistrow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PlaylistRow.id","file":"api/model/playlist.ts","doc":"","url":"./api/model/playlist.ts/~/PlaylistRow.id.html","deprecated":false},{"id":"namespace_playlistrow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PlaylistRow.user_id","file":"api/model/playlist.ts","doc":"","url":"./api/model/playlist.ts/~/PlaylistRow.user_id.html","deprecated":false},{"id":"namespace_playlistrow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PlaylistRow.title","file":"api/model/playlist.ts","doc":"","url":"./api/model/playlist.ts/~/PlaylistRow.title.html","deprecated":false},{"id":"namespace_playlistrow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PlaylistRow.slug","file":"api/model/playlist.ts","doc":"Unique among its owner's playlists, and set on every row since 0021.","url":"./api/model/playlist.ts/~/PlaylistRow.slug.html","deprecated":false},{"id":"namespace_playlistrow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PlaylistRow.owner_username","file":"api/model/playlist.ts","doc":"","url":"./api/model/playlist.ts/~/PlaylistRow.owner_username.html","deprecated":false},{"id":"namespace_playlistrow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PlaylistRow.description","file":"api/model/playlist.ts","doc":"","url":"./api/model/playlist.ts/~/PlaylistRow.description.html","deprecated":false},{"id":"namespace_playlistrow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PlaylistRow.is_public","file":"api/model/playlist.ts","doc":"","url":"./api/model/playlist.ts/~/PlaylistRow.is_public.html","deprecated":false},{"id":"namespace_playlistrow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PlaylistRow.created_at","file":"api/model/playlist.ts","doc":"","url":"./api/model/playlist.ts/~/PlaylistRow.created_at.html","deprecated":false},{"id":"namespace_playlistrow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PlaylistRow.updated_at","file":"api/model/playlist.ts","doc":"","url":"./api/model/playlist.ts/~/PlaylistRow.updated_at.html","deprecated":false},{"id":"namespace_playlistrow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PlaylistRow.image_mime","file":"api/model/playlist.ts","doc":"","url":"./api/model/playlist.ts/~/PlaylistRow.image_mime.html","deprecated":false},{"id":"namespace_isplaylistrow","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"isPlaylistRow","file":"api/model/playlist.ts","doc":"Checks whether a row node:sqlite returned is a PlaylistRow.","url":"./api/model/playlist.ts/~/isPlaylistRow.html","deprecated":false},{"id":"namespace_playlistrowtoapi","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"playlistRowToApi","file":"api/model/playlist.ts","doc":"Converts row to the Playlist the playlist routes send.","url":"./api/model/playlist.ts/~/playlistRowToApi.html","deprecated":false},{"id":"namespace_parserows","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"parseRows","file":"api/model/rows.ts","doc":"Returns rows turned by toApi, once isRow has accepted each.","url":"./api/model/rows.ts/~/parseRows.html","deprecated":false},{"id":"namespace_usersettingsrow","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"UserSettingsRow","file":"api/model/settings.ts","doc":"Stored by updateSettings and read back by getSettings. A user without a row has the defaults.","url":"./api/model/settings.ts/~/UserSettingsRow.html","deprecated":false},{"id":"namespace_usersettingsrow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"UserSettingsRow.user_id","file":"api/model/settings.ts","doc":"","url":"./api/model/settings.ts/~/UserSettingsRow.user_id.html","deprecated":false},{"id":"namespace_usersettingsrow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"UserSettingsRow.style","file":"api/model/settings.ts","doc":"A style name, or null for the instance's.","url":"./api/model/settings.ts/~/UserSettingsRow.style.html","deprecated":false},{"id":"namespace_usersettingsrow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"UserSettingsRow.color_scheme","file":"api/model/settings.ts","doc":"","url":"./api/model/settings.ts/~/UserSettingsRow.color_scheme.html","deprecated":false},{"id":"namespace_usersettingsrow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"UserSettingsRow.digest_weekly","file":"api/model/settings.ts","doc":"0 or 1.","url":"./api/model/settings.ts/~/UserSettingsRow.digest_weekly.html","deprecated":false},{"id":"namespace_usersettingsrow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"UserSettingsRow.digest_monthly","file":"api/model/settings.ts","doc":"0 or 1.","url":"./api/model/settings.ts/~/UserSettingsRow.digest_monthly.html","deprecated":false},{"id":"namespace_usersettingsrow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"UserSettingsRow.updated_at","file":"api/model/settings.ts","doc":"","url":"./api/model/settings.ts/~/UserSettingsRow.updated_at.html","deprecated":false},{"id":"namespace_settings_columns","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"SETTINGS_COLUMNS","file":"api/model/settings.ts","doc":"Names the column of each setting, for the queries that pick users by one, as digest-service.ts does by its digest's switch.","url":"./api/model/settings.ts/~/SETTINGS_COLUMNS.html","deprecated":false},{"id":"namespace_isusersettingsrow","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"isUserSettingsRow","file":"api/model/settings.ts","doc":"Checks whether obj, a row getSettings selected, is a UserSettingsRow.","url":"./api/model/settings.ts/~/isUserSettingsRow.html","deprecated":false},{"id":"namespace_settingsrowtoapi","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"settingsRowToApi","file":"api/model/settings.ts","doc":"Converts a row to the UserSettings the client gets. A style or scheme the code no longer knows, as after one is removed, reads as unset.","url":"./api/model/settings.ts/~/settingsRowToApi.html","deprecated":false},{"id":"namespace_user","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"User","file":"api/model/user.ts","doc":"Returned by the lookups of user-service.ts. It must never be sent as is: it carries the password hash.","url":"./api/model/user.ts/~/User.html","deprecated":false},{"id":"namespace_user","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"User.passwordHash","file":"api/model/user.ts","doc":"From hashPassword, as hash.salt, or null for an account from another instance (isRemoteUser), which signs in there and never with a password here. The row stores that as ''.","url":"./api/model/user.ts/~/User.passwordHash.html","deprecated":false},{"id":"namespace_isremoteuser","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"isRemoteUser","file":"api/model/user.ts","doc":"Checks whether user's account lives on another instance, whose user signs in here through federation (federation-service.ts). Their password, email, avatar and name are that instance's to change, so the routes that change them here refuse.","url":"./api/model/user.ts/~/isRemoteUser.html","deprecated":false},{"id":"namespace_topublicuser","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"toPublicUser","file":"api/model/user.ts","doc":"Returns what anyone may see of user, without the hash and the email. Every route that sends another user's profile goes through it.","url":"./api/model/user.ts/~/toPublicUser.html","deprecated":false},{"id":"namespace_toselfuser","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"toSelfUser","file":"api/model/user.ts","doc":"Returns what user sees of themselves, without the hash, for the routes that answer the caller's own account.","url":"./api/model/user.ts/~/toSelfUser.html","deprecated":false},{"id":"namespace_userrow","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"UserRow","file":"api/model/user.ts","doc":"Selected by user-service.ts and follow-service.ts, and converted by userRowToApi. It leaves out chat_read_at and tokens_valid_after, which only the chat's read state and getSessionState query.","url":"./api/model/user.ts/~/UserRow.html","deprecated":false},{"id":"namespace_userrow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"UserRow.id","file":"api/model/user.ts","doc":"","url":"./api/model/user.ts/~/UserRow.id.html","deprecated":false},{"id":"namespace_userrow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"UserRow.username","file":"api/model/user.ts","doc":"","url":"./api/model/user.ts/~/UserRow.username.html","deprecated":false},{"id":"namespace_userrow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"UserRow.password_hash","file":"api/model/user.ts","doc":"'' for an account from another instance, which has no password.","url":"./api/model/user.ts/~/UserRow.password_hash.html","deprecated":false},{"id":"namespace_userrow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"UserRow.role","file":"api/model/user.ts","doc":"","url":"./api/model/user.ts/~/UserRow.role.html","deprecated":false},{"id":"namespace_userrow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"UserRow.created_at","file":"api/model/user.ts","doc":"","url":"./api/model/user.ts/~/UserRow.created_at.html","deprecated":false},{"id":"namespace_userrow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"UserRow.updated_at","file":"api/model/user.ts","doc":"Bumped by any profile or avatar change.","url":"./api/model/user.ts/~/UserRow.updated_at.html","deprecated":false},{"id":"namespace_userrow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"UserRow.avatar_mime","file":"api/model/user.ts","doc":"Null without an avatar.","url":"./api/model/user.ts/~/UserRow.avatar_mime.html","deprecated":false},{"id":"namespace_userrow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"UserRow.description","file":"api/model/user.ts","doc":"Markdown.","url":"./api/model/user.ts/~/UserRow.description.html","deprecated":false},{"id":"namespace_userrow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"UserRow.invited_by","file":"api/model/user.ts","doc":"Null for the seeded admin, who had no inviter.","url":"./api/model/user.ts/~/UserRow.invited_by.html","deprecated":false},{"id":"namespace_userrow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"UserRow.invited_by_username","file":"api/model/user.ts","doc":"Joined from the inviter's row rather than stored, and undefined when the query doesn't join it. The guard doesn't check it.","url":"./api/model/user.ts/~/UserRow.invited_by_username.html","deprecated":false},{"id":"namespace_userrow","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"UserRow.email","file":"api/model/user.ts","doc":"","url":"./api/model/user.ts/~/UserRow.email.html","deprecated":false},{"id":"namespace_isuserrow","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"isUserRow","file":"api/model/user.ts","doc":"Checks whether obj, a row selected with the columns of UserRow, is one.","url":"./api/model/user.ts/~/isUserRow.html","deprecated":false},{"id":"namespace_userrowtoapi","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"userRowToApi","file":"api/model/user.ts","doc":"Converts a row to a User, turning nulls into undefined.","url":"./api/model/user.ts/~/userRowToApi.html","deprecated":false},{"id":"namespace_userapitorow","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"userApiToRow","file":"api/model/user.ts","doc":"Converts a User back to a row, for updateUser. A User has no inviter id, so invited_by comes out null: don't write it back.","url":"./api/model/user.ts/~/userApiToRow.html","deprecated":false},{"id":"namespace_resolvebandcamp","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"resolveBandcamp","file":"api/remote/bandcamp-streams.ts","doc":"Returns the tracklist of the Bandcamp page pageUrl, from the cache when it was resolved in the last 12 hours. force skips the cache: the player sets it when it re-resolves a queue whose URLs expired or are about to, which a cached entry could hand back.","url":"./api/remote/bandcamp-streams.ts/~/resolveBandcamp.html","deprecated":false},{"id":"namespace_bandcamp_host_re","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"BANDCAMP_HOST_RE","file":"api/remote/bandcamp-tralbum.ts","doc":"Matches the hostnames bandcamp-streams.ts accepts: bandcamp.com and its subdomains, and not bandcamp.com.example.org. An artist on a custom domain doesn't match, and the player falls back to the embed.","url":"./api/remote/bandcamp-tralbum.ts/~/BANDCAMP_HOST_RE.html","deprecated":false},{"id":"namespace_parsetralbum","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"parseTralbum","file":"api/remote/bandcamp-tralbum.ts","doc":"Returns the release on the Bandcamp page html, fetched from sourceUrl; null when the page has no release data, no audio or no streamable track. Stream URLs outside bcbits.com are dropped.","url":"./api/remote/bandcamp-tralbum.ts/~/parseTralbum.html","deprecated":false},{"id":"namespace_max_page_bytes","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"MAX_PAGE_BYTES","file":"api/remote/fetch.ts","doc":"The default cap of readTextCapped. The metadata previews read is in the , and a page past this is a download.","url":"./api/remote/fetch.ts/~/MAX_PAGE_BYTES.html","deprecated":false},{"id":"namespace_readbytescapped","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"readBytesCapped","file":"api/remote/fetch.ts","doc":"Reads the body of res up to maxBytes; the rest is cancelled, never downloaded. The image proxy reads through it, and readTextCapped.","url":"./api/remote/fetch.ts/~/readBytesCapped.html","deprecated":false},{"id":"namespace_readtextcapped","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"readTextCapped","file":"api/remote/fetch.ts","doc":"Reads the body of res as text, up to maxBytes, in the charset the page declares; the rest is cancelled, never downloaded. fetchPage and the Bandcamp and YouTube resolvers read pages through it.","url":"./api/remote/fetch.ts/~/readTextCapped.html","deprecated":false},{"id":"namespace_fetchwithtimeout","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"fetchWithTimeout","file":"api/remote/fetch.ts","doc":"Fetches a user-supplied URL, following up to five redirects, each of which must resolve to a public address too. timeoutMs bounds each hop, body included. The caller must read or cancel the body, or its connection stays open.","url":"./api/remote/fetch.ts/~/fetchWithTimeout.html","deprecated":false},{"id":"namespace_fetchedpage","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"FetchedPage","file":"api/remote/fetch.ts","doc":"Returned by fetchPage to the link preview providers.","url":"./api/remote/fetch.ts/~/FetchedPage.html","deprecated":false},{"id":"namespace_fetchedpage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"FetchedPage.url","file":"api/remote/fetch.ts","doc":"The URL the page was served from, after redirects: the base its relative links resolve against.","url":"./api/remote/fetch.ts/~/FetchedPage.url.html","deprecated":false},{"id":"namespace_fetchedpage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"FetchedPage.html","file":"api/remote/fetch.ts","doc":"The page's text, up to MAX_PAGE_BYTES; missing when it isn't HTML.","url":"./api/remote/fetch.ts/~/FetchedPage.html.html","deprecated":false},{"id":"namespace_fetchpage","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"fetchPage","file":"api/remote/fetch.ts","doc":"Fetches a page for its link preview, through fetchWithTimeout. A response that isn't HTML is cancelled unread.","url":"./api/remote/fetch.ts/~/fetchPage.html","deprecated":false},{"id":"namespace_isvalidhttpurl","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"isValidHttpUrl","file":"api/remote/fetch.ts","doc":"Checks whether raw is an http(s) URL on a host that isn't private, or a link to one of this site's own pages. Routes and services check a URL with it before storing, previewing or proxying it; it does no DNS lookup, which fetchWithTimeout does.","url":"./api/remote/fetch.ts/~/isValidHttpUrl.html","deprecated":false},{"id":"namespace_assertreachable","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"assertReachable","file":"api/remote/gerbeur-instance.ts","doc":"Checks that url may be reached: https on a public address, or anything under GERBEUR_FEDERATION_ALLOW_PRIVATE.","url":"./api/remote/gerbeur-instance.ts/~/assertReachable.html","deprecated":false},{"id":"namespace_fetchmetadata","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"fetchMetadata","file":"api/remote/gerbeur-instance.ts","doc":"Returns the metadata of the instance at origin, its issuer, cached. It must name origin as its issuer and speak this protocol's version.","url":"./api/remote/gerbeur-instance.ts/~/fetchMetadata.html","deprecated":false},{"id":"namespace_resolveissuer","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"resolveIssuer","file":"api/remote/gerbeur-instance.ts","doc":"Returns the issuer of the instance at origin, cached: origin itself, or, when origin is where the instance's pages are and its API lives at another, the issuer the pages' metadata names, whose own metadata must name those pages back as where its /authorize is. People know an instance by the address in their browser, which a sign-in form or the trust list may be given; a handle and the stored identities name the issuer.","url":"./api/remote/gerbeur-instance.ts/~/resolveIssuer.html","deprecated":false},{"id":"namespace_fetchkeys","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"fetchKeys","file":"api/remote/gerbeur-instance.ts","doc":"Returns the public keys of the instance at origin, cached unless fresh asks to refetch them and they weren't in the last minute.","url":"./api/remote/gerbeur-instance.ts/~/fetchKeys.html","deprecated":false},{"id":"namespace_exchangecode","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"exchangeCode","file":"api/remote/gerbeur-instance.ts","doc":"Trades code for an identity token at the token endpoint of the instance at origin, and returns the token, unverified.","url":"./api/remote/gerbeur-instance.ts/~/exchangeCode.html","deprecated":false},{"id":"namespace_postevent","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"postEvent","file":"api/remote/gerbeur-instance.ts","doc":"Sends the signed event event to the events endpoint of the instance at origin, and returns whether it took it. A 4xx other than 429 means it never will, which the caller treats as delivered.","url":"./api/remote/gerbeur-instance.ts/~/postEvent.html","deprecated":false},{"id":"namespace_fetchavatar","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"fetchAvatar","file":"api/remote/gerbeur-instance.ts","doc":"Returns the image at url, a user's avatar on their home instance, up to the size an avatar may be.","url":"./api/remote/gerbeur-instance.ts/~/fetchAvatar.html","deprecated":false},{"id":"namespace_clearinstancecaches","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"clearInstanceCaches","file":"api/remote/gerbeur-instance.ts","doc":"Empties the caches, for the tests' reset between cases.","url":"./api/remote/gerbeur-instance.ts/~/clearInstanceCaches.html","deprecated":false},{"id":"namespace_decodehtmlentities","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"decodeHtmlEntities","file":"api/remote/html.ts","doc":"Decodes the entities in str in a single pass, so " reads ". An entity it doesn't know, or a code point that doesn't exist, is left as written. Also used by bandcamp-tralbum.ts on the JSON a page carries in an attribute.","url":"./api/remote/html.ts/~/decodeHtmlEntities.html","deprecated":false},{"id":"namespace_absolutehttpurl","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"absoluteHttpUrl","file":"api/remote/html.ts","doc":"Returns raw resolved against base as an absolute http(s) URL; undefined for a data: URI, another scheme or a URL that doesn't parse. Every URL a page names goes through it, so /og.png and //cdn/og.png work.","url":"./api/remote/html.ts/~/absoluteHttpUrl.html","deprecated":false},{"id":"namespace_jsonldresult","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"JsonLdResult","file":"api/remote/html.ts","doc":"Returned by the JSON-LD reading of parsePage, which the generic preview ranks below the page's OG and Twitter tags.","url":"./api/remote/html.ts/~/JsonLdResult.html","deprecated":false},{"id":"namespace_jsonldresult","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"JsonLdResult.title","file":"api/remote/html.ts","doc":"From name, or else headline.","url":"./api/remote/html.ts/~/JsonLdResult.title.html","deprecated":false},{"id":"namespace_jsonldresult","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"JsonLdResult.description","file":"api/remote/html.ts","doc":"","url":"./api/remote/html.ts/~/JsonLdResult.description.html","deprecated":false},{"id":"namespace_jsonldresult","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"JsonLdResult.thumbnailUrl","file":"api/remote/html.ts","doc":"From image, or else thumbnailUrl or thumbnail.","url":"./api/remote/html.ts/~/JsonLdResult.thumbnailUrl.html","deprecated":false},{"id":"namespace_page","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"Page","file":"api/remote/html.ts","doc":"Returned by parsePage: what a page says about itself, entities decoded, values trimmed and URLs absolute.","url":"./api/remote/html.ts/~/Page.html","deprecated":false},{"id":"namespace_page","kind":[{"char":"m","kind":"Method","title":"Method"}],"name":"Page.meta","file":"api/remote/html.ts","doc":"Returns the content of the first whose property or name is key, in any case: sites write og: tags under either attribute, and Twitter's too.","url":"./api/remote/html.ts/~/Page.meta.html","deprecated":false},{"id":"namespace_page","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Page.title","file":"api/remote/html.ts","doc":"The text of the element.","url":"./api/remote/html.ts/~/Page.title.html","deprecated":false},{"id":"namespace_page","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Page.jsonLd","file":"api/remote/html.ts","doc":"","url":"./api/remote/html.ts/~/Page.jsonLd.html","deprecated":false},{"id":"namespace_page","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Page.themeColor","file":"api/remote/html.ts","doc":"The theme-color, as written: pass it to normalizeCssColor.","url":"./api/remote/html.ts/~/Page.themeColor.html","deprecated":false},{"id":"namespace_page","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Page.maskIconColor","file":"api/remote/html.ts","doc":"The color of the Safari pinned-tab icon, as written.","url":"./api/remote/html.ts/~/Page.maskIconColor.html","deprecated":false},{"id":"namespace_page","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Page.bestIcon","file":"api/remote/html.ts","doc":"The largest icon the page links, which the thumbnail placeholder draws.","url":"./api/remote/html.ts/~/Page.bestIcon.html","deprecated":false},{"id":"namespace_page","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Page.largeImage","file":"api/remote/html.ts","doc":"The first image declared at least 200 pixels both ways.","url":"./api/remote/html.ts/~/Page.largeImage.html","deprecated":false},{"id":"namespace_page","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Page.firstContentImage","file":"api/remote/html.ts","doc":"The first image that doesn't look like page furniture.","url":"./api/remote/html.ts/~/Page.firstContentImage.html","deprecated":false},{"id":"namespace_parsepage","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"parsePage","file":"api/remote/html.ts","doc":"Reads html, served from pageUrl, in one pass. The generic preview and the providers built on it read a page through it.","url":"./api/remote/html.ts/~/parsePage.html","deprecated":false},{"id":"namespace_normalizecsscolor","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"normalizeCssColor","file":"api/remote/html.ts","doc":"Returns raw as a lowercase #rrggbb, from a hex, rgb(), rgba() or common named color; undefined for any other form. The generic preview stores it as the preview's accentColor, a tint over the app's own surface, so alpha is dropped, and a fully transparent one is no color at all.","url":"./api/remote/html.ts/~/normalizeCssColor.html","deprecated":false},{"id":"namespace_proxiedimage","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"ProxiedImage","file":"api/remote/image-proxy.ts","doc":"Returned to GET /api/remote/image by fetchProxiedImage, which sends it back under contentType.","url":"./api/remote/image-proxy.ts/~/ProxiedImage.html","deprecated":false},{"id":"namespace_proxiedimage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ProxiedImage.bytes","file":"api/remote/image-proxy.ts","doc":"","url":"./api/remote/image-proxy.ts/~/ProxiedImage.bytes.html","deprecated":false},{"id":"namespace_proxiedimage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ProxiedImage.contentType","file":"api/remote/image-proxy.ts","doc":"One of the raster types, without parameters.","url":"./api/remote/image-proxy.ts/~/ProxiedImage.contentType.html","deprecated":false},{"id":"namespace_clearimagecache","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"clearImageCache","file":"api/remote/image-proxy.ts","doc":"Empties the cache, for the tests' reset between cases.","url":"./api/remote/image-proxy.ts/~/clearImageCache.html","deprecated":false},{"id":"namespace_fetchproxiedimage","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"fetchProxiedImage","file":"api/remote/image-proxy.ts","doc":"Returns the image at url, from the cache or else from its host; null when the host answers with an error, or with anything but a raster image of 5 MB at most. With width, it comes as a WebP copy scaled down to it, or as it is when no copy can be made (scalableImage, and ffmpeg). The route checks url with isValidHttpUrl first.","url":"./api/remote/image-proxy.ts/~/fetchProxiedImage.html","deprecated":false},{"id":"namespace_bandcampprovider","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"bandcampProvider","file":"api/remote/providers/bandcamp.ts","doc":"Claims bandcamp.com and its subdomains, where artists have their pages, and takes the embed player's URL from the page's og:video. The native player fetches the page's streams itself at play time, through GET /api/remote/bandcamp.","url":"./api/remote/providers/bandcamp.ts/~/bandcampProvider.html","deprecated":false},{"id":"namespace_genericpreview","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"genericPreview","file":"api/remote/providers/generic.ts","doc":"Returns the preview of the page url that page read, served from finalUrl after redirects. Each field falls back from OG tags to Twitter tags, JSON-LD and the markup itself. The icon and brand color feed the placeholder the frontend draws when there is no thumbnail.","url":"./api/remote/providers/generic.ts/~/genericPreview.html","deprecated":false},{"id":"namespace_genericprovider","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"genericProvider","file":"api/remote/providers/generic.ts","doc":"Matches every URL, so it comes last in the service's list.","url":"./api/remote/providers/generic.ts/~/genericProvider.html","deprecated":false},{"id":"namespace_richcontentprovider","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"RichContentProvider","file":"api/remote/providers/provider.ts","doc":"Implemented by each file of remote/providers/, and listed in priority order by rich-content-service.ts.","url":"./api/remote/providers/provider.ts/~/RichContentProvider.html","deprecated":false},{"id":"namespace_richcontentprovider","kind":[{"char":"m","kind":"Method","title":"Method"}],"name":"RichContentProvider.matches","file":"api/remote/providers/provider.ts","doc":"Called on a URL that isValidHttpUrl accepted; never throws.","url":"./api/remote/providers/provider.ts/~/RichContentProvider.matches.html","deprecated":false},{"id":"namespace_richcontentprovider","kind":[{"char":"m","kind":"Method","title":"Method"}],"name":"RichContentProvider.fetch","file":"api/remote/providers/provider.ts","doc":"Returns the preview of url, which ends up in the dump's rich_content or the create form's preview. It rejects when the page can't be fetched or answers with an error status, and the service then falls back to a stub. A page that isn't HTML yields a preview without metadata. The service tidies what it returns, so a provider leaves text as the page wrote it.","url":"./api/remote/providers/provider.ts/~/RichContentProvider.fetch.html","deprecated":false},{"id":"namespace_richcontentprovider","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"RichContentProvider.name","file":"api/remote/providers/provider.ts","doc":"","url":"./api/remote/providers/provider.ts/~/RichContentProvider.name.html","deprecated":false},{"id":"namespace_selfprovider","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"selfProvider","file":"api/remote/providers/self.ts","doc":"Comes before the generic provider, and claims what isSelfUrl accepts. A profile's tab previews as the profile. Its fetch rejects with a 404 APIException for a missing page, a private dump or a private playlist: the preview is stored in the linking dump, which others may see.","url":"./api/remote/providers/self.ts/~/selfProvider.html","deprecated":false},{"id":"namespace_soundcloudprovider","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"soundcloudProvider","file":"api/remote/providers/soundcloud.ts","doc":"Claims SoundCloud's hosts, short links included, and builds the embed player's URL from the page's address.","url":"./api/remote/providers/soundcloud.ts/~/soundcloudProvider.html","deprecated":false},{"id":"namespace_youtubeprovider","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"youtubeProvider","file":"api/remote/providers/youtube.ts","doc":"Comes first in the service's list. A video's embed keeps the link's playlist and start time, a playlist embeds as a videoseries, and a channel gets no embed. Its fetch never rejects: whatever YouTube doesn't answer is left out.","url":"./api/remote/providers/youtube.ts/~/youtubeProvider.html","deprecated":false},{"id":"namespace_isprivateaddress","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"isPrivateAddress","file":"api/remote/public-address.ts","doc":"Checks whether ip is an IPv4 or IPv6 address outside the public internet. An IPv4 address carried in IPv6 is judged as IPv4. Anything that isn't an IP address is false, so a hostname must be resolved first.","url":"./api/remote/public-address.ts/~/isPrivateAddress.html","deprecated":false},{"id":"namespace_barehostname","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"bareHostname","file":"api/remote/public-address.ts","doc":"Returns url's hostname without the brackets URL.hostname keeps around an IPv6 literal: the address checks here read it, and fetch.ts hands it to curl's --resolve.","url":"./api/remote/public-address.ts/~/bareHostname.html","deprecated":false},{"id":"namespace_isprivatehostname","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"isPrivateHostname","file":"api/remote/public-address.ts","doc":"Checks whether the host of url is private without a DNS lookup: a private IP address, or localhost and its subdomains. isValidHttpUrl uses it to reject a link early; only resolvePublicAddress is a real guard.","url":"./api/remote/public-address.ts/~/isPrivateHostname.html","deprecated":false},{"id":"namespace_resolvepublicaddress","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"resolvePublicAddress","file":"api/remote/public-address.ts","doc":"Resolves the host of url and returns one of its addresses, all of which must be public: the fetch may pick any of them. fetchWithTimeout calls it before each hop.Only the curl fallback connects to the address returned. Deno's fetch resolves the name again, so a DNS server that answers differently the second time (rebinding) can still get through.","url":"./api/remote/public-address.ts/~/resolvePublicAddress.html","deprecated":false},{"id":"namespace_fetchtwemojisvg","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"fetchTwemojiSvg","file":"api/remote/twemoji.ts","doc":"Returns Twemoji's SVG for emoji, whose file name cp comes from emojiToCodepoint. emoji only serves the error message. It fetches with plain fetch, since the host is fixed, and gives up after 15 s.","url":"./api/remote/twemoji.ts/~/fetchTwemojiSvg.html","deprecated":false},{"id":"namespace_parseplaylistpage","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"parsePlaylistPage","file":"api/remote/youtube-playlist.ts","doc":"Returns the playlist listId as read from its page html; null when the page has no ytInitialData or no track in it.","url":"./api/remote/youtube-playlist.ts/~/parsePlaylistPage.html","deprecated":false},{"id":"namespace_resolveyoutubeplaylist","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"resolveYouTubePlaylist","file":"api/remote/youtube-playlist.ts","doc":"Returns the tracklist of the playlist listId, from the cache when it was resolved in the last 6 hours.","url":"./api/remote/youtube-playlist.ts/~/resolveYouTubePlaylist.html","deprecated":false},{"id":"namespace_default","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"default","file":"api/routes/attachments.ts","doc":"Mounted by api/main.ts behind the error, Open Graph and CORS middleware. An APIException thrown by a handler becomes the JSON error response there.","url":"./api/routes/attachments.ts/~/default.html","deprecated":false},{"id":"namespace_default","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"default","file":"api/routes/avatars.ts","doc":"Mounted by api/main.ts behind the error, Open Graph and CORS middleware. An APIException thrown by a handler becomes the JSON error response there.","url":"./api/routes/avatars.ts/~/default.html","deprecated":false},{"id":"namespace_default","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"default","file":"api/routes/categories.ts","doc":"Mounted by api/main.ts behind the error, Open Graph and CORS middleware. An APIException thrown by a handler becomes the JSON error response there.","url":"./api/routes/categories.ts/~/default.html","deprecated":false},{"id":"namespace_default","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"default","file":"api/routes/chat.ts","doc":"Mounted by api/main.ts behind the error, Open Graph and CORS middleware. An APIException thrown by a handler becomes the JSON error response there.","url":"./api/routes/chat.ts/~/default.html","deprecated":false},{"id":"namespace_default","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"default","file":"api/routes/comments.ts","doc":"Mounted by api/main.ts behind the error, Open Graph and CORS middleware. An APIException thrown by a handler becomes the JSON error response there.","url":"./api/routes/comments.ts/~/default.html","deprecated":false},{"id":"namespace_default","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"default","file":"api/routes/community.ts","doc":"Mounted by api/main.ts behind the error, Open Graph and CORS middleware. An APIException thrown by a handler becomes the JSON error response there.","url":"./api/routes/community.ts/~/default.html","deprecated":false},{"id":"namespace_default","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"default","file":"api/routes/dumps.ts","doc":"Mounted by api/main.ts behind the error, Open Graph and CORS middleware. An APIException thrown by a handler becomes the JSON error response there.","url":"./api/routes/dumps.ts/~/default.html","deprecated":false},{"id":"namespace_default","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"default","file":"api/routes/federation.ts","doc":"Mounted by api/main.ts behind the error, Open Graph and CORS middleware. An APIException thrown by a handler becomes the JSON error response there.","url":"./api/routes/federation.ts/~/default.html","deprecated":false},{"id":"namespace_default","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"default","file":"api/routes/files.ts","doc":"Mounted by api/main.ts behind the error, Open Graph and CORS middleware. An APIException thrown by a handler becomes the JSON error response there.","url":"./api/routes/files.ts/~/default.html","deprecated":false},{"id":"namespace_default","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"default","file":"api/routes/follows.ts","doc":"Mounted by api/main.ts behind the error, Open Graph and CORS middleware. An APIException thrown by a handler becomes the JSON error response there.","url":"./api/routes/follows.ts/~/default.html","deprecated":false},{"id":"namespace_default","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"default","file":"api/routes/invites.ts","doc":"Mounted by api/main.ts behind the error, Open Graph and CORS middleware. An APIException thrown by a handler becomes the JSON error response there.","url":"./api/routes/invites.ts/~/default.html","deprecated":false},{"id":"namespace_default","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"default","file":"api/routes/me.ts","doc":"Mounted by api/main.ts behind the error, Open Graph and CORS middleware. An APIException thrown by a handler becomes the JSON error response there.","url":"./api/routes/me.ts/~/default.html","deprecated":false},{"id":"namespace_default","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"default","file":"api/routes/notifications.ts","doc":"Mounted by api/main.ts behind the error, Open Graph and CORS middleware. An APIException thrown by a handler becomes the JSON error response there.","url":"./api/routes/notifications.ts/~/default.html","deprecated":false},{"id":"namespace_default","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"default","file":"api/routes/oauth.ts","doc":"Mounted by api/main.ts behind the error, Open Graph and CORS middleware. An APIException thrown by a handler becomes the JSON error response there.","url":"./api/routes/oauth.ts/~/default.html","deprecated":false},{"id":"namespace_default","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"default","file":"api/routes/password-resets.ts","doc":"Mounted by api/main.ts behind the error, Open Graph and CORS middleware. An APIException thrown by a handler becomes the JSON error response there.","url":"./api/routes/password-resets.ts/~/default.html","deprecated":false},{"id":"namespace_default","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"default","file":"api/routes/playlists.ts","doc":"Mounted by api/main.ts behind the error, Open Graph and CORS middleware. An APIException thrown by a handler becomes the JSON error response there.","url":"./api/routes/playlists.ts/~/default.html","deprecated":false},{"id":"namespace_default","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"default","file":"api/routes/remote.ts","doc":"Mounted by api/main.ts behind the error, Open Graph and CORS middleware. An APIException thrown by a handler becomes the JSON error response there.","url":"./api/routes/remote.ts/~/default.html","deprecated":false},{"id":"namespace_default","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"default","file":"api/routes/search.ts","doc":"Mounted by api/main.ts behind the error, Open Graph and CORS middleware. An APIException thrown by a handler becomes the JSON error response there.","url":"./api/routes/search.ts/~/default.html","deprecated":false},{"id":"namespace_default","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"default","file":"api/routes/sessions.ts","doc":"Mounted by api/main.ts behind the error, Open Graph and CORS middleware. An APIException thrown by a handler becomes the JSON error response there.","url":"./api/routes/sessions.ts/~/default.html","deprecated":false},{"id":"namespace_default","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"default","file":"api/routes/thumbnails.ts","doc":"Mounted by api/main.ts behind the error, Open Graph and CORS middleware. An APIException thrown by a handler becomes the JSON error response there.","url":"./api/routes/thumbnails.ts/~/default.html","deprecated":false},{"id":"namespace_default","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"default","file":"api/routes/unsubscribe.ts","doc":"Mounted by api/main.ts behind the error, Open Graph and CORS middleware. An APIException thrown by a handler becomes the JSON error response there.","url":"./api/routes/unsubscribe.ts/~/default.html","deprecated":false},{"id":"namespace_default","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"default","file":"api/routes/users.ts","doc":"Mounted by api/main.ts behind the error, Open Graph and CORS middleware. An APIException thrown by a handler becomes the JSON error response there.","url":"./api/routes/users.ts/~/default.html","deprecated":false},{"id":"namespace_default","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"default","file":"api/routes/waveforms.ts","doc":"Mounted by api/main.ts behind the error, Open Graph and CORS middleware. An APIException thrown by a handler becomes the JSON error response there.","url":"./api/routes/waveforms.ts/~/default.html","deprecated":false},{"id":"namespace_default","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"default","file":"api/routes/well-known.ts","doc":"Mounted by api/main.ts behind the error, Open Graph and CORS middleware. An APIException thrown by a handler becomes the JSON error response there.","url":"./api/routes/well-known.ts/~/default.html","deprecated":false},{"id":"namespace_default","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"default","file":"api/routes/ws.ts","doc":"Mounted by api/main.ts behind the error, Open Graph and CORS middleware. An APIException thrown by a handler becomes the JSON error response there.","url":"./api/routes/ws.ts/~/default.html","deprecated":false},{"id":"namespace_createattachment","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"createAttachment","file":"api/services/attachment-service.ts","doc":"Records attachment id once POST /api/attachments has written its file. Until a saved body links it, the startup purge deletes it after ORPHANED_ATTACHMENTS_RETENTION_HOURS.","url":"./api/services/attachment-service.ts/~/createAttachment.html","deprecated":false},{"id":"namespace_attachmentresourcetype","kind":[{"char":"T","kind":"TypeAlias","title":"Type Alias"}],"name":"AttachmentResourceType","file":"api/services/attachment-service.ts","doc":"Stored in attachments.resource_type by bindAttachments, it names the kind of resource whose saved text links the attachment.","url":"./api/services/attachment-service.ts/~/AttachmentResourceType.html","deprecated":false},{"id":"namespace_attachmentaccess","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"AttachmentAccess","file":"api/services/attachment-service.ts","doc":"Returned to GET /api/attachments/:attachmentId by getAttachmentAccess. ownerId is set when only that user may see the image, because the resource linking it is private.","url":"./api/services/attachment-service.ts/~/AttachmentAccess.html","deprecated":false},{"id":"namespace_attachmentaccess","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"AttachmentAccess.mime","file":"api/services/attachment-service.ts","doc":"","url":"./api/services/attachment-service.ts/~/AttachmentAccess.mime.html","deprecated":false},{"id":"namespace_attachmentaccess","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"AttachmentAccess.ownerId","file":"api/services/attachment-service.ts","doc":"","url":"./api/services/attachment-service.ts/~/AttachmentAccess.ownerId.html","deprecated":false},{"id":"namespace_getattachmentaccess","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"getAttachmentAccess","file":"api/services/attachment-service.ts","doc":"Returns attachment attachmentId's type and who may see it. An attachment nothing links yet is public, so the editor can show it before the text is saved; its id is unguessable. One linked by a private dump or playlist, or by a comment on a private dump, is its owner's.","url":"./api/services/attachment-service.ts/~/getAttachmentAccess.html","deprecated":false},{"id":"namespace_linkattachments","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"linkAttachments","file":"api/services/attachment-service.ts","doc":"Binds the attachments whose URLs appear in text to the resource that saved it, so the startup purge keeps them as long as that resource exists, and they are seen by whoever may see it. It is called whenever a dump, comment, chat message, playlist or profile description is saved. An attachment already bound stays with its resource, so pasting another's URL claims nothing, and removing the link from a body never unbinds it.","url":"./api/services/attachment-service.ts/~/linkAttachments.html","deprecated":false},{"id":"namespace_announcelinksnowpublic","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"announceLinksNowPublic","file":"api/services/backlink-service.ts","doc":"Tells clients that dump dumpId, which just turned public, is now related to the dumps linked to or from it, for the dump service. Its poster saw those links already; to everyone else they are new.","url":"./api/services/backlink-service.ts/~/announceLinksNowPublic.html","deprecated":false},{"id":"namespace_relinkbacklinks","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"relinkBacklinks","file":"api/services/backlink-service.ts","doc":"Replaces the backlinks from one text, a dump's note (dump_comment) or one of its comments (comment), with the links its current text holds. A link counts when it is a dump's page on this site (/@owner/dumps/), or when it is the URL a dump was posted with, compared by canonicalizeUrl as reposts are. The dump and comment services call it on every save, and with an empty text when a comment is deleted. Clients are told of the dumps it links or no longer links, as dump_related_changed.","url":"./api/services/backlink-service.ts/~/relinkBacklinks.html","deprecated":false},{"id":"namespace_getrelateddumps","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"getRelatedDumps","file":"api/services/backlink-service.ts","doc":"Returns the dumps linked to or from dumpId, newest first and at most 20, without the private ones the requesting user can't see. It doesn't check dumpId itself: GET /api/dumps/:dumpId/related does that first.","url":"./api/services/backlink-service.ts/~/getRelatedDumps.html","deprecated":false},{"id":"namespace_getcategorybyid","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"getCategoryById","file":"api/services/category-service.ts","doc":"Returns category id, for updateCategory.","url":"./api/services/category-service.ts/~/getCategoryById.html","deprecated":false},{"id":"namespace_getcategorybyslug","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"getCategoryBySlug","file":"api/services/category-service.ts","doc":"Returns the category of kind at slug, for listDumpsByCategory and the list of every public playlist.","url":"./api/services/category-service.ts/~/getCategoryBySlug.html","deprecated":false},{"id":"namespace_getcategoryidbyslug","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"getCategoryIdBySlug","file":"api/services/category-service.ts","doc":"Returns the id of the category of kind at slug, or undefined when there is none.","url":"./api/services/category-service.ts/~/getCategoryIdBySlug.html","deprecated":false},{"id":"namespace_resolvecategoryfilter","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"resolveCategoryFilter","file":"api/services/category-service.ts","doc":"Returns the id of the category of kind whose slug the name parameter of params, ?category= by default, gives, undefined without one, or \"missing\" when it names none, so that the list comes back empty rather than unfiltered. The users routes filter a profile's lists with it, and the search route its results.","url":"./api/services/category-service.ts/~/resolveCategoryFilter.html","deprecated":false},{"id":"namespace_categoryjoin","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"categoryJoin","file":"api/services/category-service.ts","doc":"Returns the join that keeps only the rows of alias, a dump or playlist as kind says, filed under categoryId, with its parameters, or nothing without one. A query puts the join after its FROM and the parameters before its own.","url":"./api/services/category-service.ts/~/categoryJoin.html","deprecated":false},{"id":"namespace_listcategories","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"listCategories","file":"api/services/category-service.ts","doc":"Returns every category, of both kinds, by kind, position then slug, for GET /api/categories.","url":"./api/services/category-service.ts/~/listCategories.html","deprecated":false},{"id":"namespace_createcategory","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"createCategory","file":"api/services/category-service.ts","doc":"Creates a category, for POST /api/categories. The name is stored trimmed, and the position defaults to 0. Every client is told to fetch the categories again, as after the two writes below.","url":"./api/services/category-service.ts/~/createCategory.html","deprecated":false},{"id":"namespace_updatecategory","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"updateCategory","file":"api/services/category-service.ts","doc":"Applies req to category id, for PUT /api/categories/:id, and returns the category as it now is. Fields req leaves out keep their value.","url":"./api/services/category-service.ts/~/updateCategory.html","deprecated":false},{"id":"namespace_deletecategory","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"deleteCategory","file":"api/services/category-service.ts","doc":"Deletes category id, for DELETE /api/categories/:id. Its dumps or playlists stay, and lose it from their categoryIds.","url":"./api/services/category-service.ts/~/deleteCategory.html","deprecated":false},{"id":"namespace_assertcategoriesexist","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"assertCategoriesExist","file":"api/services/category-service.ts","doc":"Checks that every id in categoryIds names a category of kind, so that a dump is never filed under a playlist category, nor the other way round. The dump and playlist services run it before they write a row or store an uploaded file, so a bad id fails the request before anything is written.","url":"./api/services/category-service.ts/~/assertCategoriesExist.html","deprecated":false},{"id":"namespace_setcategories","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"setCategories","file":"api/services/category-service.ts","doc":"Replaces the categories of the dump or playlist id, as kind says, with categoryIds, duplicates dropped. An empty list takes it out of every category. Called inside the dump or playlist service's transaction, it joins that one.","url":"./api/services/category-service.ts/~/setCategories.html","deprecated":false},{"id":"namespace_attachcategoryids","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"attachCategoryIds","file":"api/services/category-service.ts","doc":"Sets categoryIds on each of items, dumps or playlists as kind says, in place, in one query. Their rows don't carry them, so every service that returns dumps or playlists calls this first.","url":"./api/services/category-service.ts/~/attachCategoryIds.html","deprecated":false},{"id":"namespace_listdumpsbycategory","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"listDumpsByCategory","file":"api/services/category-service.ts","doc":"Returns a page of the dumps in the dump category at slug, newest first, for GET /api/dumps?category=. Private dumps are left out, except requestingUserId's own.","url":"./api/services/category-service.ts/~/listDumpsByCategory.html","deprecated":false},{"id":"namespace_createchatmessage","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"createChatMessage","file":"api/services/chat-service.ts","doc":"Stores a message from userId on a chat_send, and claims the pasted images it links to. A replyToId naming no message is dropped, and the message is posted as no reply. The message mentionsEveryone when it says @everyone and userId may. The caller broadcasts the result, and notifies everyone when it is flagged.","url":"./api/services/chat-service.ts/~/createChatMessage.html","deprecated":false},{"id":"namespace_chatmessagementionseveryone","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"chatMessageMentionsEveryone","file":"api/services/chat-service.ts","doc":"Checks whether message id is flagged mentionsEveryone, false when there is no such message. The WebSocket route reads it before an edit, to notify everyone only when the edit adds @everyone.","url":"./api/services/chat-service.ts/~/chatMessageMentionsEveryone.html","deprecated":false},{"id":"namespace_updatechatmessage","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"updateChatMessage","file":"api/services/chat-service.ts","doc":"Replaces a message's body on a chat_edit, and claims any image the new body links to. canModerate lets a moderator edit anyone's message. The flag mentionsEveryone is set again from the new body and the author's role, not the editor's: a moderator's edit can't make a user's message reach everyone. The caller broadcasts the result.","url":"./api/services/chat-service.ts/~/updateChatMessage.html","deprecated":false},{"id":"namespace_deletechatmessage","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"deleteChatMessage","file":"api/services/chat-service.ts","doc":"Deletes a message on a chat_delete. canModerate lets a moderator delete anyone's message. Replies to it keep their replyToId, without its preview.","url":"./api/services/chat-service.ts/~/deleteChatMessage.html","deprecated":false},{"id":"namespace_chatcursor","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"ChatCursor","file":"api/services/chat-service.ts","doc":"Passed by routes/chat.ts to page through the history, from the message the client already has at one end. Messages are ordered by createdAt, then by id, so a page boundary between two messages sent in the same millisecond skips neither.","url":"./api/services/chat-service.ts/~/ChatCursor.html","deprecated":false},{"id":"namespace_chatcursor","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ChatCursor.createdAt","file":"api/services/chat-service.ts","doc":"An ISO timestamp, compared as a string with created_at.","url":"./api/services/chat-service.ts/~/ChatCursor.createdAt.html","deprecated":false},{"id":"namespace_chatcursor","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ChatCursor.id","file":"api/services/chat-service.ts","doc":"Without it, the cursor takes in every message at createdAt: they are all older for getRecentChatMessages and all newer for getChatMessagesAfter.","url":"./api/services/chat-service.ts/~/ChatCursor.id.html","deprecated":false},{"id":"namespace_getrecentchatmessages","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"getRecentChatMessages","file":"api/services/chat-service.ts","doc":"Returns the latest limit messages, or with before the limit messages just older than it, oldest first either way. limit is clamped to 1–100.","url":"./api/services/chat-service.ts/~/getRecentChatMessages.html","deprecated":false},{"id":"namespace_getchatmessagesafter","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"getChatMessagesAfter","file":"api/services/chat-service.ts","doc":"Returns the first limit messages after after, oldest first. The chatbox uses it to fetch what it missed while the socket was down. limit is clamped to 1–100.","url":"./api/services/chat-service.ts/~/getChatMessagesAfter.html","deprecated":false},{"id":"namespace_chatreadstate","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"ChatReadState","file":"api/services/chat-service.ts","doc":"Returned to the WebSocket route by getChatReadState and markChatRead. The route sends it in welcome and in chat_read_update, and the client shows unread on the chat's badge.","url":"./api/services/chat-service.ts/~/ChatReadState.html","deprecated":false},{"id":"namespace_chatreadstate","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ChatReadState.readAt","file":"api/services/chat-service.ts","doc":"The created_at of the newest message the user has read.","url":"./api/services/chat-service.ts/~/ChatReadState.readAt.html","deprecated":false},{"id":"namespace_chatreadstate","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ChatReadState.unread","file":"api/services/chat-service.ts","doc":"Counts only the messages of other users after readAt.","url":"./api/services/chat-service.ts/~/ChatReadState.unread.html","deprecated":false},{"id":"namespace_getchatreadstate","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"getChatReadState","file":"api/services/chat-service.ts","doc":"Returns how far userId has read the chat. A user who never opened it has read up to their registration, so the history from before it isn't unread.","url":"./api/services/chat-service.ts/~/getChatReadState.html","deprecated":false},{"id":"namespace_markchatread","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"markChatRead","file":"api/services/chat-service.ts","doc":"Moves userId's read marker to at, a message's created_at, on a chat_read. It never moves back, so a lagging tab can't undo a newer tab's read. It never passes the newest message, so a timestamp from the future can't mark messages read before they are sent.","url":"./api/services/chat-service.ts/~/markChatRead.html","deprecated":false},{"id":"namespace_likeresult","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"LikeResult","file":"api/services/comment-like-service.ts","doc":"Returned to the WebSocket route by castCommentLike and removeCommentLike. The route acks the liker with likeCount, then broadcasts it to every client, or to the liker's alone when the comment's dump isPrivate.","url":"./api/services/comment-like-service.ts/~/LikeResult.html","deprecated":false},{"id":"namespace_likeresult","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"LikeResult.likeCount","file":"api/services/comment-like-service.ts","doc":"","url":"./api/services/comment-like-service.ts/~/LikeResult.likeCount.html","deprecated":false},{"id":"namespace_likeresult","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"LikeResult.isPrivate","file":"api/services/comment-like-service.ts","doc":"","url":"./api/services/comment-like-service.ts/~/LikeResult.isPrivate.html","deprecated":false},{"id":"namespace_castcommentlike","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"castCommentLike","file":"api/services/comment-like-service.ts","doc":"Records userId's like on a comment and notifies the comment's author. The notification is best-effort: if it fails, the like still counts.","url":"./api/services/comment-like-service.ts/~/castCommentLike.html","deprecated":false},{"id":"namespace_removecommentlike","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"removeCommentLike","file":"api/services/comment-like-service.ts","doc":"Takes back userId's like on a comment. It doesn't check that the user can still see the comment, since a like on a dump that has gone private is still theirs to take back.","url":"./api/services/comment-like-service.ts/~/removeCommentLike.html","deprecated":false},{"id":"namespace_getusercommentlikes","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"getUserCommentLikes","file":"api/services/comment-like-service.ts","doc":"Returns the ids of the comments userId likes. The WebSocket route sends them in its welcome message, and the client shows those like buttons pressed.","url":"./api/services/comment-like-service.ts/~/getUserCommentLikes.html","deprecated":false},{"id":"namespace_getcommentlikers","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"getCommentLikers","file":"api/services/comment-like-service.ts","doc":"Returns a page of the users who like a comment, latest like first, for GET /api/comments/:commentId/likers. It doesn't check that the caller may see the comment: the route does that first, with getDump.","url":"./api/services/comment-like-service.ts/~/getCommentLikers.html","deprecated":false},{"id":"namespace_getcommentdumpid","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"getCommentDumpId","file":"api/services/comment-service.ts","doc":"Returns the id of the dump comment commentId is posted under. The likers route uses it to check that the caller may see that dump.","url":"./api/services/comment-service.ts/~/getCommentDumpId.html","deprecated":false},{"id":"namespace_getcomments","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"getComments","file":"api/services/comment-service.ts","doc":"Returns every comment on dump dumpId, oldest first, for GET /api/dumps/:dumpId/comments. Deleted comments are included, emptied, so the client can keep their replies in place.","url":"./api/services/comment-service.ts/~/getComments.html","deprecated":false},{"id":"namespace_createcomment","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"createComment","file":"api/services/comment-service.ts","doc":"Posts a comment on dump dumpId, replying to parentId if given, for POST /api/dumps/:dumpId/comments. It notifies the dump's poster and the users it mentions, unless the dump is private, and links the comment's attachments and backlinks. The route has checked that the caller may see the dump.","url":"./api/services/comment-service.ts/~/createComment.html","deprecated":false},{"id":"namespace_commentdump","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"CommentDump","file":"api/services/comment-service.ts","doc":"The dump a comment is on, as updateComment and deleteComment return it: what the route needs to choose the broadcast's audience.","url":"./api/services/comment-service.ts/~/CommentDump.html","deprecated":false},{"id":"namespace_commentdump","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommentDump.id","file":"api/services/comment-service.ts","doc":"","url":"./api/services/comment-service.ts/~/CommentDump.id.html","deprecated":false},{"id":"namespace_commentdump","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommentDump.isPrivate","file":"api/services/comment-service.ts","doc":"","url":"./api/services/comment-service.ts/~/CommentDump.isPrivate.html","deprecated":false},{"id":"namespace_commentdump","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommentDump.userId","file":"api/services/comment-service.ts","doc":"The dump's poster, the only one who sees a private dump's comments.","url":"./api/services/comment-service.ts/~/CommentDump.userId.html","deprecated":false},{"id":"namespace_updatecomment","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"updateComment","file":"api/services/comment-service.ts","doc":"Replaces a comment's body, for PATCH /api/comments/:commentId. canModerate lets someone other than the author do it. It notifies, in the author's name, the users it mentions for the first time, unless the dump is private, and relinks the attachments and backlinks. The route broadcasts the comment to those who may see its dump.","url":"./api/services/comment-service.ts/~/updateComment.html","deprecated":false},{"id":"namespace_deletecomment","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"deleteComment","file":"api/services/comment-service.ts","doc":"Deletes a comment, for DELETE /api/comments/:commentId. canModerate lets someone other than the author do it. The body is emptied and the backlinks dropped, but the row stays so its replies keep their place. The route broadcasts the deletion to those who may see the returned dump.","url":"./api/services/comment-service.ts/~/deleteComment.html","deprecated":false},{"id":"namespace_communitystatsof","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"communityStatsOf","file":"api/services/community-service.ts","doc":"Returns what the site did from from to to: its most upvoted public dumps, who joined, the new public playlists, the chat's messages and the totals.","url":"./api/services/community-service.ts/~/communityStatsOf.html","deprecated":false},{"id":"namespace_refreshcommunitystats","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"refreshCommunityStats","file":"api/services/community-service.ts","doc":"Recomputes the figures of each period, ending at now.","url":"./api/services/community-service.ts/~/refreshCommunityStats.html","deprecated":false},{"id":"namespace_getcommunitystats","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"getCommunityStats","file":"api/services/community-service.ts","doc":"Returns the figures of period as of the last refresh, for GET /api/community, refreshing them first if there are none yet.","url":"./api/services/community-service.ts/~/getCommunityStats.html","deprecated":false},{"id":"namespace_communityjob","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"communityJob","file":"api/services/community-service.ts","doc":"Refreshes the figures at startup, then every COMMUNITY_REFRESH_MINUTES. main.ts starts it.","url":"./api/services/community-service.ts/~/communityJob.html","deprecated":false},{"id":"namespace_listcommunityevents","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"listCommunityEvents","file":"api/services/community-service.ts","doc":"Returns the latest things done in public, newest first, FEED_MAX at most: the public dumps posted and playlists created, the comments and upvotes on public dumps, and who joined. A dump has one comment event and one upvote event at most, its latest, so that a thread or a popular dump doesn't fill the feed.Each part reads its FEED_MAX latest, which is all the whole may keep of it. The comments and the upvotes are grouped by dump first, and with MAX() SQLite fills a group's other columns from the row that holds the maximum: the latest comment's author and id, the latest voter.","url":"./api/services/community-service.ts/~/listCommunityEvents.html","deprecated":false},{"id":"namespace_getcommunityfeed","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"getCommunityFeed","file":"api/services/community-service.ts","doc":"Returns the community feed for GET /api/community/feed: the latest events, read now, and the last week's figures as of the last refresh.","url":"./api/services/community-service.ts/~/getCommunityFeed.html","deprecated":false},{"id":"namespace_builddigest","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"buildDigest","file":"api/services/digest-service.ts","doc":"Returns the digest of user readerId for the period from from to to, or null when it would show nothing. The links are absolute; the unsubscribe one carries token, which turns off cadence.","url":"./api/services/digest-service.ts/~/buildDigest.html","deprecated":false},{"id":"namespace_syncdigestschedules","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"syncDigestSchedules","file":"api/services/digest-service.ts","doc":"Brings digest_schedule in line with the settings: a user who turned a cadence off loses its row, and one who receives it without a row, being new or having turned it back on, starts a period at now.","url":"./api/services/digest-service.ts/~/syncDigestSchedules.html","deprecated":false},{"id":"namespace_sendduedigests","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"sendDueDigests","file":"api/services/digest-service.ts","doc":"Sends every digest due at now, one after the other, and returns how many went out. A digest that fails to send is logged and not retried: its period is over either way, and the next one starts.","url":"./api/services/digest-service.ts/~/sendDueDigests.html","deprecated":false},{"id":"namespace_digestjob","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"digestJob","file":"api/services/digest-service.ts","doc":"Sends the due digests a minute after the server starts, then every quarter of an hour. main.ts starts it.","url":"./api/services/digest-service.ts/~/digestJob.html","deprecated":false},{"id":"namespace_createurldump","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"createUrlDump","file":"api/services/dump-service.ts","doc":"Posts a link as userId, for POST /api/dumps, with its preview fetched from the page. A public dump is broadcast as dump_created and notified to the poster's followers. Anyone @mentioned in the note is notified even when the dump is private.","url":"./api/services/dump-service.ts/~/createUrlDump.html","deprecated":false},{"id":"namespace_createfiledump","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"createFileDump","file":"api/services/dump-service.ts","doc":"Posts an uploaded file as userId, for POST /api/dumps, and stores it in DUMPS_DIR under the dump's id. It is announced and notified as createUrlDump does.","url":"./api/services/dump-service.ts/~/createFileDump.html","deprecated":false},{"id":"namespace_getdump","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"getDump","file":"api/services/dump-service.ts","doc":"Returns dump dumpId as requestingUserId may see it. The routes resolve every :dumpId with it before acting on the dump.","url":"./api/services/dump-service.ts/~/getDump.html","deprecated":false},{"id":"namespace_getdumpbypath","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"getDumpByPath","file":"api/services/dump-service.ts","doc":"Returns the dump of userId's whose slug is or was slug, as requestingUserId may see it, for GET /api/users/:key/dumps/:slug, which reads a dump by its page's path. Reached by a former slug, it comes with its current one, which the client puts in its URL.","url":"./api/services/dump-service.ts/~/getDumpByPath.html","deprecated":false},{"id":"namespace_searchdumps","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"searchDumps","file":"api/services/dump-service.ts","doc":"Returns a page of the dumps requestingUserId may see whose title, note, or previewed title or description contains query, newest first, with how many match in all, optionally only those in the dump category categoryId. GET /api/search calls it.","url":"./api/services/dump-service.ts/~/searchDumps.html","deprecated":false},{"id":"namespace_listdumps","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"listDumps","file":"api/services/dump-service.ts","doc":"Returns a page of the dumps requestingUserId may see, newest first, for the index feed (GET /api/dumps).","url":"./api/services/dump-service.ts/~/listDumps.html","deprecated":false},{"id":"namespace_listtopdumps","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"listTopDumps","file":"api/services/dump-service.ts","doc":"Returns the limit most upvoted public dumps posted from from to to, the newer first on a tie, leaving out those no one upvoted. The community service gathers them for the /community page and the digests.","url":"./api/services/dump-service.ts/~/listTopDumps.html","deprecated":false},{"id":"namespace_finddumpsbyurl","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"findDumpsByUrl","file":"api/services/dump-service.ts","doc":"Returns the dumps requestingUserId may see that were posted with the same link as url, newest first, for the create form's duplicate notice (GET /api/dumps?url=). Links are compared in their canonical form, so tracking parameters, the scheme, www. or a YouTube share format don't hide a repost.","url":"./api/services/dump-service.ts/~/findDumpsByUrl.html","deprecated":false},{"id":"namespace_updatedump","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"updateDump","file":"api/services/dump-service.ts","doc":"Applies request to a dump, for PUT /api/dumps/:dumpId. A new link has its preview fetched and gives the dump its page's title, unless request sets one. A file dump ignores url. A new slug goes through changeSlug, which exempt (a moderator) frees from its rate limit; a new title leaves the slug as it is. Clients get the dump as dump_updated, or a dump_deleted when it turns private and a dump_created when it turns public. Anyone @mentioned in the note is notified, and when it turns public, its followers are as when it is posted (notifyIfWentPublic).","url":"./api/services/dump-service.ts/~/updateDump.html","deprecated":false},{"id":"namespace_replacefiledump","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"replaceFileDump","file":"api/services/dump-service.ts","doc":"Replaces a file dump's upload and its comment, for PUT /api/dumps/:dumpId/file. A title, slug, categoryIds or isPrivate left out stays as it is. Visibility is taken here so that a new file and a change of visibility land together. The slug changes as in updateDump, before the file is written. The old file is put back if the database update fails, and clients and followers are told as updateDump tells them.","url":"./api/services/dump-service.ts/~/replaceFileDump.html","deprecated":false},{"id":"namespace_getdumpsbyuser","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"getDumpsByUser","file":"api/services/dump-service.ts","doc":"Returns a page of userId's dumps, newest first, for GET /api/users/:key/dumps, optionally only those in categoryId. The route sets includePrivate when users ask for their own.","url":"./api/services/dump-service.ts/~/getDumpsByUser.html","deprecated":false},{"id":"namespace_getvoteddumpsbyuser","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"getVotedDumpsByUser","file":"api/services/dump-service.ts","doc":"Returns a page of the dumps userId upvoted, latest vote first, for GET /api/users/:key/upvoted, optionally only those in categoryId. Their own private dumps are included only when they are the one asking.","url":"./api/services/dump-service.ts/~/getVotedDumpsByUser.html","deprecated":false},{"id":"namespace_refreshdumpmetadata","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"refreshDumpMetadata","file":"api/services/dump-service.ts","doc":"Fetches a URL dump's preview again, bypassing the cache, and replaces its title and preview, for POST /api/dumps/:dumpId/metadata. The slug stays.","url":"./api/services/dump-service.ts/~/refreshDumpMetadata.html","deprecated":false},{"id":"namespace_customthumbnailpath","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"customThumbnailPath","file":"api/services/dump-service.ts","doc":"Returns where dump dumpId's custom thumbnail is kept: the thumbnail route writes and serves it, and this service deletes it with the thumbnail or the dump.","url":"./api/services/dump-service.ts/~/customThumbnailPath.html","deprecated":false},{"id":"namespace_setdumpthumbnail","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"setDumpThumbnail","file":"api/services/dump-service.ts","doc":"Records that a dump has a custom thumbnail of type mime, for PUT /api/dumps/:dumpId/thumbnail, once the route has written the file.","url":"./api/services/dump-service.ts/~/setDumpThumbnail.html","deprecated":false},{"id":"namespace_removedumpthumbnail","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"removeDumpThumbnail","file":"api/services/dump-service.ts","doc":"Removes a dump's custom thumbnail and its file, for DELETE /api/dumps/:dumpId/thumbnail.","url":"./api/services/dump-service.ts/~/removeDumpThumbnail.html","deprecated":false},{"id":"namespace_deletedump","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"deleteDump","file":"api/services/dump-service.ts","doc":"Deletes a dump with its files and thumbnails, for DELETE /api/dumps/:dumpId, and broadcasts dump_deleted and the new dumps of the playlists that held it.","url":"./api/services/dump-service.ts/~/deleteDump.html","deprecated":false},{"id":"namespace_outgoingemail","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"OutgoingEmail","file":"api/services/email-service.ts","doc":"Passed to sendEmail: a rendered email, its recipient, and the headers some emails add (the digests' List-Unsubscribe).","url":"./api/services/email-service.ts/~/OutgoingEmail.html","deprecated":false},{"id":"namespace_outgoingemail","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"OutgoingEmail.to","file":"api/services/email-service.ts","doc":"","url":"./api/services/email-service.ts/~/OutgoingEmail.to.html","deprecated":false},{"id":"namespace_outgoingemail","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"OutgoingEmail.headers","file":"api/services/email-service.ts","doc":"","url":"./api/services/email-service.ts/~/OutgoingEmail.headers.html","deprecated":false},{"id":"namespace_emailtransport","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"EmailTransport","file":"api/services/email-service.ts","doc":"Hands a message to a mail server. nodemailer's SMTP transport is one, and the tests put a recording one in its place with setEmailTransport.","url":"./api/services/email-service.ts/~/EmailTransport.html","deprecated":false},{"id":"namespace_emailtransport","kind":[{"char":"m","kind":"Method","title":"Method"}],"name":"EmailTransport.sendMail","file":"api/services/email-service.ts","doc":"","url":"./api/services/email-service.ts/~/EmailTransport.sendMail.html","deprecated":false},{"id":"namespace_isemailenabled","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"isEmailEnabled","file":"api/services/email-service.ts","doc":"Checks whether email can be sent. Without an SMTP server, sign-up sends no welcome email, a password reset request does nothing, and no digest goes out.","url":"./api/services/email-service.ts/~/isEmailEnabled.html","deprecated":false},{"id":"namespace_setemailtransport","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"setEmailTransport","file":"api/services/email-service.ts","doc":"Replaces the transport, so that email is enabled and every message goes to next; null disables email again. The tests use it to read what was sent.","url":"./api/services/email-service.ts/~/setEmailTransport.html","deprecated":false},{"id":"namespace_sendemail","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"sendEmail","file":"api/services/email-service.ts","doc":"Sends email from FROM_EMAIL and resolves once the SMTP server has accepted it. The welcome and reset emails don't wait for it: a slow server mustn't hold up the request.","url":"./api/services/email-service.ts/~/sendEmail.html","deprecated":false},{"id":"namespace_getpeerstatus","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"getPeerStatus","file":"api/services/federation-peer-service.ts","doc":"Returns what an admin decided about the instance at issuer, or null when it is on neither list.","url":"./api/services/federation-peer-service.ts/~/getPeerStatus.html","deprecated":false},{"id":"namespace_listpeers","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"listPeers","file":"api/services/federation-peer-service.ts","doc":"Returns the instances on the lists, by name: every one for /manage, or only the trusted ones, which the login page offers.","url":"./api/services/federation-peer-service.ts/~/listPeers.html","deprecated":false},{"id":"namespace_setpeer","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"setPeer","file":"api/services/federation-peer-service.ts","doc":"Puts the instance instance names, by its API's address or its pages' (resolveIssuer), on the list of status, for /manage, and returns it. A trusted one must answer as a gerbeur instance, whose name is kept; a blocked one is blocked whether it answers or not, keeping the name it had. Blocking one ends the sessions of its users here at once: their tokens stop counting by getSessionState, and this closes their sockets.","url":"./api/services/federation-peer-service.ts/~/setPeer.html","deprecated":false},{"id":"namespace_removepeer","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"removePeer","file":"api/services/federation-peer-service.ts","doc":"Takes the instance whose host is host off the lists, for /manage: its users are invite only again, and those already here may sign in again if it was blocked.","url":"./api/services/federation-peer-service.ts/~/removePeer.html","deprecated":false},{"id":"namespace_startlogin","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"startLogin","file":"api/services/federation-service.ts","doc":"Starts a sign-in with an account on the instance request.instance names, and returns its /authorize page with the request, for POST /api/federation/logins. Unless that instance is trusted, or someone here already comes from it, the request must carry a valid invite, which is claimed only once the account is made; completeLogin makes no account without one.","url":"./api/services/federation-service.ts/~/startLogin.html","deprecated":false},{"id":"namespace_completelogin","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"completeLogin","file":"api/services/federation-service.ts","doc":"Finishes a sign-in begun by startLogin, for POST /api/federation/sessions, and returns the account it signs in to: the one linked to the identity, brought up to date, or a new one. A login works once. A new account needs the home to be trusted, or the invite the login was started with, claimed now.","url":"./api/services/federation-service.ts/~/completeLogin.html","deprecated":false},{"id":"namespace_receiveevent","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"receiveEvent","file":"api/services/federation-service.ts","doc":"Applies the signed event token from a user's home, for POST /api/federation/events: update brings their account in step, revoke ends their sessions here. Only an instance some account here comes from, and not blocked, may send one, about one of those accounts, and at most EVENT_LIMIT's rate. The sender gives up on an event at a 4xx other than 429, and tries it again later otherwise.","url":"./api/services/federation-service.ts/~/receiveEvent.html","deprecated":false},{"id":"namespace_homepageurl","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"homePageUrl","file":"api/services/federation-service.ts","doc":"Returns the URL of path on the home of user, an account from another instance, for GET /api/users/:key/home: their profile there by default, or another of its pages, such as /settings, where they change their password. A handle's host is its home's issuer, the API's origin, which needn't be its pages': those are where its /authorize page is, and the home's metadata says. While it doesn't answer, the issuer stands in.","url":"./api/services/federation-service.ts/~/homePageUrl.html","deprecated":false},{"id":"namespace_followuser","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"followUser","file":"api/services/follow-service.ts","doc":"Makes followerId follow followedUserId, and notifies the followed user. Following again changes nothing. The follower's other tabs are told.","url":"./api/services/follow-service.ts/~/followUser.html","deprecated":false},{"id":"namespace_unfollowuser","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"unfollowUser","file":"api/services/follow-service.ts","doc":"Makes followerId stop following followedUserId, if they did.","url":"./api/services/follow-service.ts/~/unfollowUser.html","deprecated":false},{"id":"namespace_followplaylist","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"followPlaylist","file":"api/services/follow-service.ts","doc":"Makes followerId follow a public playlist, and notifies its owner. Following again changes nothing. A follow outlives the playlist going private, but the feeds and lists skip it while it is.","url":"./api/services/follow-service.ts/~/followPlaylist.html","deprecated":false},{"id":"namespace_unfollowplaylist","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"unfollowPlaylist","file":"api/services/follow-service.ts","doc":"Makes followerId stop following a playlist, if they did.","url":"./api/services/follow-service.ts/~/unfollowPlaylist.html","deprecated":false},{"id":"namespace_getfollowstatus","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"getFollowStatus","file":"api/services/follow-service.ts","doc":"Returns the ids of every user and playlist followerId follows, private playlists included, for GET /api/me/follow.","url":"./api/services/follow-service.ts/~/getFollowStatus.html","deprecated":false},{"id":"namespace_getfollowedusersdumpfeed","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"getFollowedUsersDumpFeed","file":"api/services/follow-service.ts","doc":"Returns a page of the public dumps posted by the users followerId follows, newest first, optionally only those in categoryId. It feeds the \"users\" half of the index's \"followed\" tab.","url":"./api/services/follow-service.ts/~/getFollowedUsersDumpFeed.html","deprecated":false},{"id":"namespace_getfollowedplaylistsdumpfeed","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"getFollowedPlaylistsDumpFeed","file":"api/services/follow-service.ts","doc":"Returns a page of the public dumps in the public playlists followerId follows, optionally only those in categoryId. It feeds the \"playlists\" half of the index's \"followed\" tab. A dump in several of them shows once, dated by its latest addition.","url":"./api/services/follow-service.ts/~/getFollowedPlaylistsDumpFeed.html","deprecated":false},{"id":"namespace_getfollowedplaylistsbyuser","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"getFollowedPlaylistsByUser","file":"api/services/follow-service.ts","doc":"Returns a page of the public playlists userId follows, most recently followed first, for their profile and playlists pages. Their dumps are counted for requestingUserId, null being a signed-out viewer.","url":"./api/services/follow-service.ts/~/getFollowedPlaylistsByUser.html","deprecated":false},{"id":"namespace_getfollowedusersbyuser","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"getFollowedUsersByUser","file":"api/services/follow-service.ts","doc":"Returns a page of the users userId follows, most recently followed first, for their profile page. The users carry their password hash and email: pass them through toPublicUser before sending them.","url":"./api/services/follow-service.ts/~/getFollowedUsersByUser.html","deprecated":false},{"id":"namespace_issuer","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"ISSUER","file":"api/services/identity-provider-service.ts","doc":"The instance's name in every token it signs and every token addressed to it: its public URL, which must be an origin for other instances to find its metadata.","url":"./api/services/identity-provider-service.ts/~/ISSUER.html","deprecated":false},{"id":"namespace_redirect_uri","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"REDIRECT_URI","file":"api/services/identity-provider-service.ts","doc":"The client's page a home instance sends the user back to, on the frontend. Its metadata announces it, and a home accepts no other.","url":"./api/services/identity-provider-service.ts/~/REDIRECT_URI.html","deprecated":false},{"id":"namespace_getinstancemetadata","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"getInstanceMetadata","file":"api/services/identity-provider-service.ts","doc":"Returns the instance's metadata, served at /.well-known/openid-configuration.","url":"./api/services/identity-provider-service.ts/~/getInstanceMetadata.html","deprecated":false},{"id":"namespace_identityclaims","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"identityClaims","file":"api/services/identity-provider-service.ts","doc":"Returns what this instance tells another of user: their name, email and avatar, whose URL changes with each new one, so that a client fetches it again only then.","url":"./api/services/identity-provider-service.ts/~/identityClaims.html","deprecated":false},{"id":"namespace_describeclient","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"describeClient","file":"api/services/identity-provider-service.ts","doc":"Returns the instance clientId names, for the /authorize page's question to user userId, and whether they already let it sign them in.","url":"./api/services/identity-provider-service.ts/~/describeClient.html","deprecated":false},{"id":"namespace_createauthorizationcode","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"createAuthorizationCode","file":"api/services/identity-provider-service.ts","doc":"Records user userId's consent to sign in to the client of request, and returns where to send them: the client's callback page with a code, which the client trades within a minute (exchangeCode). The grant lasts until they withdraw it, so the page asks no more.","url":"./api/services/identity-provider-service.ts/~/createAuthorizationCode.html","deprecated":false},{"id":"namespace_exchangecode","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"exchangeCode","file":"api/services/identity-provider-service.ts","doc":"Trades a code for an identity token, for POST /api/oauth/tokens, which the client calls server to server with the form params. A code works once, within a minute, for the client and redirect it was made for, and with the verifier whose hash the request carried (PKCE). The token, signed with the instance key and addressed to the client, carries identityClaims and the request's nonce.","url":"./api/services/identity-provider-service.ts/~/exchangeCode.html","deprecated":false},{"id":"namespace_listgrants","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"listGrants","file":"api/services/identity-provider-service.ts","doc":"Returns the instances user userId let their account sign in to, the most recently used first, for the settings page.","url":"./api/services/identity-provider-service.ts/~/listGrants.html","deprecated":false},{"id":"namespace_revokegrant","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"revokeGrant","file":"api/services/identity-provider-service.ts","doc":"Withdraws user userId's grant to the instance whose host is host: it stops answering for them there, and is told to end their sessions.","url":"./api/services/identity-provider-service.ts/~/revokeGrant.html","deprecated":false},{"id":"namespace_withdrawallgrants","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"withdrawAllGrants","file":"api/services/identity-provider-service.ts","doc":"Withdraws every grant, as each user would theirs, and drops the codes not yet traded, so that no account here stays signed in elsewhere: main.ts calls it at startup when FEDERATION.outgoing is off. Returns how many grants it withdrew.","url":"./api/services/identity-provider-service.ts/~/withdrawAllGrants.html","deprecated":false},{"id":"namespace_notifyclients","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"notifyClients","file":"api/services/identity-provider-service.ts","doc":"Tells each instance user userId signed in to of event, or only those of clientIds: update when their name, email or avatar changed, revoke when their sessions there must end. The routes that change a user call it, and for an update, event may be just the type: the claims are read now. The events are queued in the outbox and their delivery starts at once, after those queued before for the same instance (deliverTo).","url":"./api/services/identity-provider-service.ts/~/notifyClients.html","deprecated":false},{"id":"namespace_deliveroutbox","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"deliverOutbox","file":"api/services/identity-provider-service.ts","doc":"Sends the outbox's events to each instance that has some, every instance at once so that one that doesn't answer delays none of the others.","url":"./api/services/identity-provider-service.ts/~/deliverOutbox.html","deprecated":false},{"id":"namespace_outboxjob","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"outboxJob","file":"api/services/identity-provider-service.ts","doc":"Retries the outbox's failed events every minute.","url":"./api/services/identity-provider-service.ts/~/outboxJob.html","deprecated":false},{"id":"namespace_getsigningkey","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"getSigningKey","file":"api/services/instance-key-service.ts","doc":"Returns the key the instance signs with now: the newest stored, or a new one, stored, when there is none.","url":"./api/services/instance-key-service.ts/~/getSigningKey.html","deprecated":false},{"id":"namespace_getpublickeys","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"getPublicKeys","file":"api/services/instance-key-service.ts","doc":"Returns the public halves of every stored key, for GET /.well-known/jwks.json. It makes the first key when there is none, so that the set is never empty.","url":"./api/services/instance-key-service.ts/~/getPublicKeys.html","deprecated":false},{"id":"namespace_resetsigningkey","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"resetSigningKey","file":"api/services/instance-key-service.ts","doc":"Forgets the loaded key, for the tests, which wipe the table between cases.","url":"./api/services/instance-key-service.ts/~/resetSigningKey.html","deprecated":false},{"id":"namespace_createinvite","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"createInvite","file":"api/services/invite-service.ts","doc":"Makes an invite from inviterId and returns its token, which the client puts in the invite link.","url":"./api/services/invite-service.ts/~/createInvite.html","deprecated":false},{"id":"namespace_validateinvite","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"validateInvite","file":"api/services/invite-service.ts","doc":"Returns the id of the inviter when invite token is unused and still in its window, which is the one after which db/startup.ts purges it. It doesn't claim the invite: sign-up goes through claimInvite.","url":"./api/services/invite-service.ts/~/validateInvite.html","deprecated":false},{"id":"namespace_claiminvite","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"claimInvite","file":"api/services/invite-service.ts","doc":"Marks invite token used and returns the inviter's id. Call it before the async account creation, and releaseInvite if that fails: checking first and marking after would let parallel sign-ups share one invite.","url":"./api/services/invite-service.ts/~/claimInvite.html","deprecated":false},{"id":"namespace_releaseinvite","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"releaseInvite","file":"api/services/invite-service.ts","doc":"Makes a claimed invite usable again, when the sign-up that claimed it failed.","url":"./api/services/invite-service.ts/~/releaseInvite.html","deprecated":false},{"id":"namespace_withcurrentrefs","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"withCurrentRefs","file":"api/services/notification-service.ts","doc":"Returns data with what may have changed since it was stored joined from the database: each user's current name, and the slug and owner of its dump and playlist, which the client builds their paths from. A user since deleted keeps their stored name; a deleted dump or playlist gets no ref, and so no link. Every notification the server sends goes through it, and so do the digests.","url":"./api/services/notification-service.ts/~/withCurrentRefs.html","deprecated":false},{"id":"namespace_getnotificationsforuser","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"getNotificationsForUser","file":"api/services/notification-service.ts","doc":"Returns a page of userId's notifications, newest first, with their refs joined, for GET /api/me/notifications.","url":"./api/services/notification-service.ts/~/getNotificationsForUser.html","deprecated":false},{"id":"namespace_getunreadcount","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"getUnreadCount","file":"api/services/notification-service.ts","doc":"Returns how many of userId's notifications are unread. The WebSocket route sends it in its welcome message, for the bell's count.","url":"./api/services/notification-service.ts/~/getUnreadCount.html","deprecated":false},{"id":"namespace_markallread","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"markAllRead","file":"api/services/notification-service.ts","doc":"Marks every notification of userId read, when they open the /notifications page, and tells all their sockets, so that the bell clears in their other tabs and devices too.","url":"./api/services/notification-service.ts/~/markAllRead.html","deprecated":false},{"id":"namespace_notifyusernewfollower","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"notifyUserNewFollower","file":"api/services/notification-service.ts","doc":"Notifies followedUserId that followerId follows them, once however often they unfollow and follow again. followUser calls it.","url":"./api/services/notification-service.ts/~/notifyUserNewFollower.html","deprecated":false},{"id":"namespace_notifyplaylistownernewfollower","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"notifyPlaylistOwnerNewFollower","file":"api/services/notification-service.ts","doc":"Notifies a playlist's owner that followerId follows it, unless they are the owner, and once however often they unfollow and follow again. followPlaylist calls it.","url":"./api/services/notification-service.ts/~/notifyPlaylistOwnerNewFollower.html","deprecated":false},{"id":"namespace_notifyuserfollowersnewdump","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"notifyUserFollowersNewDump","file":"api/services/notification-service.ts","doc":"Notifies everyone following dumperId that they posted a dump. The dump service calls it for a public dump only, when it is created or goes public. A follower is told of a dump once, however often it goes private and public again.","url":"./api/services/notification-service.ts/~/notifyUserFollowersNewDump.html","deprecated":false},{"id":"namespace_notifydumpownerupvote","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"notifyDumpOwnerUpvote","file":"api/services/notification-service.ts","doc":"Notifies a dump's poster that voterId upvoted it, unless they are the poster, and once however often the vote is withdrawn and cast again. castVote calls it.","url":"./api/services/notification-service.ts/~/notifyDumpOwnerUpvote.html","deprecated":false},{"id":"namespace_notifymentions","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"notifyMentions","file":"api/services/notification-service.ts","doc":"Notifies every user @mentioned in body, except its author, that they were mentioned in the comment, dump, playlist or chat message contextId. Call it again after each edit: a user already notified for this context isn't notified twice. skipUserId spares a mentioned user; the chat uses it for those who have it open.","url":"./api/services/notification-service.ts/~/notifyMentions.html","deprecated":false},{"id":"namespace_notifyeveryone","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"notifyEveryone","file":"api/services/notification-service.ts","doc":"Notifies every user but its author of chat message messageId, which says @everyone. The WebSocket route calls it, after notifyMentions so that a user also named is told by name, when the message is sent flagged mentionsEveryone, or when an edit flags it. Each user is notified once per message, however often it is edited. skipUserId spares the users who have the chat open, as for a mention.","url":"./api/services/notification-service.ts/~/notifyEveryone.html","deprecated":false},{"id":"namespace_notifydumpownernewcomment","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"notifyDumpOwnerNewComment","file":"api/services/notification-service.ts","doc":"Notifies a dump's poster that commenterId commented on it, unless they are the poster. createComment calls it for replies too, but not on an edit.","url":"./api/services/notification-service.ts/~/notifyDumpOwnerNewComment.html","deprecated":false},{"id":"namespace_notifycommentownerlike","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"notifyCommentOwnerLike","file":"api/services/notification-service.ts","doc":"Notifies a comment's author that likerId likes it, unless they are the author, and once however often the like is withdrawn and given again.","url":"./api/services/notification-service.ts/~/notifyCommentOwnerLike.html","deprecated":false},{"id":"namespace_notifyplaylistfollowersnewdump","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"notifyPlaylistFollowersNewDump","file":"api/services/notification-service.ts","doc":"Notifies everyone following a playlist that a dump was added to it. The playlist service calls it only when both are public, since a follower can't open a private one.","url":"./api/services/notification-service.ts/~/notifyPlaylistFollowersNewDump.html","deprecated":false},{"id":"namespace_notifyplaylistfollowersnowpublic","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"notifyPlaylistFollowersNowPublic","file":"api/services/notification-service.ts","doc":"Notifies the followers of each playlist of the dumps in it that became visible to them: a playlist's followers are told of a dump once both are public. The dump service calls it with dumpId when a dump goes public, for each public playlist holding it; the playlist service with playlistId when a playlist goes public, for each public dump in it, from the bottom of the playlist up. A dump the followers were told of before either went private isn't notified again. Adding a dump to a public playlist calls notifyPlaylistFollowersNewDump directly.","url":"./api/services/notification-service.ts/~/notifyPlaylistFollowersNowPublic.html","deprecated":false},{"id":"namespace_requestpasswordreset","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"requestPasswordReset","file":"api/services/password-reset-service.ts","doc":"Emails a reset link to the account with address email, if there is one and email is configured. It says nothing of what it did, so that the route answers the same whether the address has an account or not. It sends at most 3 links in a row per address, then one every 10 minutes.","url":"./api/services/password-reset-service.ts/~/requestPasswordReset.html","deprecated":false},{"id":"namespace_resetpassword","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"resetPassword","file":"api/services/password-reset-service.ts","doc":"Sets newPassword for the user of a reset token, marks the token used, and returns the user's id. Through updateUser, this ends the user's sessions here; the route tells the instances they signed in to.","url":"./api/services/password-reset-service.ts/~/resetPassword.html","deprecated":false},{"id":"namespace_getplaylistbyid","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"getPlaylistById","file":"api/services/playlist-service.ts","doc":"Returns playlist playlistId, private or not. A caller that shows it to someone must check isPublic first, as the OG middleware does. Its dumpCount and lastDumpAt are viewerId's, or a signed-out viewer's without one.","url":"./api/services/playlist-service.ts/~/getPlaylistById.html","deprecated":false},{"id":"namespace_getplaylistbypath","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"getPlaylistByPath","file":"api/services/playlist-service.ts","doc":"Returns the playlist of userId's whose slug is or was slug, private or not, or throws a 404, as getPlaylistById does, counting its dumps for viewerId likewise. Reached by a former slug, it comes with its current one.","url":"./api/services/playlist-service.ts/~/getPlaylistByPath.html","deprecated":false},{"id":"namespace_createplaylist","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"createPlaylist","file":"api/services/playlist-service.ts","doc":"Creates a playlist owned by userId, for POST /api/playlists, filed under the playlist categories req names. If it is public, it notifies the users its description mentions. It links the attachments the description embeds and broadcasts playlist_created.","url":"./api/services/playlist-service.ts/~/createPlaylist.html","deprecated":false},{"id":"namespace_getplaylist","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"getPlaylist","file":"api/services/playlist-service.ts","doc":"Returns a playlist with the dumps requestingUserId may see in it, in order, for GET /api/playlists/:playlistId, and for GET /api/users/:key/playlists/:slug once it has found the playlist by its path, for the same viewer. A null requestingUserId is a signed-out viewer. Its dumpCount is the number of those dumps.","url":"./api/services/playlist-service.ts/~/getPlaylist.html","deprecated":false},{"id":"namespace_searchplaylists","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"searchPlaylists","file":"api/services/playlist-service.ts","doc":"Returns up to limit playlists whose title or description contains query, newest first, for GET /api/search, optionally only those in the playlist category categoryId. Private playlists are left out, except requestingUserId's own. A blank query finds nothing.","url":"./api/services/playlist-service.ts/~/searchPlaylists.html","deprecated":false},{"id":"namespace_listpublicplaylists","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"listPublicPlaylists","file":"api/services/playlist-service.ts","doc":"Returns a page of every public playlist, in the order sort names, for GET /api/playlists, optionally only those in the playlist category categoryId. The client's /playlists page lists them. Their dumps are counted, and so ordered, for requestingUserId, null being a signed-out viewer.","url":"./api/services/playlist-service.ts/~/listPublicPlaylists.html","deprecated":false},{"id":"namespace_listnewpublicplaylists","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"listNewPublicPlaylists","file":"api/services/playlist-service.ts","doc":"Returns the public playlists created from from to to, the fullest first and the newer on a tie. The community service gathers them for the /community page and the digests, which show every reader the same figures: only their public dumps are counted.","url":"./api/services/playlist-service.ts/~/listNewPublicPlaylists.html","deprecated":false},{"id":"namespace_listplaylistsbyuser","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"listPlaylistsByUser","file":"api/services/playlist-service.ts","doc":"Returns a page of userId's playlists, in the order sort names, for GET /api/users/:key/playlists, optionally only those in the playlist category categoryId. The private ones are listed only when requestingUserId is userId.","url":"./api/services/playlist-service.ts/~/listPlaylistsByUser.html","deprecated":false},{"id":"namespace_updateplaylist","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"updatePlaylist","file":"api/services/playlist-service.ts","doc":"Applies req to a playlist for PUT /api/playlists/:playlistId, and returns it as it now is. A new slug goes through changeSlug, first, and a moderator is exempt from its rate limit; a new title leaves the slug as it is. canModerate lets someone other than the owner edit it. If the playlist is public, it notifies, in the owner's name, the users the description mentions. When it goes public, its followers are notified of its public dumps they weren't yet told of. It links the description's attachments and tells clients of the change (broadcastPlaylistChange).","url":"./api/services/playlist-service.ts/~/updatePlaylist.html","deprecated":false},{"id":"namespace_deleteplaylist","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"deletePlaylist","file":"api/services/playlist-service.ts","doc":"Deletes a playlist for DELETE /api/playlists/:playlistId, and broadcasts playlist_deleted. canModerate lets someone other than the owner do it.","url":"./api/services/playlist-service.ts/~/deletePlaylist.html","deprecated":false},{"id":"namespace_geteditableplaylist","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"getEditablePlaylist","file":"api/services/playlist-service.ts","doc":"Returns the playlist if requestingUserId may edit it. The cover upload route checks this before it writes the file, then calls setPlaylistImage.","url":"./api/services/playlist-service.ts/~/getEditablePlaylist.html","deprecated":false},{"id":"namespace_setplaylistimage","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"setPlaylistImage","file":"api/services/playlist-service.ts","doc":"Records the type of a playlist's new cover and broadcasts playlist_updated. The route must have written the file already, since clients fetch the cover as soon as they get the broadcast.","url":"./api/services/playlist-service.ts/~/setPlaylistImage.html","deprecated":false},{"id":"namespace_adddumptoplaylist","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"addDumpToPlaylist","file":"api/services/playlist-service.ts","doc":"Puts a dump at the top of a playlist, for POST /api/playlists/:playlistId/dumps/:dumpId, and broadcasts playlist_dumps_updated. The followers of a public playlist are notified when the dump is public.","url":"./api/services/playlist-service.ts/~/addDumpToPlaylist.html","deprecated":false},{"id":"namespace_removedumpfromplaylist","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"removeDumpFromPlaylist","file":"api/services/playlist-service.ts","doc":"Takes a dump out of a playlist, for DELETE /api/playlists/:playlistId/dumps/:dumpId, and broadcasts playlist_dumps_updated. A dump that isn't in it is no error.","url":"./api/services/playlist-service.ts/~/removeDumpFromPlaylist.html","deprecated":false},{"id":"namespace_reorderplaylist","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"reorderPlaylist","file":"api/services/playlist-service.ts","doc":"Puts the dumps of a playlist that the requester can see in the order of dumpIds, for PUT /api/playlists/:playlistId/order, and broadcasts playlist_dumps_updated.","url":"./api/services/playlist-service.ts/~/reorderPlaylist.html","deprecated":false},{"id":"namespace_getplaylistmembershipsfordump","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"getPlaylistMembershipsForDump","file":"api/services/playlist-service.ts","doc":"Returns each of userId's playlists, newest first, and whether it holds dump dumpId, for GET /api/me/playlists?contains=. The client's add-to-playlist modal shows it.","url":"./api/services/playlist-service.ts/~/getPlaylistMembershipsForDump.html","deprecated":false},{"id":"namespace_getplaylistsfordump","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"getPlaylistsForDump","file":"api/services/playlist-service.ts","doc":"Returns up to 20 playlists that hold dump dumpId, newest first, for GET /api/dumps/:dumpId/playlists. Private playlists are left out, except requestingUserId's own. The route checks first that the caller may see the dump.","url":"./api/services/playlist-service.ts/~/getPlaylistsForDump.html","deprecated":false},{"id":"namespace_getplaylistimageinfo","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"getPlaylistImageInfo","file":"api/services/playlist-service.ts","doc":"Returns what GET /api/playlists/:playlistId/cover needs to serve a playlist's cover, or undefined when it has none. The route serves a private playlist's cover as private, so no shared cache keeps it.","url":"./api/services/playlist-service.ts/~/getPlaylistImageInfo.html","deprecated":false},{"id":"namespace_playlistholder","kind":[{"char":"T","kind":"TypeAlias","title":"Type Alias"}],"name":"PlaylistHolder","file":"api/services/playlist-service.ts","doc":"A playlist holding a dump, as playlistsHolding returns it: what broadcastPlaylistDumpsUpdated needs to choose its audience.","url":"./api/services/playlist-service.ts/~/PlaylistHolder.html","deprecated":false},{"id":"namespace_playlistsholding","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"playlistsHolding","file":"api/services/playlist-service.ts","doc":"Returns the playlists holding dump dumpId. The dump service reads them before it deletes the dump or changes its visibility, and passes them to broadcastHoldersDumps after.","url":"./api/services/playlist-service.ts/~/playlistsHolding.html","deprecated":false},{"id":"namespace_broadcastholdersdumps","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"broadcastHoldersDumps","file":"api/services/playlist-service.ts","doc":"Sends each of holders its dumps again, after one of them was deleted or changed visibility, which changes what each viewer may see of them.","url":"./api/services/playlist-service.ts/~/broadcastHoldersDumps.html","deprecated":false},{"id":"namespace_fetchrichcontentresult","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"FetchRichContentResult","file":"api/services/rich-content-service.ts","doc":"Returned by tryFetchRichContent to GET /api/remote/preview, which reports ok as reached, and to refreshDumpMetadata, which gives up when it is false.","url":"./api/services/rich-content-service.ts/~/FetchRichContentResult.html","deprecated":false},{"id":"namespace_fetchrichcontentresult","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"FetchRichContentResult.ok","file":"api/services/rich-content-service.ts","doc":"False when the page couldn't be reached at all, as opposed to reached and found to carry no metadata. A caller that already holds metadata must not overwrite it with the failure stub.","url":"./api/services/rich-content-service.ts/~/FetchRichContentResult.ok.html","deprecated":false},{"id":"namespace_fetchrichcontentresult","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"FetchRichContentResult.content","file":"api/services/rich-content-service.ts","doc":"On failure, a stub holding the URL and its host name. Missing only when the URL doesn't parse.","url":"./api/services/rich-content-service.ts/~/FetchRichContentResult.content.html","deprecated":false},{"id":"namespace_clearrichcontentcache","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"clearRichContentCache","file":"api/services/rich-content-service.ts","doc":"Forgets every cached preview. The tests' stubNetwork calls it, since previews fetched from the previous stubbed network no longer apply.","url":"./api/services/rich-content-service.ts/~/clearRichContentCache.html","deprecated":false},{"id":"namespace_tryfetchrichcontent","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"tryFetchRichContent","file":"api/services/rich-content-service.ts","doc":"Fetches the preview of url, and says whether the page could be reached. A preview fetched in the last five minutes is reused unless fresh is set, as a metadata refresh does. It never rejects: a failure resolves to a stub.","url":"./api/services/rich-content-service.ts/~/tryFetchRichContent.html","deprecated":false},{"id":"namespace_fetchrichcontent","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"fetchRichContent","file":"api/services/rich-content-service.ts","doc":"Returns the preview of url, or a stub holding its host name when the page can't be reached. createUrlDump and updateDump use it for a new link, which has no earlier preview to keep.","url":"./api/services/rich-content-service.ts/~/fetchRichContent.html","deprecated":false},{"id":"namespace_getsettings","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"getSettings","file":"api/services/settings-service.ts","doc":"Returns the settings of user userId, the defaults if they changed none.","url":"./api/services/settings-service.ts/~/getSettings.html","deprecated":false},{"id":"namespace_updatesettings","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"updateSettings","file":"api/services/settings-service.ts","doc":"Applies patch to the settings of user userId and returns them all. The settings it leaves out keep their value.","url":"./api/services/settings-service.ts/~/updateSettings.html","deprecated":false},{"id":"namespace_newslug","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"newSlug","file":"api/services/slug-service.ts","doc":"Returns a free slug for a new item of userId's titled title, for the dump and playlist services to insert it with, inside their transaction.","url":"./api/services/slug-service.ts/~/newSlug.html","deprecated":false},{"id":"namespace_resolveslug","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"resolveSlug","file":"api/services/slug-service.ts","doc":"Returns the id of userId's item of kind whose slug is or was slug, or undefined when none is.","url":"./api/services/slug-service.ts/~/resolveSlug.html","deprecated":false},{"id":"namespace_changeslug","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"changeSlug","file":"api/services/slug-service.ts","doc":"Gives item the slug slug, keeping its current one as an alias. An alias always names the item itself, so redirects never chain; taking back one of the item's own aliases swaps it with the current slug. Unless exempt (a moderator), an item's slug changes at most RENAME_LIMITS.SLUG.count times in its window, counted from its aliases. A slug equal to the current one changes nothing.","url":"./api/services/slug-service.ts/~/changeSlug.html","deprecated":false},{"id":"namespace_createuser","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"createUser","file":"api/services/user-service.ts","doc":"Creates a user with the user role, invited by inviterId, for POST /api/users. The caller has validated request and claimed the invite.","url":"./api/services/user-service.ts/~/createUser.html","deprecated":false},{"id":"namespace_createremoteuser","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"createRemoteUser","file":"api/services/user-service.ts","doc":"Creates the account of a user from another instance, named username (their handle here, name@host), with no password, for federation-service.ts, which links it to their identity there in the same transaction. inviterId is whoever invited them, or null when their instance is trusted.","url":"./api/services/user-service.ts/~/createRemoteUser.html","deprecated":false},{"id":"namespace_sendwelcomeemail","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"sendWelcomeEmail","file":"api/services/user-service.ts","doc":"Emails user the welcome message, if email is configured. The register route calls it once the account exists, and doesn't wait: a slow or failing SMTP server mustn't hold up the sign-up, so a failure is only logged.","url":"./api/services/user-service.ts/~/sendWelcomeEmail.html","deprecated":false},{"id":"namespace_getuserbyid","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"getUserById","file":"api/services/user-service.ts","doc":"Returns user userId, with their hash and email.","url":"./api/services/user-service.ts/~/getUserById.html","deprecated":false},{"id":"namespace_getsessionstate","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"getSessionState","file":"api/services/user-service.ts","doc":"Returns the user's live role and their last password change, before which their tokens don't count, or undefined when the user is gone, or comes from another instance while an admin blocks it or the deployment turns sign-ins from other instances off (FEDERATION.incoming). lib/auth.ts checks every session and media token against it.","url":"./api/services/user-service.ts/~/getSessionState.html","deprecated":false},{"id":"namespace_getuserbyusername","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"getUserByUsername","file":"api/services/user-service.ts","doc":"Returns the user named username now, in any case, with their hash and email. Signing in takes it: a former name doesn't sign in.","url":"./api/services/user-service.ts/~/getUserByUsername.html","deprecated":false},{"id":"namespace_resolveusername","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"resolveUsername","file":"api/services/user-service.ts","doc":"Returns the user who is or was named username, in any case, or by the handle another instance gives them (localHandle): a page or an API path naming a user so reaches them, and the caller sends the client on to their current name.","url":"./api/services/user-service.ts/~/resolveUsername.html","deprecated":false},{"id":"namespace_resolveuserkey","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"resolveUserKey","file":"api/services/user-service.ts","doc":"Returns the user an API path's key names: @name by their name, current or former (resolveUsername), anything else by their id. Every route under /api/users/:key resolves its key with it.","url":"./api/services/user-service.ts/~/resolveUserKey.html","deprecated":false},{"id":"namespace_renameuser","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"renameUser","file":"api/services/user-service.ts","doc":"Renames user userId to username, for PATCH /api/users/:key/username, which only user:manage may call: users can't rename themselves. Returns them renamed. The old name becomes an alias of theirs for good, so /@old/… still reaches them and nobody else may take it; a change of case alone leaves none, since names are looked up in any case. Taking back a former name of their own is allowed. Their dumps' and playlists' slugs belong to their id, so their paths follow the new name.","url":"./api/services/user-service.ts/~/renameUser.html","deprecated":false},{"id":"namespace_setusername","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"setUsername","file":"api/services/user-service.ts","doc":"Names user userId username, keeping the old name as their alias as renameUser describes, and returns them. The caller has checked the name: renameUser checks a local one, and federation-service.ts the handle of a user renamed on their home instance.","url":"./api/services/user-service.ts/~/setUsername.html","deprecated":false},{"id":"namespace_assertlocaluser","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"assertLocalUser","file":"api/services/user-service.ts","doc":"Throws a 400 when user's account lives on another instance (isRemoteUser), whose password, email, avatar and name are that instance's to change. The routes that change them call it first.","url":"./api/services/user-service.ts/~/assertLocalUser.html","deprecated":false},{"id":"namespace_getuserbyemail","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"getUserByEmail","file":"api/services/user-service.ts","doc":"Returns the local user whose email is email, in any case, or null, for requestPasswordReset. An account from another instance has no password here to reset.","url":"./api/services/user-service.ts/~/getUserByEmail.html","deprecated":false},{"id":"namespace_searchusers","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"searchUsers","file":"api/services/user-service.ts","doc":"Returns up to limit users whose name starts with query, for the editor's","url":"./api/services/user-service.ts/~/searchUsers.html","deprecated":false},{"id":"namespace_searchusersglobal","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"searchUsersGlobal","file":"api/services/user-service.ts","doc":"Returns up to limit users whose name or description contains query, for the /search page (GET /api/search). They are already public profiles.","url":"./api/services/user-service.ts/~/searchUsersGlobal.html","deprecated":false},{"id":"namespace_listnewusers","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"listNewUsers","file":"api/services/user-service.ts","doc":"Returns the users who joined from from to to, in sign-up order, each with the name of whoever invited them. The community service gathers them for the /community page and the digests.","url":"./api/services/user-service.ts/~/listNewUsers.html","deprecated":false},{"id":"namespace_updateuser","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"updateUser","file":"api/services/user-service.ts","doc":"Applies request to user userId and returns the updated user. It trusts request: the routes pick the fields a caller may change. The username changes through renameUser alone, which keeps the old one as an alias. A new password also ends every session opened before it and closes the user's sockets, so the caller must issue fresh tokens if the user is to stay signed in. A description of null keeps the current one.","url":"./api/services/user-service.ts/~/updateUser.html","deprecated":false},{"id":"namespace_revokesessions","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"revokeSessions","file":"api/services/user-service.ts","doc":"Ends every session of user userId opened before at, closing their sockets with reason: their tokens stop counting (users.tokens_valid_after, which getSessionState reads). A password change calls it, and so does the sign-out of a user from another instance, when that instance says so or an admin blocks it.","url":"./api/services/user-service.ts/~/revokeSessions.html","deprecated":false},{"id":"namespace_setuseravatar","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"setUserAvatar","file":"api/services/user-service.ts","doc":"Makes the image data user userId's avatar and returns them, for an upload (PUT /api/me/avatar) and for the avatar a user from another instance has there (federation-service.ts). Presence alone would update only the online list, so it also sends user_updated, which reaches every avatar on screen, its bumped updatedAt busting their cache.","url":"./api/services/user-service.ts/~/setUserAvatar.html","deprecated":false},{"id":"namespace_getinvitetree","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"getInviteTree","file":"api/services/user-service.ts","doc":"Returns everyone userId invited, and everyone they invited in turn, eleven levels deep at most, in sign-up order, for the profile page's invite tree (GET /api/users/:key/invitees).","url":"./api/services/user-service.ts/~/getInviteTree.html","deprecated":false},{"id":"namespace_voteresult","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"VoteResult","file":"api/services/vote-service.ts","doc":"Returned to the WebSocket route by castVote and removeVote. The route acks the voter with voteCount, then broadcasts it to every client, or to the dump owner's alone when isPrivate.","url":"./api/services/vote-service.ts/~/VoteResult.html","deprecated":false},{"id":"namespace_voteresult","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"VoteResult.voteCount","file":"api/services/vote-service.ts","doc":"","url":"./api/services/vote-service.ts/~/VoteResult.voteCount.html","deprecated":false},{"id":"namespace_voteresult","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"VoteResult.isPrivate","file":"api/services/vote-service.ts","doc":"","url":"./api/services/vote-service.ts/~/VoteResult.isPrivate.html","deprecated":false},{"id":"namespace_castvote","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"castVote","file":"api/services/vote-service.ts","doc":"Records userId's upvote on a dump and notifies the dump's poster. The notification is best-effort: if it fails, the vote still counts.","url":"./api/services/vote-service.ts/~/castVote.html","deprecated":false},{"id":"namespace_removevote","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"removeVote","file":"api/services/vote-service.ts","doc":"Takes back userId's upvote on a dump. No visibility check: taking back a vote on a dump that has since gone private is harmless, and it's the voter's own row.","url":"./api/services/vote-service.ts/~/removeVote.html","deprecated":false},{"id":"namespace_getuservotes","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"getUserVotes","file":"api/services/vote-service.ts","doc":"Returns the ids of the dumps userId upvoted. The WebSocket route sends them in its welcome message, and the client shows those vote buttons pressed.","url":"./api/services/vote-service.ts/~/getUserVotes.html","deprecated":false},{"id":"namespace_getdumpvoters","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"getDumpVoters","file":"api/services/vote-service.ts","doc":"Returns a page of the users who upvoted a dump, latest vote first, for GET /api/dumps/:dumpId/voters. It doesn't check that the caller may see the dump: the route does that first, with getDump.","url":"./api/services/vote-service.ts/~/getDumpVoters.html","deprecated":false},{"id":"namespace_wsclient","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"WsClient","file":"api/services/ws-service.ts","doc":"Created by the WebSocket route for each socket it opens, and kept here until the socket closes. The user fields are read at connect and left undefined for an anonymous socket.","url":"./api/services/ws-service.ts/~/WsClient.html","deprecated":false},{"id":"namespace_wsclient","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"WsClient.socket","file":"api/services/ws-service.ts","doc":"","url":"./api/services/ws-service.ts/~/WsClient.socket.html","deprecated":false},{"id":"namespace_wsclient","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"WsClient.userId","file":"api/services/ws-service.ts","doc":"","url":"./api/services/ws-service.ts/~/WsClient.userId.html","deprecated":false},{"id":"namespace_wsclient","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"WsClient.username","file":"api/services/ws-service.ts","doc":"","url":"./api/services/ws-service.ts/~/WsClient.username.html","deprecated":false},{"id":"namespace_wsclient","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"WsClient.role","file":"api/services/ws-service.ts","doc":"Read again from the database on each chat edit or delete, so a demoted moderator loses the right at once.","url":"./api/services/ws-service.ts/~/WsClient.role.html","deprecated":false},{"id":"namespace_wsclient","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"WsClient.avatarMime","file":"api/services/ws-service.ts","doc":"","url":"./api/services/ws-service.ts/~/WsClient.avatarMime.html","deprecated":false},{"id":"namespace_wsclient","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"WsClient.avatarVersion","file":"api/services/ws-service.ts","doc":"Set by updateClientAvatar, for the client's avatar URLs.","url":"./api/services/ws-service.ts/~/WsClient.avatarVersion.html","deprecated":false},{"id":"namespace_wsclient","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"WsClient.pongReceived","file":"api/services/ws-service.ts","doc":"Undefined until the first ping, so a new socket isn't closed at once.","url":"./api/services/ws-service.ts/~/WsClient.pongReceived.html","deprecated":false},{"id":"namespace_wsclient","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"WsClient.chatOpen","file":"api/services/ws-service.ts","doc":"Set by chat_focus: the chatbox is open and the tab visible, so the user is reading the chat and gets no notification for a mention in it.","url":"./api/services/ws-service.ts/~/WsClient.chatOpen.html","deprecated":false},{"id":"namespace_wsclient","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"WsClient.typingAt","file":"api/services/ws-service.ts","doc":"When the last chat_typing true arrived, in ms.","url":"./api/services/ws-service.ts/~/WsClient.typingAt.html","deprecated":false},{"id":"namespace_register","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"register","file":"api/services/ws-service.ts","doc":"Adds a client once its socket opens. From then on, it receives the broadcasts, and is shown online if it is signed in.","url":"./api/services/ws-service.ts/~/register.html","deprecated":false},{"id":"namespace_unregister","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"unregister","file":"api/services/ws-service.ts","doc":"Removes a client when its socket closes. The caller rebroadcasts presence.","url":"./api/services/ws-service.ts/~/unregister.html","deprecated":false},{"id":"namespace_updateclientavatar","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"updateClientAvatar","file":"api/services/ws-service.ts","doc":"Records userId's new avatar on their clients, so presence and the typing list show it, and rebroadcasts presence. routes/avatars.ts calls it on an upload.","url":"./api/services/ws-service.ts/~/updateClientAvatar.html","deprecated":false},{"id":"namespace_updateclientusername","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"updateClientUsername","file":"api/services/ws-service.ts","doc":"Records userId's new name on their clients, so presence and the typing list show it, and rebroadcasts presence. The routes that rename a user call it, along with broadcastUserUpdated.","url":"./api/services/ws-service.ts/~/updateClientUsername.html","deprecated":false},{"id":"namespace_getonlineusers","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"getOnlineUsers","file":"api/services/ws-service.ts","doc":"Returns each signed-in user with a socket open, once. The route sends it in welcome, and broadcastPresence in presence_update.","url":"./api/services/ws-service.ts/~/getOnlineUsers.html","deprecated":false},{"id":"namespace_send","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"send","file":"api/services/ws-service.ts","doc":"Sends data to one socket unless it is closing. The WebSocket route answers a client's own message with it: a pong, a vote's ack, an error.","url":"./api/services/ws-service.ts/~/send.html","deprecated":false},{"id":"namespace_sendtouser","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"sendToUser","file":"api/services/ws-service.ts","doc":"Sends data to every socket of userId. The notification service sends notification_created and notifications_read with it, the follow service follows_changed, and the route chat_read_update.","url":"./api/services/ws-service.ts/~/sendToUser.html","deprecated":false},{"id":"namespace_closeusersockets","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"closeUserSockets","file":"api/services/ws-service.ts","doc":"Closes every socket of userId without signing anyone out. The user service calls it on a password change. Each tab reconnects with the token it holds: the tab that made the change has a fresh one and stays signed in, while the others connect anonymously and sign out on their next 401.","url":"./api/services/ws-service.ts/~/closeUserSockets.html","deprecated":false},{"id":"namespace_broadcastpresence","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"broadcastPresence","file":"api/services/ws-service.ts","doc":"Sends everyone presence_update. The route calls it whenever a socket opens or closes.","url":"./api/services/ws-service.ts/~/broadcastPresence.html","deprecated":false},{"id":"namespace_broadcastdumpchange","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"broadcastDumpChange","file":"api/services/ws-service.ts","doc":"Tells the clients that may see a dump how it changed, as broadcastChange says, for the dump service after every write.","url":"./api/services/ws-service.ts/~/broadcastDumpChange.html","deprecated":false},{"id":"namespace_broadcastdumprelatedchanged","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"broadcastDumpRelatedChanged","file":"api/services/ws-service.ts","doc":"Sends dump_related_changed after the links between dump and each of others changed, for the backlink service. A link shows only to those who may see both its ends, so a socket is told only when its user may see dump and one of others, and of those alone.","url":"./api/services/ws-service.ts/~/broadcastDumpRelatedChanged.html","deprecated":false},{"id":"namespace_broadcastvoteupdate","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"broadcastVoteUpdate","file":"api/services/ws-service.ts","doc":"Sends votes_update after the route stored a vote, to everyone, or with onlyUserId to that user's sockets alone (for a private dump).","url":"./api/services/ws-service.ts/~/broadcastVoteUpdate.html","deprecated":false},{"id":"namespace_broadcastcommentlikeupdate","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"broadcastCommentLikeUpdate","file":"api/services/ws-service.ts","doc":"Sends comment_likes_update after the route stored a like, to everyone, or with onlyUserId to that user's sockets alone (for a comment on a private dump).","url":"./api/services/ws-service.ts/~/broadcastCommentLikeUpdate.html","deprecated":false},{"id":"namespace_broadcastplaylistchange","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"broadcastPlaylistChange","file":"api/services/ws-service.ts","doc":"Tells the clients that may see a playlist how it changed, as broadcastChange says, for the playlist service after every write to its details. A playlist turned private thus leaves the others' views without their learning what it became. members are the dumps of after: each socket gets the playlist with the count of those its user may see and the date of the latest, the owner's private dumps being theirs alone to count.","url":"./api/services/ws-service.ts/~/broadcastPlaylistChange.html","deprecated":false},{"id":"namespace_broadcastplaylistdumpsupdated","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"broadcastPlaylistDumpsUpdated","file":"api/services/ws-service.ts","doc":"Sends playlist_dumps_updated to the playlist's audience, each socket with only the dumps its user may see, as GET would list them. The private dumps in a public playlist stay hidden from everyone but their posters, and so does their number: a client counts the dumps it is sent.","url":"./api/services/ws-service.ts/~/broadcastPlaylistDumpsUpdated.html","deprecated":false},{"id":"namespace_broadcastuserupdated","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"broadcastUserUpdated","file":"api/services/ws-service.ts","doc":"Sends everyone user_updated, after a profile edit, a role change or an avatar upload.","url":"./api/services/ws-service.ts/~/broadcastUserUpdated.html","deprecated":false},{"id":"namespace_broadcastcommentcreated","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"broadcastCommentCreated","file":"api/services/ws-service.ts","doc":"Sends comment_created to those who may see the comment's dump: everyone, or its owner alone when it is private. The comments route calls it, as it does the two below.","url":"./api/services/ws-service.ts/~/broadcastCommentCreated.html","deprecated":false},{"id":"namespace_broadcastcommentdeleted","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"broadcastCommentDeleted","file":"api/services/ws-service.ts","doc":"Sends comment_deleted, as broadcastCommentCreated does.","url":"./api/services/ws-service.ts/~/broadcastCommentDeleted.html","deprecated":false},{"id":"namespace_broadcastcommentupdated","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"broadcastCommentUpdated","file":"api/services/ws-service.ts","doc":"Sends comment_updated, as broadcastCommentCreated does.","url":"./api/services/ws-service.ts/~/broadcastCommentUpdated.html","deprecated":false},{"id":"namespace_broadcastcategorieschanged","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"broadcastCategoriesChanged","file":"api/services/ws-service.ts","doc":"Sends everyone categories_changed, after the category manager created, edited or deleted one, so that every client fetches them again.","url":"./api/services/ws-service.ts/~/broadcastCategoriesChanged.html","deprecated":false},{"id":"namespace_broadcastchatmessage","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"broadcastChatMessage","file":"api/services/ws-service.ts","doc":"Sends chat_message to every signed-in socket, the sender's included. nonce comes from the sender's chat_send, and lets it swap its pending copy for the message.","url":"./api/services/ws-service.ts/~/broadcastChatMessage.html","deprecated":false},{"id":"namespace_broadcastchatmessageupdated","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"broadcastChatMessageUpdated","file":"api/services/ws-service.ts","doc":"Sends chat_message_updated to every signed-in socket.","url":"./api/services/ws-service.ts/~/broadcastChatMessageUpdated.html","deprecated":false},{"id":"namespace_broadcastchatmessagedeleted","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"broadcastChatMessageDeleted","file":"api/services/ws-service.ts","doc":"Sends chat_message_deleted to every signed-in socket.","url":"./api/services/ws-service.ts/~/broadcastChatMessageDeleted.html","deprecated":false},{"id":"namespace_gettypingusers","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"getTypingUsers","file":"api/services/ws-service.ts","doc":"Returns each user who sent chat_typing true within the last TYPING_TTL, once, for broadcastTyping.","url":"./api/services/ws-service.ts/~/getTypingUsers.html","deprecated":false},{"id":"namespace_broadcasttyping","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"broadcastTyping","file":"api/services/ws-service.ts","doc":"Sends chat_typing_update to every signed-in socket. The route also calls it when a typing user's socket closes.","url":"./api/services/ws-service.ts/~/broadcastTyping.html","deprecated":false},{"id":"namespace_setclienttyping","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"setClientTyping","file":"api/services/ws-service.ts","doc":"Records a client's chat_typing, and broadcasts the typing list when the client starts or stops. The route also clears it when the client sends a message. A client that stops without saying so is expired after TYPING_TTL.","url":"./api/services/ws-service.ts/~/setClientTyping.html","deprecated":false},{"id":"namespace_typingexpiryjob","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"typingExpiryJob","file":"api/services/ws-service.ts","doc":"Expires the typing users who went quiet without a false, such as by closing the tab, every 2 seconds. main.ts starts it.","url":"./api/services/ws-service.ts/~/typingExpiryJob.html","deprecated":false},{"id":"namespace_isuserchatopen","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"isUserChatOpen","file":"api/services/ws-service.ts","doc":"Checks whether userId is reading the chat on any of their sockets. The route passes it to notifyMentions, which skips those users: they saw the mention live, and their client chimes for it.","url":"./api/services/ws-service.ts/~/isUserChatOpen.html","deprecated":false},{"id":"namespace_handleclientpong","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"handleClientPong","file":"api/services/ws-service.ts","doc":"Records a client's pong, which keeps its socket open.","url":"./api/services/ws-service.ts/~/handleClientPong.html","deprecated":false},{"id":"namespace_pingjob","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"pingJob","file":"api/services/ws-service.ts","doc":"Pings every client each PING_INTERVAL, closing the ones that didn't answer the previous ping. main.ts starts it.","url":"./api/services/ws-service.ts/~/pingJob.html","deprecated":false},{"id":"namespace_iscreatecategoryrequest","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"isCreateCategoryRequest","file":"api/validators/category.ts","doc":"Checks whether obj has the fields of a CreateCategoryRequest.","url":"./api/validators/category.ts/~/isCreateCategoryRequest.html","deprecated":false},{"id":"namespace_isupdatecategoryrequest","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"isUpdateCategoryRequest","file":"api/validators/category.ts","doc":"Checks whether obj has the fields of an UpdateCategoryRequest.","url":"./api/validators/category.ts/~/isUpdateCategoryRequest.html","deprecated":false},{"id":"namespace_iscreatecommentrequest","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"isCreateCommentRequest","file":"api/validators/comment.ts","doc":"Checks whether obj is a CreateCommentRequest whose body isn't blank and fits VALIDATION.COMMENT_BODY_MAX. A null parentId passes, as a top-level comment.","url":"./api/validators/comment.ts/~/isCreateCommentRequest.html","deprecated":false},{"id":"namespace_isupdatecommentrequest","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"isUpdateCommentRequest","file":"api/validators/comment.ts","doc":"Checks whether obj is an UpdateCommentRequest whose body isn't blank and fits VALIDATION.COMMENT_BODY_MAX.","url":"./api/validators/comment.ts/~/isUpdateCommentRequest.html","deprecated":false},{"id":"namespace_iscreateurldumprequest","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"isCreateUrlDumpRequest","file":"api/validators/dump.ts","doc":"Checks whether obj is a CreateUrlDumpRequest whose title and comment fit the VALIDATION limits. It leaves the URL to createUrlDump, which rejects anything but a public http(s) URL.","url":"./api/validators/dump.ts/~/isCreateUrlDumpRequest.html","deprecated":false},{"id":"namespace_isupdatedumprequest","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"isUpdateDumpRequest","file":"api/validators/dump.ts","doc":"Checks whether obj is an UpdateDumpRequest whose title and comment fit the VALIDATION limits. Unlike on creation, a title that is given must not be blank.","url":"./api/validators/dump.ts/~/isUpdateDumpRequest.html","deprecated":false},{"id":"namespace_parsecategoryids","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"parseCategoryIds","file":"api/validators/dump.ts","doc":"Parses a multipart form's categoryIds, a JSON array sent as a string. A missing or malformed value counts as no category. The dumps and files routes read the forms that post and replace a file with it.","url":"./api/validators/dump.ts/~/parseCategoryIds.html","deprecated":false},{"id":"namespace_isfederationloginrequest","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"isFederationLoginRequest","file":"api/validators/federation.ts","doc":"Checks whether obj is a FederationLoginRequest.","url":"./api/validators/federation.ts/~/isFederationLoginRequest.html","deprecated":false},{"id":"namespace_isfederationsessionrequest","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"isFederationSessionRequest","file":"api/validators/federation.ts","doc":"Checks whether obj is a FederationSessionRequest.","url":"./api/validators/federation.ts/~/isFederationSessionRequest.html","deprecated":false},{"id":"namespace_isauthorizerequest","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"isAuthorizeRequest","file":"api/validators/federation.ts","doc":"Checks whether obj is an AuthorizeRequest.","url":"./api/validators/federation.ts/~/isAuthorizeRequest.html","deprecated":false},{"id":"namespace_issetpeerrequest","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"isSetPeerRequest","file":"api/validators/federation.ts","doc":"Checks whether obj is a SetPeerRequest.","url":"./api/validators/federation.ts/~/isSetPeerRequest.html","deprecated":false},{"id":"namespace_iscreateplaylistrequest","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"isCreatePlaylistRequest","file":"api/validators/playlist.ts","doc":"Checks whether obj is a CreatePlaylistRequest with a title that isn't blank, and a title and description within the VALIDATION limits. A null description passes. Whether its category ids name playlist categories is the playlist service's to check.","url":"./api/validators/playlist.ts/~/isCreatePlaylistRequest.html","deprecated":false},{"id":"namespace_isupdateplaylistrequest","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"isUpdatePlaylistRequest","file":"api/validators/playlist.ts","doc":"Checks whether obj is an UpdatePlaylistRequest whose title, if given, isn't blank, with a title and description within the VALIDATION limits.","url":"./api/validators/playlist.ts/~/isUpdatePlaylistRequest.html","deprecated":false},{"id":"namespace_isreorderplaylistrequest","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"isReorderPlaylistRequest","file":"api/validators/playlist.ts","doc":"Checks whether obj is a ReorderPlaylistRequest. Whether its ids match the playlist is reorderPlaylist's to check.","url":"./api/validators/playlist.ts/~/isReorderPlaylistRequest.html","deprecated":false},{"id":"namespace_isupdatesettingsrequest","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"isUpdateSettingsRequest","file":"api/validators/settings.ts","doc":"Checks whether obj is an UpdateSettingsRequest: an object whose every key is a setting, each with a value that setting takes. An unknown key fails, so a typo doesn't pass for a change.","url":"./api/validators/settings.ts/~/isUpdateSettingsRequest.html","deprecated":false},{"id":"namespace_isloginuserrequest","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"isLoginUserRequest","file":"api/validators/user.ts","doc":"Checks whether obj is a LoginUserRequest. It checks the types only: a wrong name or password is the login route's answer to give.","url":"./api/validators/user.ts/~/isLoginUserRequest.html","deprecated":false},{"id":"namespace_fieldof","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"fieldOf","file":"api/validators/user.ts","doc":"Returns obj[key] when obj is an object that has it, else undefined. The users routes whose body has no guard of its own read their fields with it.","url":"./api/validators/user.ts/~/fieldOf.html","deprecated":false},{"id":"namespace_isregisteruserrequest","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"isRegisterUserRequest","file":"api/validators/user.ts","doc":"Checks whether obj is a valid RegisterUserRequest. When it isn't, validateRegisterUserRequest says why.","url":"./api/validators/user.ts/~/isRegisterUserRequest.html","deprecated":false},{"id":"namespace_validateregisteruserrequest","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"validateRegisterUserRequest","file":"api/validators/user.ts","doc":"Returns what is wrong with a sign-up body, as the message the register page shows, or null when it is valid. It checks the shape, the email's form, and the username and password against the VALIDATION limits. Whether the name, the email or the invite is taken is createUser's and claimInvite's check.","url":"./api/validators/user.ts/~/validateRegisterUserRequest.html","deprecated":false},{"id":"namespace_isupdateuserrequest","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"isUpdateUserRequest","file":"api/validators/user.ts","doc":"Checks whether obj is a valid UpdateUserRequest, for PATCH /api/me. Every field is optional, but each one present must be well-formed and within the VALIDATION limits.","url":"./api/validators/user.ts/~/isUpdateUserRequest.html","deprecated":false},{"id":"namespace_devinstance","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"DevInstance","file":"dev/instances.ts","doc":"One instance of INSTANCES.","url":"./dev/instances.ts/~/DevInstance.html","deprecated":false},{"id":"namespace_devinstance","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DevInstance.name","file":"dev/instances.ts","doc":"Names its database and uploads, and prefixes its output. Lowercase letters, digits and hyphens.","url":"./dev/instances.ts/~/DevInstance.name.html","deprecated":false},{"id":"namespace_devinstance","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DevInstance.apiPort","file":"dev/instances.ts","doc":"The port of its API server, GERBEUR_PORT.","url":"./dev/instances.ts/~/DevInstance.apiPort.html","deprecated":false},{"id":"namespace_devinstance","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DevInstance.webPort","file":"dev/instances.ts","doc":"The port of its Vite server, where its pages are.","url":"./dev/instances.ts/~/DevInstance.webPort.html","deprecated":false},{"id":"namespace_devinstance","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DevInstance.env","file":"dev/instances.ts","doc":"GERBEUR_* settings of its own, over the base .env: a site name, an emoji or a style, to tell the instances apart, or which ways federated sign-in goes.","url":"./dev/instances.ts/~/DevInstance.env.html","deprecated":false},{"id":"namespace_instances","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"INSTANCES","file":"dev/instances.ts","doc":"The instances deno task dev starts, in this order. The first keeps the ports the single dev server always had, and takes no users of the others, while its own sign in to them, so that both switches of federated sign-in can be tried.","url":"./dev/instances.ts/~/INSTANCES.html","deprecated":false},{"id":"namespace_apierrorcode","kind":[{"char":"v","kind":"Variable","title":"Variable"},{"char":"T","kind":"TypeAlias","title":"Type Alias"}],"name":"APIErrorCode","file":"shared/api.ts","doc":"Lists the codes an APIError carries, one per HTTP status. The backend's APIException derives its code from the status it is given, and the frontend shows the message without reading the code.","url":"./shared/api.ts/~/APIErrorCode.html","deprecated":false},{"id":"namespace_apierrorcode","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"APIErrorCode.BAD_REQUEST","file":"shared/api.ts","doc":"","url":"./shared/api.ts/~/APIErrorCode.BAD_REQUEST.html","deprecated":false},{"id":"namespace_apierrorcode","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"APIErrorCode.UNAUTHORIZED","file":"shared/api.ts","doc":"","url":"./shared/api.ts/~/APIErrorCode.UNAUTHORIZED.html","deprecated":false},{"id":"namespace_apierrorcode","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"APIErrorCode.FORBIDDEN","file":"shared/api.ts","doc":"","url":"./shared/api.ts/~/APIErrorCode.FORBIDDEN.html","deprecated":false},{"id":"namespace_apierrorcode","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"APIErrorCode.NOT_FOUND","file":"shared/api.ts","doc":"Also answers for what exists but the caller may not see.","url":"./shared/api.ts/~/APIErrorCode.NOT_FOUND.html","deprecated":false},{"id":"namespace_apierrorcode","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"APIErrorCode.CONFLICT","file":"shared/api.ts","doc":"","url":"./shared/api.ts/~/APIErrorCode.CONFLICT.html","deprecated":false},{"id":"namespace_apierrorcode","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"APIErrorCode.RATE_LIMITED","file":"shared/api.ts","doc":"","url":"./shared/api.ts/~/APIErrorCode.RATE_LIMITED.html","deprecated":false},{"id":"namespace_apierrorcode","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"APIErrorCode.SERVER_ERROR","file":"shared/api.ts","doc":"","url":"./shared/api.ts/~/APIErrorCode.SERVER_ERROR.html","deprecated":false},{"id":"namespace_apierrorcode","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"APIErrorCode.BAD_GATEWAY","file":"shared/api.ts","doc":"Answers when another site, such as Bandcamp or YouTube, failed us.","url":"./shared/api.ts/~/APIErrorCode.BAD_GATEWAY.html","deprecated":false},{"id":"namespace_apierror","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"APIError","file":"shared/api.ts","doc":"Sent in an APIFailure. The frontend shows message to the user, so it is written for them.","url":"./shared/api.ts/~/APIError.html","deprecated":false},{"id":"namespace_apierror","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"APIError.code","file":"shared/api.ts","doc":"","url":"./shared/api.ts/~/APIError.code.html","deprecated":false},{"id":"namespace_apierror","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"APIError.message","file":"shared/api.ts","doc":"","url":"./shared/api.ts/~/APIError.message.html","deprecated":false},{"id":"namespace_apisuccess","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"APISuccess","file":"shared/api.ts","doc":"Sent by a route that succeeded, around its payload.","url":"./shared/api.ts/~/APISuccess.html","deprecated":false},{"id":"namespace_apisuccess","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"APISuccess.success","file":"shared/api.ts","doc":"","url":"./shared/api.ts/~/APISuccess.success.html","deprecated":false},{"id":"namespace_apisuccess","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"APISuccess.data","file":"shared/api.ts","doc":"","url":"./shared/api.ts/~/APISuccess.data.html","deprecated":false},{"id":"namespace_apisuccess","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"APISuccess.error","file":"shared/api.ts","doc":"","url":"./shared/api.ts/~/APISuccess.error.html","deprecated":false},{"id":"namespace_apifailure","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"APIFailure","file":"shared/api.ts","doc":"Sent by the error middleware when a request fails, and by the few routes that answer an error themselves.","url":"./shared/api.ts/~/APIFailure.html","deprecated":false},{"id":"namespace_apifailure","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"APIFailure.success","file":"shared/api.ts","doc":"","url":"./shared/api.ts/~/APIFailure.success.html","deprecated":false},{"id":"namespace_apifailure","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"APIFailure.data","file":"shared/api.ts","doc":"","url":"./shared/api.ts/~/APIFailure.data.html","deprecated":false},{"id":"namespace_apifailure","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"APIFailure.error","file":"shared/api.ts","doc":"","url":"./shared/api.ts/~/APIFailure.error.html","deprecated":false},{"id":"namespace_apiresponse","kind":[{"char":"T","kind":"TypeAlias","title":"Type Alias"}],"name":"APIResponse","file":"shared/api.ts","doc":"Returned by every JSON endpoint. A reader tells the two apart by success.","url":"./shared/api.ts/~/APIResponse.html","deprecated":false},{"id":"namespace_paginateddata","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"PaginatedData","file":"shared/api.ts","doc":"Returned by the list endpoints, as the data of an APISuccess.","url":"./shared/api.ts/~/PaginatedData.html","deprecated":false},{"id":"namespace_paginateddata","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PaginatedData.items","file":"shared/api.ts","doc":"","url":"./shared/api.ts/~/PaginatedData.items.html","deprecated":false},{"id":"namespace_paginateddata","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PaginatedData.hasMore","file":"shared/api.ts","doc":"","url":"./shared/api.ts/~/PaginatedData.hasMore.html","deprecated":false},{"id":"namespace_paginateddata","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PaginatedData.total","file":"shared/api.ts","doc":"The size of the whole list, set only by search, which shows it.","url":"./shared/api.ts/~/PaginatedData.total.html","deprecated":false},{"id":"namespace_wire","kind":[{"char":"T","kind":"TypeAlias","title":"Type Alias"}],"name":"Wire","file":"shared/api.ts","doc":"T as the client reads it from JSON, over HTTP, the socket or localStorage, where every Date has become an ISO string.","url":"./shared/api.ts/~/Wire.html","deprecated":false},{"id":"namespace_attachmentresponse","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"AttachmentResponse","file":"shared/attachment.ts","doc":"Returned by POST /api/attachments to the text editor, which inserts the image into the body as a link to attachmentPath.","url":"./shared/attachment.ts/~/AttachmentResponse.html","deprecated":false},{"id":"namespace_attachmentresponse","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"AttachmentResponse.id","file":"shared/attachment.ts","doc":"","url":"./shared/attachment.ts/~/AttachmentResponse.id.html","deprecated":false},{"id":"namespace_attachmentpath","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"attachmentPath","file":"shared/attachment.ts","doc":"Returns the API path of attachment id, to which the API's base is added.","url":"./shared/attachment.ts/~/attachmentPath.html","deprecated":false},{"id":"namespace_attachmentidsin","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"attachmentIdsIn","file":"shared/attachment.ts","doc":"Returns the ids of the attachments text links to, in order.","url":"./shared/attachment.ts/~/attachmentIdsIn.html","deprecated":false},{"id":"namespace_isattachmenturl","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"isAttachmentUrl","file":"shared/attachment.ts","doc":"Checks whether url is an attachment's, with no query yet.","url":"./shared/attachment.ts/~/isAttachmentUrl.html","deprecated":false},{"id":"namespace_category_kinds","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"CATEGORY_KINDS","file":"shared/category.ts","doc":"Lists what a category files: a dump category files dumps, a playlist category playlists. Each kind is a set of its own, whose slugs and names are unique within it.","url":"./shared/category.ts/~/CATEGORY_KINDS.html","deprecated":false},{"id":"namespace_categorykind","kind":[{"char":"T","kind":"TypeAlias","title":"Type Alias"}],"name":"CategoryKind","file":"shared/category.ts","doc":"One of the CATEGORY_KINDS.","url":"./shared/category.ts/~/CategoryKind.html","deprecated":false},{"id":"namespace_iscategorykind","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"isCategoryKind","file":"shared/category.ts","doc":"Checks whether value is one of the CATEGORY_KINDS, for the category validator and the rows the category service reads.","url":"./shared/category.ts/~/isCategoryKind.html","deprecated":false},{"id":"namespace_category","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"Category","file":"shared/category.ts","doc":"Returned by the category routes. A dump category's feed lives at / on the client, a playlist category's at /playlists/, and a dump or playlist names its categories by id in categoryIds.","url":"./shared/category.ts/~/Category.html","deprecated":false},{"id":"namespace_category","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Category.id","file":"shared/category.ts","doc":"","url":"./shared/category.ts/~/Category.id.html","deprecated":false},{"id":"namespace_category","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Category.kind","file":"shared/category.ts","doc":"What it files. It never changes.","url":"./shared/category.ts/~/Category.kind.html","deprecated":false},{"id":"namespace_category","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Category.slug","file":"shared/category.ts","doc":"","url":"./shared/category.ts/~/Category.slug.html","deprecated":false},{"id":"namespace_category","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Category.name","file":"shared/category.ts","doc":"","url":"./shared/category.ts/~/Category.name.html","deprecated":false},{"id":"namespace_category","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Category.position","file":"shared/category.ts","doc":"Sorts the categories, lowest first.","url":"./shared/category.ts/~/Category.position.html","deprecated":false},{"id":"namespace_category","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Category.createdAt","file":"shared/category.ts","doc":"","url":"./shared/category.ts/~/Category.createdAt.html","deprecated":false},{"id":"namespace_category","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Category.updatedAt","file":"shared/category.ts","doc":"","url":"./shared/category.ts/~/Category.updatedAt.html","deprecated":false},{"id":"namespace_createcategoryrequest","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"CreateCategoryRequest","file":"shared/category.ts","doc":"Passed to POST /api/categories. The slug must be free within its kind, and a dump category's not reserved by a route.","url":"./shared/category.ts/~/CreateCategoryRequest.html","deprecated":false},{"id":"namespace_createcategoryrequest","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CreateCategoryRequest.kind","file":"shared/category.ts","doc":"","url":"./shared/category.ts/~/CreateCategoryRequest.kind.html","deprecated":false},{"id":"namespace_createcategoryrequest","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CreateCategoryRequest.slug","file":"shared/category.ts","doc":"","url":"./shared/category.ts/~/CreateCategoryRequest.slug.html","deprecated":false},{"id":"namespace_createcategoryrequest","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CreateCategoryRequest.name","file":"shared/category.ts","doc":"","url":"./shared/category.ts/~/CreateCategoryRequest.name.html","deprecated":false},{"id":"namespace_createcategoryrequest","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CreateCategoryRequest.position","file":"shared/category.ts","doc":"0 when left out.","url":"./shared/category.ts/~/CreateCategoryRequest.position.html","deprecated":false},{"id":"namespace_updatecategoryrequest","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"UpdateCategoryRequest","file":"shared/category.ts","doc":"Passed to PUT /api/categories/:id. A field left out keeps its value, and the kind is kept.","url":"./shared/category.ts/~/UpdateCategoryRequest.html","deprecated":false},{"id":"namespace_updatecategoryrequest","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"UpdateCategoryRequest.slug","file":"shared/category.ts","doc":"","url":"./shared/category.ts/~/UpdateCategoryRequest.slug.html","deprecated":false},{"id":"namespace_updatecategoryrequest","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"UpdateCategoryRequest.name","file":"shared/category.ts","doc":"","url":"./shared/category.ts/~/UpdateCategoryRequest.name.html","deprecated":false},{"id":"namespace_updatecategoryrequest","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"UpdateCategoryRequest.position","file":"shared/category.ts","doc":"","url":"./shared/category.ts/~/UpdateCategoryRequest.position.html","deprecated":false},{"id":"namespace_chatmessage","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"ChatMessage","file":"shared/chat.ts","doc":"Returned by GET /api/chat, and sent by the server in chat_message and chat_message_updated. The client reads it through deserializeChatMessage, which turns its dates back into Dates.","url":"./shared/chat.ts/~/ChatMessage.html","deprecated":false},{"id":"namespace_chatmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ChatMessage.id","file":"shared/chat.ts","doc":"","url":"./shared/chat.ts/~/ChatMessage.id.html","deprecated":false},{"id":"namespace_chatmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ChatMessage.userId","file":"shared/chat.ts","doc":"","url":"./shared/chat.ts/~/ChatMessage.userId.html","deprecated":false},{"id":"namespace_chatmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ChatMessage.body","file":"shared/chat.ts","doc":"In Markdown, trimmed by the server.","url":"./shared/chat.ts/~/ChatMessage.body.html","deprecated":false},{"id":"namespace_chatmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ChatMessage.createdAt","file":"shared/chat.ts","doc":"","url":"./shared/chat.ts/~/ChatMessage.createdAt.html","deprecated":false},{"id":"namespace_chatmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ChatMessage.updatedAt","file":"shared/chat.ts","doc":"Absent until the first edit.","url":"./shared/chat.ts/~/ChatMessage.updatedAt.html","deprecated":false},{"id":"namespace_chatmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ChatMessage.authorUsername","file":"shared/chat.ts","doc":"","url":"./shared/chat.ts/~/ChatMessage.authorUsername.html","deprecated":false},{"id":"namespace_chatmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ChatMessage.authorAvatarMime","file":"shared/chat.ts","doc":"","url":"./shared/chat.ts/~/ChatMessage.authorAvatarMime.html","deprecated":false},{"id":"namespace_chatmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ChatMessage.replyToId","file":"shared/chat.ts","doc":"Kept when the message it points to is deleted, while replyToAuthor and replyToBody then go absent.","url":"./shared/chat.ts/~/ChatMessage.replyToId.html","deprecated":false},{"id":"namespace_chatmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ChatMessage.replyToAuthor","file":"shared/chat.ts","doc":"","url":"./shared/chat.ts/~/ChatMessage.replyToAuthor.html","deprecated":false},{"id":"namespace_chatmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ChatMessage.replyToBody","file":"shared/chat.ts","doc":"The first 300 characters of the replied-to body, in Markdown.","url":"./shared/chat.ts/~/ChatMessage.replyToBody.html","deprecated":false},{"id":"namespace_chatmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ChatMessage.mentionsEveryone","file":"shared/chat.ts","doc":"Set when the body says @everyone and its author's role had chat:everyone when it was last written; absent otherwise. The client highlights the message for everyone and shows @everyone as a mention by it, never by the text, which anyone may type.","url":"./shared/chat.ts/~/ChatMessage.mentionsEveryone.html","deprecated":false},{"id":"namespace_comment","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"Comment","file":"shared/comment.ts","doc":"Returned by the comment routes, and sent in the comment_created and comment_updated WebSocket messages. It carries its author's name and avatar, so the thread needn't look them up.","url":"./shared/comment.ts/~/Comment.html","deprecated":false},{"id":"namespace_comment","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Comment.id","file":"shared/comment.ts","doc":"","url":"./shared/comment.ts/~/Comment.id.html","deprecated":false},{"id":"namespace_comment","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Comment.dumpId","file":"shared/comment.ts","doc":"","url":"./shared/comment.ts/~/Comment.dumpId.html","deprecated":false},{"id":"namespace_comment","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Comment.userId","file":"shared/comment.ts","doc":"","url":"./shared/comment.ts/~/Comment.userId.html","deprecated":false},{"id":"namespace_comment","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Comment.parentId","file":"shared/comment.ts","doc":"It is undefined on a top-level comment.","url":"./shared/comment.ts/~/Comment.parentId.html","deprecated":false},{"id":"namespace_comment","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Comment.body","file":"shared/comment.ts","doc":"The Markdown text. Deleting the comment empties it.","url":"./shared/comment.ts/~/Comment.body.html","deprecated":false},{"id":"namespace_comment","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Comment.createdAt","file":"shared/comment.ts","doc":"","url":"./shared/comment.ts/~/Comment.createdAt.html","deprecated":false},{"id":"namespace_comment","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Comment.updatedAt","file":"shared/comment.ts","doc":"","url":"./shared/comment.ts/~/Comment.updatedAt.html","deprecated":false},{"id":"namespace_comment","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Comment.deleted","file":"shared/comment.ts","doc":"A deleted comment stays in the thread, emptied, so its replies keep their place.","url":"./shared/comment.ts/~/Comment.deleted.html","deprecated":false},{"id":"namespace_comment","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Comment.likeCount","file":"shared/comment.ts","doc":"","url":"./shared/comment.ts/~/Comment.likeCount.html","deprecated":false},{"id":"namespace_comment","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Comment.authorUsername","file":"shared/comment.ts","doc":"","url":"./shared/comment.ts/~/Comment.authorUsername.html","deprecated":false},{"id":"namespace_comment","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Comment.authorAvatarMime","file":"shared/comment.ts","doc":"","url":"./shared/comment.ts/~/Comment.authorAvatarMime.html","deprecated":false},{"id":"namespace_createcommentrequest","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"CreateCommentRequest","file":"shared/comment.ts","doc":"Passed to POST /api/dumps/:dumpId/comments by CommentThread, and by CommentNode for a reply. The body must not be blank.","url":"./shared/comment.ts/~/CreateCommentRequest.html","deprecated":false},{"id":"namespace_createcommentrequest","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CreateCommentRequest.body","file":"shared/comment.ts","doc":"","url":"./shared/comment.ts/~/CreateCommentRequest.body.html","deprecated":false},{"id":"namespace_createcommentrequest","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CreateCommentRequest.parentId","file":"shared/comment.ts","doc":"","url":"./shared/comment.ts/~/CreateCommentRequest.parentId.html","deprecated":false},{"id":"namespace_updatecommentrequest","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"UpdateCommentRequest","file":"shared/comment.ts","doc":"Passed to PATCH /api/comments/:commentId by CommentNode.","url":"./shared/comment.ts/~/UpdateCommentRequest.html","deprecated":false},{"id":"namespace_updatecommentrequest","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"UpdateCommentRequest.body","file":"shared/comment.ts","doc":"","url":"./shared/comment.ts/~/UpdateCommentRequest.body.html","deprecated":false},{"id":"namespace_communitystats","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"CommunityStats","file":"shared/community.ts","doc":"Returned by GET /api/community?period= to the Community page, and gathered by community-service.ts, which the digests read too.","url":"./shared/community.ts/~/CommunityStats.html","deprecated":false},{"id":"namespace_communitystats","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommunityStats.from","file":"shared/community.ts","doc":"The period covered, from from to to.","url":"./shared/community.ts/~/CommunityStats.from.html","deprecated":false},{"id":"namespace_communitystats","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommunityStats.to","file":"shared/community.ts","doc":"","url":"./shared/community.ts/~/CommunityStats.to.html","deprecated":false},{"id":"namespace_communitystats","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommunityStats.top","file":"shared/community.ts","doc":"The most upvoted public dumps posted in it, 10 at most.","url":"./shared/community.ts/~/CommunityStats.top.html","deprecated":false},{"id":"namespace_communitystats","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommunityStats.members","file":"shared/community.ts","doc":"In sign-up order, each with invitedByUsername when someone invited them.","url":"./shared/community.ts/~/CommunityStats.members.html","deprecated":false},{"id":"namespace_communitystats","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommunityStats.playlists","file":"shared/community.ts","doc":"The public playlists created in it, the fullest first, with dumpCount.","url":"./shared/community.ts/~/CommunityStats.playlists.html","deprecated":false},{"id":"namespace_communitystats","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommunityStats.chatMessages","file":"shared/community.ts","doc":"","url":"./shared/community.ts/~/CommunityStats.chatMessages.html","deprecated":false},{"id":"namespace_communitystats","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommunityStats.totals","file":"shared/community.ts","doc":"Public dumps posted, upvotes cast and comments written in it.","url":"./shared/community.ts/~/CommunityStats.totals.html","deprecated":false},{"id":"namespace_communitystats","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommunityStats.totals.dumps","file":"shared/community.ts","doc":"","url":"./shared/community.ts/~/CommunityStats.totals.dumps.html","deprecated":false},{"id":"namespace_communitystats","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommunityStats.totals.upvotes","file":"shared/community.ts","doc":"","url":"./shared/community.ts/~/CommunityStats.totals.upvotes.html","deprecated":false},{"id":"namespace_communitystats","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommunityStats.totals.comments","file":"shared/community.ts","doc":"","url":"./shared/community.ts/~/CommunityStats.totals.comments.html","deprecated":false},{"id":"namespace_communityitem","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"CommunityItem","file":"shared/community.ts","doc":"Names a dump or a playlist in a CommunityEvent: its title, and what dumpPath or playlistPath builds its page's path from.","url":"./shared/community.ts/~/CommunityItem.html","deprecated":false},{"id":"namespace_communityitem","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommunityItem.title","file":"shared/community.ts","doc":"","url":"./shared/community.ts/~/CommunityItem.title.html","deprecated":false},{"id":"namespace_dumppostedevent","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"DumpPostedEvent","file":"shared/community.ts","doc":"A public dump was posted. A dump made public later keeps its date.","url":"./shared/community.ts/~/DumpPostedEvent.html","deprecated":false},{"id":"namespace_dumppostedevent","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DumpPostedEvent.type","file":"shared/community.ts","doc":"","url":"./shared/community.ts/~/DumpPostedEvent.type.html","deprecated":false},{"id":"namespace_dumppostedevent","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DumpPostedEvent.dump","file":"shared/community.ts","doc":"","url":"./shared/community.ts/~/DumpPostedEvent.dump.html","deprecated":false},{"id":"namespace_playlistcreatedevent","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"PlaylistCreatedEvent","file":"shared/community.ts","doc":"A public playlist was created.","url":"./shared/community.ts/~/PlaylistCreatedEvent.html","deprecated":false},{"id":"namespace_playlistcreatedevent","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PlaylistCreatedEvent.type","file":"shared/community.ts","doc":"","url":"./shared/community.ts/~/PlaylistCreatedEvent.type.html","deprecated":false},{"id":"namespace_playlistcreatedevent","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PlaylistCreatedEvent.playlist","file":"shared/community.ts","doc":"","url":"./shared/community.ts/~/PlaylistCreatedEvent.playlist.html","deprecated":false},{"id":"namespace_dumpcommentedevent","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"DumpCommentedEvent","file":"shared/community.ts","doc":"A public dump got a comment. However many it got, the feed tells of its latest alone.","url":"./shared/community.ts/~/DumpCommentedEvent.html","deprecated":false},{"id":"namespace_dumpcommentedevent","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DumpCommentedEvent.type","file":"shared/community.ts","doc":"","url":"./shared/community.ts/~/DumpCommentedEvent.type.html","deprecated":false},{"id":"namespace_dumpcommentedevent","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DumpCommentedEvent.dump","file":"shared/community.ts","doc":"","url":"./shared/community.ts/~/DumpCommentedEvent.dump.html","deprecated":false},{"id":"namespace_dumpcommentedevent","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DumpCommentedEvent.commentId","file":"shared/community.ts","doc":"For the #comment- anchor on the dump's page.","url":"./shared/community.ts/~/DumpCommentedEvent.commentId.html","deprecated":false},{"id":"namespace_dumpupvotedevent","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"DumpUpvotedEvent","file":"shared/community.ts","doc":"A public dump got an upvote, told as DumpCommentedEvent is.","url":"./shared/community.ts/~/DumpUpvotedEvent.html","deprecated":false},{"id":"namespace_dumpupvotedevent","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DumpUpvotedEvent.type","file":"shared/community.ts","doc":"","url":"./shared/community.ts/~/DumpUpvotedEvent.type.html","deprecated":false},{"id":"namespace_dumpupvotedevent","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DumpUpvotedEvent.dump","file":"shared/community.ts","doc":"","url":"./shared/community.ts/~/DumpUpvotedEvent.dump.html","deprecated":false},{"id":"namespace_userjoinedevent","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"UserJoinedEvent","file":"shared/community.ts","doc":"Someone joined the site: username is theirs.","url":"./shared/community.ts/~/UserJoinedEvent.html","deprecated":false},{"id":"namespace_userjoinedevent","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"UserJoinedEvent.type","file":"shared/community.ts","doc":"","url":"./shared/community.ts/~/UserJoinedEvent.type.html","deprecated":false},{"id":"namespace_userjoinedevent","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"UserJoinedEvent.invitedByUsername","file":"shared/community.ts","doc":"","url":"./shared/community.ts/~/UserJoinedEvent.invitedByUsername.html","deprecated":false},{"id":"namespace_communityevent","kind":[{"char":"T","kind":"TypeAlias","title":"Type Alias"}],"name":"CommunityEvent","file":"shared/community.ts","doc":"One line of the community feed, told apart by type.","url":"./shared/community.ts/~/CommunityEvent.html","deprecated":false},{"id":"namespace_communityfeed","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"CommunityFeed","file":"shared/community.ts","doc":"Returned by GET /api/community/feed to CommunityFeedProvider, which asks again as the socket tells of changes, and rendered by the CommunityFeed component with who is online, which the client knows from its socket. community-service.ts gathers it. Everything in it is public: every reader gets the same feed.","url":"./shared/community.ts/~/CommunityFeed.html","deprecated":false},{"id":"namespace_communityfeed","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommunityFeed.events","file":"shared/community.ts","doc":"The latest events, newest first, 12 at most.","url":"./shared/community.ts/~/CommunityFeed.events.html","deprecated":false},{"id":"namespace_communityfeed","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommunityFeed.week","file":"shared/community.ts","doc":"The last week's figures, as /community shows them: as of the server's last refresh.","url":"./shared/community.ts/~/CommunityFeed.week.html","deprecated":false},{"id":"namespace_communityeventbase","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"CommunityEventBase","file":"shared/community.ts","doc":"What every CommunityEvent carries.","url":"./shared/community.ts/~/CommunityEventBase.html","deprecated":false},{"id":"namespace_communityeventbase","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommunityEventBase.id","file":"shared/community.ts","doc":"The event's kind and what it is about, dump_upvoted:: unique in a feed, where a dump has one event of each kind at most.","url":"./shared/community.ts/~/CommunityEventBase.id.html","deprecated":false},{"id":"namespace_communityeventbase","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommunityEventBase.at","file":"shared/community.ts","doc":"","url":"./shared/community.ts/~/CommunityEventBase.at.html","deprecated":false},{"id":"namespace_communityeventbase","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommunityEventBase.username","file":"shared/community.ts","doc":"Who did it, by their current name.","url":"./shared/community.ts/~/CommunityEventBase.username.html","deprecated":false},{"id":"namespace_digest_messages","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"DIGEST_MESSAGES","file":"shared/digest-messages.ts","doc":"The shared messages, by name.","url":"./shared/digest-messages.ts/~/DIGEST_MESSAGES.html","deprecated":false},{"id":"namespace_digest_messages","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DIGEST_MESSAGES.weekly","file":"shared/digest-messages.ts","doc":"","url":"./shared/digest-messages.ts/~/DIGEST_MESSAGES.weekly.html","deprecated":false},{"id":"namespace_digest_messages","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DIGEST_MESSAGES.weekly.id","file":"shared/digest-messages.ts","doc":"","url":"./shared/digest-messages.ts/~/DIGEST_MESSAGES.weekly.id.html","deprecated":false},{"id":"namespace_digest_messages","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DIGEST_MESSAGES.weekly.message","file":"shared/digest-messages.ts","doc":"","url":"./shared/digest-messages.ts/~/DIGEST_MESSAGES.weekly.message.html","deprecated":false},{"id":"namespace_digest_messages","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DIGEST_MESSAGES.monthly","file":"shared/digest-messages.ts","doc":"","url":"./shared/digest-messages.ts/~/DIGEST_MESSAGES.monthly.html","deprecated":false},{"id":"namespace_digest_messages","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DIGEST_MESSAGES.monthly.id","file":"shared/digest-messages.ts","doc":"","url":"./shared/digest-messages.ts/~/DIGEST_MESSAGES.monthly.id.html","deprecated":false},{"id":"namespace_digest_messages","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DIGEST_MESSAGES.monthly.message","file":"shared/digest-messages.ts","doc":"","url":"./shared/digest-messages.ts/~/DIGEST_MESSAGES.monthly.message.html","deprecated":false},{"id":"namespace_digest_messages","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DIGEST_MESSAGES.weeklyOff","file":"shared/digest-messages.ts","doc":"","url":"./shared/digest-messages.ts/~/DIGEST_MESSAGES.weeklyOff.html","deprecated":false},{"id":"namespace_digest_messages","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DIGEST_MESSAGES.weeklyOff.id","file":"shared/digest-messages.ts","doc":"","url":"./shared/digest-messages.ts/~/DIGEST_MESSAGES.weeklyOff.id.html","deprecated":false},{"id":"namespace_digest_messages","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DIGEST_MESSAGES.weeklyOff.message","file":"shared/digest-messages.ts","doc":"","url":"./shared/digest-messages.ts/~/DIGEST_MESSAGES.weeklyOff.message.html","deprecated":false},{"id":"namespace_digest_messages","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DIGEST_MESSAGES.monthlyOff","file":"shared/digest-messages.ts","doc":"","url":"./shared/digest-messages.ts/~/DIGEST_MESSAGES.monthlyOff.html","deprecated":false},{"id":"namespace_digest_messages","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DIGEST_MESSAGES.monthlyOff.id","file":"shared/digest-messages.ts","doc":"","url":"./shared/digest-messages.ts/~/DIGEST_MESSAGES.monthlyOff.id.html","deprecated":false},{"id":"namespace_digest_messages","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DIGEST_MESSAGES.monthlyOff.message","file":"shared/digest-messages.ts","doc":"","url":"./shared/digest-messages.ts/~/DIGEST_MESSAGES.monthlyOff.message.html","deprecated":false},{"id":"namespace_digest_messages","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DIGEST_MESSAGES.community","file":"shared/digest-messages.ts","doc":"","url":"./shared/digest-messages.ts/~/DIGEST_MESSAGES.community.html","deprecated":false},{"id":"namespace_digest_messages","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DIGEST_MESSAGES.community.id","file":"shared/digest-messages.ts","doc":"","url":"./shared/digest-messages.ts/~/DIGEST_MESSAGES.community.id.html","deprecated":false},{"id":"namespace_digest_messages","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DIGEST_MESSAGES.community.message","file":"shared/digest-messages.ts","doc":"","url":"./shared/digest-messages.ts/~/DIGEST_MESSAGES.community.message.html","deprecated":false},{"id":"namespace_digest_messages","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DIGEST_MESSAGES.topWeek","file":"shared/digest-messages.ts","doc":"","url":"./shared/digest-messages.ts/~/DIGEST_MESSAGES.topWeek.html","deprecated":false},{"id":"namespace_digest_messages","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DIGEST_MESSAGES.topWeek.id","file":"shared/digest-messages.ts","doc":"","url":"./shared/digest-messages.ts/~/DIGEST_MESSAGES.topWeek.id.html","deprecated":false},{"id":"namespace_digest_messages","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DIGEST_MESSAGES.topWeek.message","file":"shared/digest-messages.ts","doc":"","url":"./shared/digest-messages.ts/~/DIGEST_MESSAGES.topWeek.message.html","deprecated":false},{"id":"namespace_digest_messages","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DIGEST_MESSAGES.topMonth","file":"shared/digest-messages.ts","doc":"","url":"./shared/digest-messages.ts/~/DIGEST_MESSAGES.topMonth.html","deprecated":false},{"id":"namespace_digest_messages","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DIGEST_MESSAGES.topMonth.id","file":"shared/digest-messages.ts","doc":"","url":"./shared/digest-messages.ts/~/DIGEST_MESSAGES.topMonth.id.html","deprecated":false},{"id":"namespace_digest_messages","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DIGEST_MESSAGES.topMonth.message","file":"shared/digest-messages.ts","doc":"","url":"./shared/digest-messages.ts/~/DIGEST_MESSAGES.topMonth.message.html","deprecated":false},{"id":"namespace_digest_messages","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DIGEST_MESSAGES.newMembers","file":"shared/digest-messages.ts","doc":"","url":"./shared/digest-messages.ts/~/DIGEST_MESSAGES.newMembers.html","deprecated":false},{"id":"namespace_digest_messages","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DIGEST_MESSAGES.newMembers.id","file":"shared/digest-messages.ts","doc":"","url":"./shared/digest-messages.ts/~/DIGEST_MESSAGES.newMembers.id.html","deprecated":false},{"id":"namespace_digest_messages","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DIGEST_MESSAGES.newMembers.message","file":"shared/digest-messages.ts","doc":"","url":"./shared/digest-messages.ts/~/DIGEST_MESSAGES.newMembers.message.html","deprecated":false},{"id":"namespace_digest_messages","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DIGEST_MESSAGES.newPlaylists","file":"shared/digest-messages.ts","doc":"","url":"./shared/digest-messages.ts/~/DIGEST_MESSAGES.newPlaylists.html","deprecated":false},{"id":"namespace_digest_messages","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DIGEST_MESSAGES.newPlaylists.id","file":"shared/digest-messages.ts","doc":"","url":"./shared/digest-messages.ts/~/DIGEST_MESSAGES.newPlaylists.id.html","deprecated":false},{"id":"namespace_digest_messages","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DIGEST_MESSAGES.newPlaylists.message","file":"shared/digest-messages.ts","doc":"","url":"./shared/digest-messages.ts/~/DIGEST_MESSAGES.newPlaylists.message.html","deprecated":false},{"id":"namespace_digest_messages","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DIGEST_MESSAGES.invitedBy","file":"shared/digest-messages.ts","doc":"","url":"./shared/digest-messages.ts/~/DIGEST_MESSAGES.invitedBy.html","deprecated":false},{"id":"namespace_digest_messages","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DIGEST_MESSAGES.invitedBy.id","file":"shared/digest-messages.ts","doc":"","url":"./shared/digest-messages.ts/~/DIGEST_MESSAGES.invitedBy.id.html","deprecated":false},{"id":"namespace_digest_messages","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DIGEST_MESSAGES.invitedBy.message","file":"shared/digest-messages.ts","doc":"","url":"./shared/digest-messages.ts/~/DIGEST_MESSAGES.invitedBy.message.html","deprecated":false},{"id":"namespace_digest_messages","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DIGEST_MESSAGES.invitedByYou","file":"shared/digest-messages.ts","doc":"","url":"./shared/digest-messages.ts/~/DIGEST_MESSAGES.invitedByYou.html","deprecated":false},{"id":"namespace_digest_messages","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DIGEST_MESSAGES.invitedByYou.id","file":"shared/digest-messages.ts","doc":"","url":"./shared/digest-messages.ts/~/DIGEST_MESSAGES.invitedByYou.id.html","deprecated":false},{"id":"namespace_digest_messages","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DIGEST_MESSAGES.invitedByYou.message","file":"shared/digest-messages.ts","doc":"","url":"./shared/digest-messages.ts/~/DIGEST_MESSAGES.invitedByYou.message.html","deprecated":false},{"id":"namespace_digest_messages","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DIGEST_MESSAGES.statDumps","file":"shared/digest-messages.ts","doc":"","url":"./shared/digest-messages.ts/~/DIGEST_MESSAGES.statDumps.html","deprecated":false},{"id":"namespace_digest_messages","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DIGEST_MESSAGES.statDumps.id","file":"shared/digest-messages.ts","doc":"","url":"./shared/digest-messages.ts/~/DIGEST_MESSAGES.statDumps.id.html","deprecated":false},{"id":"namespace_digest_messages","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DIGEST_MESSAGES.statDumps.message","file":"shared/digest-messages.ts","doc":"","url":"./shared/digest-messages.ts/~/DIGEST_MESSAGES.statDumps.message.html","deprecated":false},{"id":"namespace_digest_messages","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DIGEST_MESSAGES.statChat","file":"shared/digest-messages.ts","doc":"","url":"./shared/digest-messages.ts/~/DIGEST_MESSAGES.statChat.html","deprecated":false},{"id":"namespace_digest_messages","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DIGEST_MESSAGES.statChat.id","file":"shared/digest-messages.ts","doc":"","url":"./shared/digest-messages.ts/~/DIGEST_MESSAGES.statChat.id.html","deprecated":false},{"id":"namespace_digest_messages","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DIGEST_MESSAGES.statChat.message","file":"shared/digest-messages.ts","doc":"","url":"./shared/digest-messages.ts/~/DIGEST_MESSAGES.statChat.message.html","deprecated":false},{"id":"namespace_digest_messages","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DIGEST_MESSAGES.countUpvotes","file":"shared/digest-messages.ts","doc":"","url":"./shared/digest-messages.ts/~/DIGEST_MESSAGES.countUpvotes.html","deprecated":false},{"id":"namespace_digest_messages","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DIGEST_MESSAGES.countUpvotes.id","file":"shared/digest-messages.ts","doc":"","url":"./shared/digest-messages.ts/~/DIGEST_MESSAGES.countUpvotes.id.html","deprecated":false},{"id":"namespace_digest_messages","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DIGEST_MESSAGES.countUpvotes.message","file":"shared/digest-messages.ts","doc":"","url":"./shared/digest-messages.ts/~/DIGEST_MESSAGES.countUpvotes.message.html","deprecated":false},{"id":"namespace_digest_messages","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DIGEST_MESSAGES.countComments","file":"shared/digest-messages.ts","doc":"","url":"./shared/digest-messages.ts/~/DIGEST_MESSAGES.countComments.html","deprecated":false},{"id":"namespace_digest_messages","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DIGEST_MESSAGES.countComments.id","file":"shared/digest-messages.ts","doc":"","url":"./shared/digest-messages.ts/~/DIGEST_MESSAGES.countComments.id.html","deprecated":false},{"id":"namespace_digest_messages","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DIGEST_MESSAGES.countComments.message","file":"shared/digest-messages.ts","doc":"","url":"./shared/digest-messages.ts/~/DIGEST_MESSAGES.countComments.message.html","deprecated":false},{"id":"namespace_richcontenttype","kind":[{"char":"T","kind":"TypeAlias","title":"Type Alias"}],"name":"RichContentType","file":"shared/dump.ts","doc":"Names the kind of link a RichContent previews: a site the player plays its own way, or generic for any other page, this site's included.","url":"./shared/dump.ts/~/RichContentType.html","deprecated":false},{"id":"namespace_richcontent","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"RichContent","file":"shared/dump.ts","doc":"Built by a provider of rich-content-service.ts when a link is posted or previewed, and stored with the dump as JSON. The frontend's RichContentCard and player read it.","url":"./shared/dump.ts/~/RichContent.html","deprecated":false},{"id":"namespace_richcontent","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"RichContent.type","file":"shared/dump.ts","doc":"The player picks how to play the link by it.","url":"./shared/dump.ts/~/RichContent.type.html","deprecated":false},{"id":"namespace_richcontent","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"RichContent.url","file":"shared/dump.ts","doc":"","url":"./shared/dump.ts/~/RichContent.url.html","deprecated":false},{"id":"namespace_richcontent","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"RichContent.siteName","file":"shared/dump.ts","doc":"","url":"./shared/dump.ts/~/RichContent.siteName.html","deprecated":false},{"id":"namespace_richcontent","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"RichContent.title","file":"shared/dump.ts","doc":"","url":"./shared/dump.ts/~/RichContent.title.html","deprecated":false},{"id":"namespace_richcontent","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"RichContent.description","file":"shared/dump.ts","doc":"","url":"./shared/dump.ts/~/RichContent.description.html","deprecated":false},{"id":"namespace_richcontent","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"RichContent.thumbnailUrl","file":"shared/dump.ts","doc":"A real preview image (og:image, a large content image, a video still). Never a favicon — an absent value means \"this page offers no artwork\", which is what makes the generated placeholder possible.","url":"./shared/dump.ts/~/RichContent.thumbnailUrl.html","deprecated":false},{"id":"namespace_richcontent","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"RichContent.faviconUrl","file":"shared/dump.ts","doc":"Used as the placeholder's glyph.","url":"./shared/dump.ts/~/RichContent.faviconUrl.html","deprecated":false},{"id":"namespace_richcontent","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"RichContent.accentColor","file":"shared/dump.ts","doc":"The page's declared brand color, normalized to #rrggbb.","url":"./shared/dump.ts/~/RichContent.accentColor.html","deprecated":false},{"id":"namespace_richcontent","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"RichContent.embedUrl","file":"shared/dump.ts","doc":"The player a YouTube, Bandcamp or SoundCloud link plays in, framed by the frontend.","url":"./shared/dump.ts/~/RichContent.embedUrl.html","deprecated":false},{"id":"namespace_dump","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"Dump","file":"shared/dump.ts","doc":"Returned by every endpoint that answers dumps, and pushed to clients by the dump_created and dump_updated socket messages. A URL dump has url and richContent, a file dump the file… fields. A private dump reaches its poster only.","url":"./shared/dump.ts/~/Dump.html","deprecated":false},{"id":"namespace_dump","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Dump.id","file":"shared/dump.ts","doc":"","url":"./shared/dump.ts/~/Dump.id.html","deprecated":false},{"id":"namespace_dump","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Dump.kind","file":"shared/dump.ts","doc":"","url":"./shared/dump.ts/~/Dump.kind.html","deprecated":false},{"id":"namespace_dump","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Dump.title","file":"shared/dump.ts","doc":"","url":"./shared/dump.ts/~/Dump.title.html","deprecated":false},{"id":"namespace_dump","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Dump.slug","file":"shared/dump.ts","doc":"Names the dump in its page's path, dumpPath (shared/paths.ts) building it with ownerUsername. Made from the title on creation, it changes only when edited, and is unique among its poster's dumps.","url":"./shared/dump.ts/~/Dump.slug.html","deprecated":false},{"id":"namespace_dump","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Dump.comment","file":"shared/dump.ts","doc":"The poster's note on the dump, in Markdown.","url":"./shared/dump.ts/~/Dump.comment.html","deprecated":false},{"id":"namespace_dump","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Dump.userId","file":"shared/dump.ts","doc":"","url":"./shared/dump.ts/~/Dump.userId.html","deprecated":false},{"id":"namespace_dump","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Dump.ownerUsername","file":"shared/dump.ts","doc":"The poster's current name, which the dump's path starts with.","url":"./shared/dump.ts/~/Dump.ownerUsername.html","deprecated":false},{"id":"namespace_dump","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Dump.createdAt","file":"shared/dump.ts","doc":"","url":"./shared/dump.ts/~/Dump.createdAt.html","deprecated":false},{"id":"namespace_dump","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Dump.updatedAt","file":"shared/dump.ts","doc":"","url":"./shared/dump.ts/~/Dump.updatedAt.html","deprecated":false},{"id":"namespace_dump","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Dump.url","file":"shared/dump.ts","doc":"","url":"./shared/dump.ts/~/Dump.url.html","deprecated":false},{"id":"namespace_dump","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Dump.richContent","file":"shared/dump.ts","doc":"","url":"./shared/dump.ts/~/Dump.richContent.html","deprecated":false},{"id":"namespace_dump","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Dump.fileName","file":"shared/dump.ts","doc":"","url":"./shared/dump.ts/~/Dump.fileName.html","deprecated":false},{"id":"namespace_dump","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Dump.fileMime","file":"shared/dump.ts","doc":"","url":"./shared/dump.ts/~/Dump.fileMime.html","deprecated":false},{"id":"namespace_dump","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Dump.fileSize","file":"shared/dump.ts","doc":"","url":"./shared/dump.ts/~/Dump.fileSize.html","deprecated":false},{"id":"namespace_dump","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Dump.voteCount","file":"shared/dump.ts","doc":"","url":"./shared/dump.ts/~/Dump.voteCount.html","deprecated":false},{"id":"namespace_dump","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Dump.commentCount","file":"shared/dump.ts","doc":"Deleted comments are not counted.","url":"./shared/dump.ts/~/Dump.commentCount.html","deprecated":false},{"id":"namespace_dump","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Dump.isPrivate","file":"shared/dump.ts","doc":"","url":"./shared/dump.ts/~/Dump.isPrivate.html","deprecated":false},{"id":"namespace_dump","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Dump.thumbnailMime","file":"shared/dump.ts","doc":"Set when the poster uploaded a custom thumbnail.","url":"./shared/dump.ts/~/Dump.thumbnailMime.html","deprecated":false},{"id":"namespace_dump","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Dump.categoryIds","file":"shared/dump.ts","doc":"","url":"./shared/dump.ts/~/Dump.categoryIds.html","deprecated":false},{"id":"namespace_dumpurlmatch","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"DumpUrlMatch","file":"shared/dump.ts","doc":"Returned by GET /api/dumps?url= for each dump already posted with the link being typed, and shown by the create form's DuplicateNotice. It holds only what the notice displays and links to.","url":"./shared/dump.ts/~/DumpUrlMatch.html","deprecated":false},{"id":"namespace_dumpurlmatch","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DumpUrlMatch.id","file":"shared/dump.ts","doc":"","url":"./shared/dump.ts/~/DumpUrlMatch.id.html","deprecated":false},{"id":"namespace_dumpurlmatch","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DumpUrlMatch.slug","file":"shared/dump.ts","doc":"","url":"./shared/dump.ts/~/DumpUrlMatch.slug.html","deprecated":false},{"id":"namespace_dumpurlmatch","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DumpUrlMatch.title","file":"shared/dump.ts","doc":"","url":"./shared/dump.ts/~/DumpUrlMatch.title.html","deprecated":false},{"id":"namespace_dumpurlmatch","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DumpUrlMatch.ownerUsername","file":"shared/dump.ts","doc":"The poster's username.","url":"./shared/dump.ts/~/DumpUrlMatch.ownerUsername.html","deprecated":false},{"id":"namespace_dumpurlmatch","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DumpUrlMatch.createdAt","file":"shared/dump.ts","doc":"","url":"./shared/dump.ts/~/DumpUrlMatch.createdAt.html","deprecated":false},{"id":"namespace_dumpurlmatch","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DumpUrlMatch.voteCount","file":"shared/dump.ts","doc":"","url":"./shared/dump.ts/~/DumpUrlMatch.voteCount.html","deprecated":false},{"id":"namespace_dumpurlmatch","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DumpUrlMatch.commentCount","file":"shared/dump.ts","doc":"","url":"./shared/dump.ts/~/DumpUrlMatch.commentCount.html","deprecated":false},{"id":"namespace_linkpreview","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"LinkPreview","file":"shared/dump.ts","doc":"Returned by GET /api/remote/preview to the create form, which shows it before the link is posted.","url":"./shared/dump.ts/~/LinkPreview.html","deprecated":false},{"id":"namespace_linkpreview","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"LinkPreview.reached","file":"shared/dump.ts","doc":"False when the page couldn't be fetched. richContent is then a stub holding the host name, and this flag is how the form tells a dead link from a page with no preview.","url":"./shared/dump.ts/~/LinkPreview.reached.html","deprecated":false},{"id":"namespace_linkpreview","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"LinkPreview.richContent","file":"shared/dump.ts","doc":"Null only for a link that doesn't parse, which the route rejects before fetching anyway.","url":"./shared/dump.ts/~/LinkPreview.richContent.html","deprecated":false},{"id":"namespace_createurldumprequest","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"CreateUrlDumpRequest","file":"shared/dump.ts","doc":"Passed by the create form to POST /api/dumps as a JSON body, to post a link. A file is posted as a multipart form instead.","url":"./shared/dump.ts/~/CreateUrlDumpRequest.html","deprecated":false},{"id":"namespace_createurldumprequest","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CreateUrlDumpRequest.url","file":"shared/dump.ts","doc":"","url":"./shared/dump.ts/~/CreateUrlDumpRequest.url.html","deprecated":false},{"id":"namespace_createurldumprequest","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CreateUrlDumpRequest.title","file":"shared/dump.ts","doc":"Replaces the title read from the page, when the poster edited it.","url":"./shared/dump.ts/~/CreateUrlDumpRequest.title.html","deprecated":false},{"id":"namespace_createurldumprequest","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CreateUrlDumpRequest.comment","file":"shared/dump.ts","doc":"","url":"./shared/dump.ts/~/CreateUrlDumpRequest.comment.html","deprecated":false},{"id":"namespace_createurldumprequest","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CreateUrlDumpRequest.isPrivate","file":"shared/dump.ts","doc":"","url":"./shared/dump.ts/~/CreateUrlDumpRequest.isPrivate.html","deprecated":false},{"id":"namespace_createurldumprequest","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CreateUrlDumpRequest.categoryIds","file":"shared/dump.ts","doc":"","url":"./shared/dump.ts/~/CreateUrlDumpRequest.categoryIds.html","deprecated":false},{"id":"namespace_updatedumprequest","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"UpdateDumpRequest","file":"shared/dump.ts","doc":"Passed to PUT /api/dumps/:dumpId by the edit page, and by the dump page's inline title edit. A field left out stays as it is.","url":"./shared/dump.ts/~/UpdateDumpRequest.html","deprecated":false},{"id":"namespace_updatedumprequest","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"UpdateDumpRequest.url","file":"shared/dump.ts","doc":"Ignored for a file dump. A changed link has its preview fetched again.","url":"./shared/dump.ts/~/UpdateDumpRequest.url.html","deprecated":false},{"id":"namespace_updatedumprequest","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"UpdateDumpRequest.title","file":"shared/dump.ts","doc":"","url":"./shared/dump.ts/~/UpdateDumpRequest.title.html","deprecated":false},{"id":"namespace_updatedumprequest","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"UpdateDumpRequest.slug","file":"shared/dump.ts","doc":"A new slug, which the edit page's slug field sends. A title change never changes the slug by itself.","url":"./shared/dump.ts/~/UpdateDumpRequest.slug.html","deprecated":false},{"id":"namespace_updatedumprequest","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"UpdateDumpRequest.comment","file":"shared/dump.ts","doc":"null removes the note.","url":"./shared/dump.ts/~/UpdateDumpRequest.comment.html","deprecated":false},{"id":"namespace_updatedumprequest","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"UpdateDumpRequest.isPrivate","file":"shared/dump.ts","doc":"","url":"./shared/dump.ts/~/UpdateDumpRequest.isPrivate.html","deprecated":false},{"id":"namespace_updatedumprequest","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"UpdateDumpRequest.categoryIds","file":"shared/dump.ts","doc":"Replaces the current categories.","url":"./shared/dump.ts/~/UpdateDumpRequest.categoryIds.html","deprecated":false},{"id":"namespace_dumpfileversion","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"dumpFileVersion","file":"shared/dump.ts","doc":"Returns a file dump's version, which the file and thumbnail URLs carry as ?v=: the frontend's dumpFileUrl and dumpThumbnailUrl, and the digest's thumbnails. It changes whenever the file may have, so the file and thumbnail routes cache a URL naming the current one for good and revalidate any other. Without its dates, a dump gets a version no route serves as current.","url":"./shared/dump.ts/~/dumpFileVersion.html","deprecated":false},{"id":"namespace_federation_version","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"FEDERATION_VERSION","file":"shared/federation.ts","doc":"The version of the protocol below, which an instance announces in its InstanceMetadata. An instance refuses one announcing another.","url":"./shared/federation.ts/~/FEDERATION_VERSION.html","deprecated":false},{"id":"namespace_instancemetadata","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"InstanceMetadata","file":"shared/federation.ts","doc":"Served by every instance at /.well-known/openid-configuration (routes/well-known.ts), and read by another before it trusts it, starts a sign-in on it or sends it an event. The names are OpenID Connect's, and the gerbeur_ fields are this protocol's own.","url":"./shared/federation.ts/~/InstanceMetadata.html","deprecated":false},{"id":"namespace_instancemetadata","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"InstanceMetadata.issuer","file":"shared/federation.ts","doc":"The instance's public URL, an origin, which names it in every token.","url":"./shared/federation.ts/~/InstanceMetadata.issuer.html","deprecated":false},{"id":"namespace_instancemetadata","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"InstanceMetadata.authorization_endpoint","file":"shared/federation.ts","doc":"Its /authorize page, where a user lets another instance sign them in.","url":"./shared/federation.ts/~/InstanceMetadata.authorization_endpoint.html","deprecated":false},{"id":"namespace_instancemetadata","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"InstanceMetadata.token_endpoint","file":"shared/federation.ts","doc":"POST /api/oauth/tokens, which trades a code for an identity token.","url":"./shared/federation.ts/~/InstanceMetadata.token_endpoint.html","deprecated":false},{"id":"namespace_instancemetadata","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"InstanceMetadata.jwks_uri","file":"shared/federation.ts","doc":"GET /.well-known/jwks.json, its public keys.","url":"./shared/federation.ts/~/InstanceMetadata.jwks_uri.html","deprecated":false},{"id":"namespace_instancemetadata","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"InstanceMetadata.response_types_supported","file":"shared/federation.ts","doc":"","url":"./shared/federation.ts/~/InstanceMetadata.response_types_supported.html","deprecated":false},{"id":"namespace_instancemetadata","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"InstanceMetadata.grant_types_supported","file":"shared/federation.ts","doc":"","url":"./shared/federation.ts/~/InstanceMetadata.grant_types_supported.html","deprecated":false},{"id":"namespace_instancemetadata","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"InstanceMetadata.subject_types_supported","file":"shared/federation.ts","doc":"","url":"./shared/federation.ts/~/InstanceMetadata.subject_types_supported.html","deprecated":false},{"id":"namespace_instancemetadata","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"InstanceMetadata.id_token_signing_alg_values_supported","file":"shared/federation.ts","doc":"","url":"./shared/federation.ts/~/InstanceMetadata.id_token_signing_alg_values_supported.html","deprecated":false},{"id":"namespace_instancemetadata","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"InstanceMetadata.code_challenge_methods_supported","file":"shared/federation.ts","doc":"","url":"./shared/federation.ts/~/InstanceMetadata.code_challenge_methods_supported.html","deprecated":false},{"id":"namespace_instancemetadata","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"InstanceMetadata.scopes_supported","file":"shared/federation.ts","doc":"","url":"./shared/federation.ts/~/InstanceMetadata.scopes_supported.html","deprecated":false},{"id":"namespace_instancemetadata","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"InstanceMetadata.gerbeur_federation","file":"shared/federation.ts","doc":"FEDERATION_VERSION.","url":"./shared/federation.ts/~/InstanceMetadata.gerbeur_federation.html","deprecated":false},{"id":"namespace_instancemetadata","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"InstanceMetadata.gerbeur_site_name","file":"shared/federation.ts","doc":"The site's name, which a consent page and the peer list show.","url":"./shared/federation.ts/~/InstanceMetadata.gerbeur_site_name.html","deprecated":false},{"id":"namespace_instancemetadata","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"InstanceMetadata.gerbeur_redirect_uri","file":"shared/federation.ts","doc":"Where its home instance sends a user back once they consent, as a client: its /federation/callback page, on its frontend.","url":"./shared/federation.ts/~/InstanceMetadata.gerbeur_redirect_uri.html","deprecated":false},{"id":"namespace_instancemetadata","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"InstanceMetadata.gerbeur_events_endpoint","file":"shared/federation.ts","doc":"POST /api/federation/events, where it receives a home's events.","url":"./shared/federation.ts/~/InstanceMetadata.gerbeur_events_endpoint.html","deprecated":false},{"id":"namespace_instancemetadata","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"InstanceMetadata.gerbeur_outgoing","file":"shared/federation.ts","doc":"Whether its users may sign in to other instances, so that a client refuses at once to send them to its /authorize page, which would. An instance that doesn't say lets them.","url":"./shared/federation.ts/~/InstanceMetadata.gerbeur_outgoing.html","deprecated":false},{"id":"namespace_isinstancemetadata","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"isInstanceMetadata","file":"shared/federation.ts","doc":"Checks whether value is an InstanceMetadata of this protocol's version, as remote/gerbeur-instance.ts must before reading one.","url":"./shared/federation.ts/~/isInstanceMetadata.html","deprecated":false},{"id":"namespace_parseinstance","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"parseInstance","file":"shared/federation.ts","doc":"Returns the origin of the instance input names, or null when it names none. Someone may type a bare host (music.example, taken as https), a URL, or a handle's host with its port (localhost:8001); a URL with a path names no instance. Whether plain http is allowed is the server's call.","url":"./shared/federation.ts/~/parseInstance.html","deprecated":false},{"id":"namespace_instancehost","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"instanceHost","file":"shared/federation.ts","doc":"Returns the host of the instance at issuer, with its port if it has one: the part after the @ of its users' handles here (alice@music.example).","url":"./shared/federation.ts/~/instanceHost.html","deprecated":false},{"id":"namespace_peerstatus","kind":[{"char":"T","kind":"TypeAlias","title":"Type Alias"}],"name":"PeerStatus","file":"shared/federation.ts","doc":"What an admin decided about an instance. Users of a trusted one sign in here directly; those of a blocked one never do, and its users already here are signed out. An instance with neither is invite only: its users sign in here with an invite.","url":"./shared/federation.ts/~/PeerStatus.html","deprecated":false},{"id":"namespace_peer_statuses","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"PEER_STATUSES","file":"shared/federation.ts","doc":"Every PeerStatus.","url":"./shared/federation.ts/~/PEER_STATUSES.html","deprecated":false},{"id":"namespace_ispeerstatus","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"isPeerStatus","file":"shared/federation.ts","doc":"Checks whether value is a PeerStatus.","url":"./shared/federation.ts/~/isPeerStatus.html","deprecated":false},{"id":"namespace_federationpeer","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"FederationPeer","file":"shared/federation.ts","doc":"Returned by GET /api/federation/peers: the login page offers each trusted one, and /manage lists them all.","url":"./shared/federation.ts/~/FederationPeer.html","deprecated":false},{"id":"namespace_federationpeer","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"FederationPeer.issuer","file":"shared/federation.ts","doc":"","url":"./shared/federation.ts/~/FederationPeer.issuer.html","deprecated":false},{"id":"namespace_federationpeer","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"FederationPeer.host","file":"shared/federation.ts","doc":"instanceHost of the issuer.","url":"./shared/federation.ts/~/FederationPeer.host.html","deprecated":false},{"id":"namespace_federationpeer","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"FederationPeer.name","file":"shared/federation.ts","doc":"The site's name, as its metadata gave it when it was added.","url":"./shared/federation.ts/~/FederationPeer.name.html","deprecated":false},{"id":"namespace_federationpeer","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"FederationPeer.status","file":"shared/federation.ts","doc":"","url":"./shared/federation.ts/~/FederationPeer.status.html","deprecated":false},{"id":"namespace_federationpeer","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"FederationPeer.createdAt","file":"shared/federation.ts","doc":"","url":"./shared/federation.ts/~/FederationPeer.createdAt.html","deprecated":false},{"id":"namespace_setpeerrequest","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"SetPeerRequest","file":"shared/federation.ts","doc":"Sent to PUT /api/federation/peers by /manage.","url":"./shared/federation.ts/~/SetPeerRequest.html","deprecated":false},{"id":"namespace_setpeerrequest","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"SetPeerRequest.instance","file":"shared/federation.ts","doc":"As someone typed it, read with parseInstance.","url":"./shared/federation.ts/~/SetPeerRequest.instance.html","deprecated":false},{"id":"namespace_setpeerrequest","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"SetPeerRequest.status","file":"shared/federation.ts","doc":"","url":"./shared/federation.ts/~/SetPeerRequest.status.html","deprecated":false},{"id":"namespace_federationloginrequest","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"FederationLoginRequest","file":"shared/federation.ts","doc":"Sent to POST /api/federation/logins by the login page, or by the register page with the invite it was opened with.","url":"./shared/federation.ts/~/FederationLoginRequest.html","deprecated":false},{"id":"namespace_federationloginrequest","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"FederationLoginRequest.instance","file":"shared/federation.ts","doc":"The user's home instance, read with parseInstance.","url":"./shared/federation.ts/~/FederationLoginRequest.instance.html","deprecated":false},{"id":"namespace_federationloginrequest","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"FederationLoginRequest.inviteToken","file":"shared/federation.ts","doc":"","url":"./shared/federation.ts/~/FederationLoginRequest.inviteToken.html","deprecated":false},{"id":"namespace_federationloginresponse","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"FederationLoginResponse","file":"shared/federation.ts","doc":"Returned by POST /api/federation/logins: the home instance's /authorize page with the request in its query, which the client navigates to.","url":"./shared/federation.ts/~/FederationLoginResponse.html","deprecated":false},{"id":"namespace_federationloginresponse","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"FederationLoginResponse.authorizeUrl","file":"shared/federation.ts","doc":"","url":"./shared/federation.ts/~/FederationLoginResponse.authorizeUrl.html","deprecated":false},{"id":"namespace_federationsessionrequest","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"FederationSessionRequest","file":"shared/federation.ts","doc":"Sent to POST /api/federation/sessions by the /federation/callback page, from the query the home instance sent the user back with. The answer is an AuthResponse, as a sign-in's.","url":"./shared/federation.ts/~/FederationSessionRequest.html","deprecated":false},{"id":"namespace_federationsessionrequest","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"FederationSessionRequest.code","file":"shared/federation.ts","doc":"","url":"./shared/federation.ts/~/FederationSessionRequest.code.html","deprecated":false},{"id":"namespace_federationsessionrequest","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"FederationSessionRequest.state","file":"shared/federation.ts","doc":"","url":"./shared/federation.ts/~/FederationSessionRequest.state.html","deprecated":false},{"id":"namespace_oauthclient","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"OAuthClient","file":"shared/federation.ts","doc":"Returned by GET /api/oauth/clients?client_id= to the /authorize page, which asks the user whether to sign in there.","url":"./shared/federation.ts/~/OAuthClient.html","deprecated":false},{"id":"namespace_oauthclient","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"OAuthClient.clientId","file":"shared/federation.ts","doc":"","url":"./shared/federation.ts/~/OAuthClient.clientId.html","deprecated":false},{"id":"namespace_oauthclient","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"OAuthClient.host","file":"shared/federation.ts","doc":"","url":"./shared/federation.ts/~/OAuthClient.host.html","deprecated":false},{"id":"namespace_oauthclient","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"OAuthClient.name","file":"shared/federation.ts","doc":"","url":"./shared/federation.ts/~/OAuthClient.name.html","deprecated":false},{"id":"namespace_oauthclient","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"OAuthClient.granted","file":"shared/federation.ts","doc":"Whether the user already let it sign them in, in which case the page doesn't ask again.","url":"./shared/federation.ts/~/OAuthClient.granted.html","deprecated":false},{"id":"namespace_authorizerequest","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"AuthorizeRequest","file":"shared/federation.ts","doc":"Sent to POST /api/oauth/codes by the /authorize page once the user consents, from the query the client instance sent them with.","url":"./shared/federation.ts/~/AuthorizeRequest.html","deprecated":false},{"id":"namespace_authorizerequest","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"AuthorizeRequest.clientId","file":"shared/federation.ts","doc":"","url":"./shared/federation.ts/~/AuthorizeRequest.clientId.html","deprecated":false},{"id":"namespace_authorizerequest","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"AuthorizeRequest.redirectUri","file":"shared/federation.ts","doc":"","url":"./shared/federation.ts/~/AuthorizeRequest.redirectUri.html","deprecated":false},{"id":"namespace_authorizerequest","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"AuthorizeRequest.state","file":"shared/federation.ts","doc":"","url":"./shared/federation.ts/~/AuthorizeRequest.state.html","deprecated":false},{"id":"namespace_authorizerequest","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"AuthorizeRequest.codeChallenge","file":"shared/federation.ts","doc":"","url":"./shared/federation.ts/~/AuthorizeRequest.codeChallenge.html","deprecated":false},{"id":"namespace_authorizerequest","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"AuthorizeRequest.codeChallengeMethod","file":"shared/federation.ts","doc":"","url":"./shared/federation.ts/~/AuthorizeRequest.codeChallengeMethod.html","deprecated":false},{"id":"namespace_authorizerequest","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"AuthorizeRequest.nonce","file":"shared/federation.ts","doc":"","url":"./shared/federation.ts/~/AuthorizeRequest.nonce.html","deprecated":false},{"id":"namespace_authorizeresponse","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"AuthorizeResponse","file":"shared/federation.ts","doc":"Returned by POST /api/oauth/codes: the client's callback page with the code, where the /authorize page sends the user.","url":"./shared/federation.ts/~/AuthorizeResponse.html","deprecated":false},{"id":"namespace_authorizeresponse","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"AuthorizeResponse.redirectTo","file":"shared/federation.ts","doc":"","url":"./shared/federation.ts/~/AuthorizeResponse.redirectTo.html","deprecated":false},{"id":"namespace_federationgrant","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"FederationGrant","file":"shared/federation.ts","doc":"Returned by GET /api/me/grants to the settings page: an instance the user let their account sign in to.","url":"./shared/federation.ts/~/FederationGrant.html","deprecated":false},{"id":"namespace_federationgrant","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"FederationGrant.clientId","file":"shared/federation.ts","doc":"","url":"./shared/federation.ts/~/FederationGrant.clientId.html","deprecated":false},{"id":"namespace_federationgrant","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"FederationGrant.host","file":"shared/federation.ts","doc":"","url":"./shared/federation.ts/~/FederationGrant.host.html","deprecated":false},{"id":"namespace_federationgrant","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"FederationGrant.name","file":"shared/federation.ts","doc":"","url":"./shared/federation.ts/~/FederationGrant.name.html","deprecated":false},{"id":"namespace_federationgrant","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"FederationGrant.grantedAt","file":"shared/federation.ts","doc":"","url":"./shared/federation.ts/~/FederationGrant.grantedAt.html","deprecated":false},{"id":"namespace_federationgrant","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"FederationGrant.lastUsedAt","file":"shared/federation.ts","doc":"","url":"./shared/federation.ts/~/FederationGrant.lastUsedAt.html","deprecated":false},{"id":"namespace_identityclaims","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"IdentityClaims","file":"shared/federation.ts","doc":"Carried by an identity token and by an update event: what a home instance tells another of a user. The names are OpenID Connect's.","url":"./shared/federation.ts/~/IdentityClaims.html","deprecated":false},{"id":"namespace_identityclaims","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"IdentityClaims.preferred_username","file":"shared/federation.ts","doc":"The user's name at home; the client calls them @.","url":"./shared/federation.ts/~/IdentityClaims.preferred_username.html","deprecated":false},{"id":"namespace_identityclaims","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"IdentityClaims.email","file":"shared/federation.ts","doc":"","url":"./shared/federation.ts/~/IdentityClaims.email.html","deprecated":false},{"id":"namespace_identityclaims","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"IdentityClaims.picture","file":"shared/federation.ts","doc":"Their avatar's URL at home, versioned; absent without one.","url":"./shared/federation.ts/~/IdentityClaims.picture.html","deprecated":false},{"id":"namespace_federationevent","kind":[{"char":"T","kind":"TypeAlias","title":"Type Alias"}],"name":"FederationEvent","file":"shared/federation.ts","doc":"The payload of a signed event, which a home instance sends each instance a user signed in to (POST /api/federation/events): update when their name, email or avatar changed, revoke when their sessions there must end, after a password change or when they withdraw the grant.","url":"./shared/federation.ts/~/FederationEvent.html","deprecated":false},{"id":"namespace_isfederationevent","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"isFederationEvent","file":"shared/federation.ts","doc":"Checks whether value is a FederationEvent, as the events endpoint must once the signature is verified.","url":"./shared/federation.ts/~/isFederationEvent.html","deprecated":false},{"id":"namespace_isidentityclaims","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"isIdentityClaims","file":"shared/federation.ts","doc":"Checks whether value carries the IdentityClaims, as a client must before creating or updating an account from them.","url":"./shared/federation.ts/~/isIdentityClaims.html","deprecated":false},{"id":"namespace_followstatus","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"FollowStatus","file":"shared/follow.ts","doc":"Returned by GET /api/me/follow to FollowProvider, which then keeps it up to date itself as the user follows and unfollows.","url":"./shared/follow.ts/~/FollowStatus.html","deprecated":false},{"id":"namespace_followstatus","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"FollowStatus.followedUserIds","file":"shared/follow.ts","doc":"","url":"./shared/follow.ts/~/FollowStatus.followedUserIds.html","deprecated":false},{"id":"namespace_followstatus","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"FollowStatus.followedPlaylistIds","file":"shared/follow.ts","doc":"","url":"./shared/follow.ts/~/FollowStatus.followedPlaylistIds.html","deprecated":false},{"id":"namespace_image_widths","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"IMAGE_WIDTHS","file":"shared/image.ts","doc":"The widths, in pixels, smallest first: an avatar on a dense screen, a small cover, a card on a phone, and the widest feed card on a dense screen.","url":"./shared/image.ts/~/IMAGE_WIDTHS.html","deprecated":false},{"id":"namespace_imagewidth","kind":[{"char":"T","kind":"TypeAlias","title":"Type Alias"}],"name":"ImageWidth","file":"shared/image.ts","doc":"One of IMAGE_WIDTHS.","url":"./shared/image.ts/~/ImageWidth.html","deprecated":false},{"id":"namespace_max_image_width","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"MAX_IMAGE_WIDTH","file":"shared/image.ts","doc":"The largest of IMAGE_WIDTHS, which a thumbnail never exceeds.","url":"./shared/image.ts/~/MAX_IMAGE_WIDTH.html","deprecated":false},{"id":"namespace_snapimagewidth","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"snapImageWidth","file":"shared/image.ts","doc":"Returns the narrowest of IMAGE_WIDTHS that covers width pixels, or the widest when none does.","url":"./shared/image.ts/~/snapImageWidth.html","deprecated":false},{"id":"namespace_parseimagewidth","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"parseImageWidth","file":"shared/image.ts","doc":"Returns the width a ?w= value asks for, snapped to IMAGE_WIDTHS, or null when it is absent or not a positive number, which asks for the image as it is.","url":"./shared/image.ts/~/parseImageWidth.html","deprecated":false},{"id":"namespace_locales","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"LOCALES","file":"shared/locale.ts","doc":"Lists the locales the app is translated into.","url":"./shared/locale.ts/~/LOCALES.html","deprecated":false},{"id":"namespace_locale","kind":[{"char":"T","kind":"TypeAlias","title":"Type Alias"}],"name":"Locale","file":"shared/locale.ts","doc":"One of the LOCALES.","url":"./shared/locale.ts/~/Locale.html","deprecated":false},{"id":"namespace_source_locale","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"SOURCE_LOCALE","file":"shared/locale.ts","doc":"The locale the messages are written in, and the fallback for any other.","url":"./shared/locale.ts/~/SOURCE_LOCALE.html","deprecated":false},{"id":"namespace_islocale","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"isLocale","file":"shared/locale.ts","doc":"Checks whether value is a Locale.","url":"./shared/locale.ts/~/isLocale.html","deprecated":false},{"id":"namespace_markdowntoplaintext","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"markdownToPlainText","file":"shared/markdown.ts","doc":"Returns the Markdown md as one line of plain text. Images become their alt text, or imageLabel without one, and links their text. It also takes a body cut short, possibly inside a link, as the server cuts a chat message's replyToBody: the unfinished link then shows as its text, without half a URL.","url":"./shared/markdown.ts/~/markdownToPlainText.html","deprecated":false},{"id":"namespace_mention_re","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"MENTION_RE","file":"shared/mention.ts","doc":"Matches an @handle, a local @name or a remote user's @name@host (HANDLE_SOURCE), with the handle as its first group. The @ must not follow a word character, so an email address mentions no one. Nor may it follow [ or (, which leaves out a Markdown link's text or URL starting with @, and also a plain (@name). The editor's suggestions match its source at the caret; the rest goes through mentionedUsernames. Markdown links mentions with a looser pattern of its own, on text already parsed, where code and URLs are out of the way.","url":"./shared/mention.ts/~/MENTION_RE.html","deprecated":false},{"id":"namespace_mentionedusernames","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"mentionedUsernames","file":"shared/mention.ts","doc":"Returns the names body mentions, in lower case, each once. Code, fenced or inline, and URLs mention no one, as Markdown shows them. The server notifies by it, and the chat highlights and chimes by it.","url":"./shared/mention.ts/~/mentionedUsernames.html","deprecated":false},{"id":"namespace_everyone","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"EVERYONE","file":"shared/mention.ts","doc":"The name @everyone reaches. Said by a role with chat:everyone in the chat, it notifies every user, so no account may take it (assertUsernameAvailable).","url":"./shared/mention.ts/~/EVERYONE.html","deprecated":false},{"id":"namespace_mentionseveryone","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"mentionsEveryone","file":"shared/mention.ts","doc":"Checks whether body says @everyone, in any case, by the rule of mentionedUsernames. Only the chat service reads it, to set a message's mentionsEveryone when its author may; the client reads that flag, not the text.","url":"./shared/mention.ts/~/mentionsEveryone.html","deprecated":false},{"id":"namespace_notificationtype","kind":[{"char":"T","kind":"TypeAlias","title":"Type Alias"}],"name":"NotificationType","file":"shared/notification.ts","doc":"Says which of the …Data interfaces a notification's data is. Each value has one notify… trigger in notification-service.ts.","url":"./shared/notification.ts/~/NotificationType.html","deprecated":false},{"id":"namespace_dumpref","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"DumpRef","file":"shared/notification.ts","doc":"Where a notification's dump is now, for its link (dumpPath). The server joins it each time it sends the notification, so a renamed dump or poster still links right; it is absent once the dump is deleted.","url":"./shared/notification.ts/~/DumpRef.html","deprecated":false},{"id":"namespace_dumpref","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DumpRef.dumpSlug","file":"shared/notification.ts","doc":"","url":"./shared/notification.ts/~/DumpRef.dumpSlug.html","deprecated":false},{"id":"namespace_dumpref","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DumpRef.dumpOwnerUsername","file":"shared/notification.ts","doc":"","url":"./shared/notification.ts/~/DumpRef.dumpOwnerUsername.html","deprecated":false},{"id":"namespace_playlistref","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"PlaylistRef","file":"shared/notification.ts","doc":"Where a notification's playlist is now, joined as DumpRef is.","url":"./shared/notification.ts/~/PlaylistRef.html","deprecated":false},{"id":"namespace_playlistref","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PlaylistRef.playlistSlug","file":"shared/notification.ts","doc":"","url":"./shared/notification.ts/~/PlaylistRef.playlistSlug.html","deprecated":false},{"id":"namespace_playlistref","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PlaylistRef.playlistOwnerUsername","file":"shared/notification.ts","doc":"","url":"./shared/notification.ts/~/PlaylistRef.playlistOwnerUsername.html","deprecated":false},{"id":"namespace_playlistfolloweddata","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"PlaylistFollowedData","file":"shared/notification.ts","doc":"Carried by a playlist_followed notification, sent to a playlist's owner.","url":"./shared/notification.ts/~/PlaylistFollowedData.html","deprecated":false},{"id":"namespace_playlistfolloweddata","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PlaylistFollowedData.followerId","file":"shared/notification.ts","doc":"","url":"./shared/notification.ts/~/PlaylistFollowedData.followerId.html","deprecated":false},{"id":"namespace_playlistfolloweddata","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PlaylistFollowedData.followerUsername","file":"shared/notification.ts","doc":"","url":"./shared/notification.ts/~/PlaylistFollowedData.followerUsername.html","deprecated":false},{"id":"namespace_playlistfolloweddata","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PlaylistFollowedData.playlistId","file":"shared/notification.ts","doc":"","url":"./shared/notification.ts/~/PlaylistFollowedData.playlistId.html","deprecated":false},{"id":"namespace_playlistfolloweddata","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PlaylistFollowedData.playlistTitle","file":"shared/notification.ts","doc":"","url":"./shared/notification.ts/~/PlaylistFollowedData.playlistTitle.html","deprecated":false},{"id":"namespace_userfolloweddata","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"UserFollowedData","file":"shared/notification.ts","doc":"Carried by a user_followed notification, sent to the user followed.","url":"./shared/notification.ts/~/UserFollowedData.html","deprecated":false},{"id":"namespace_userfolloweddata","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"UserFollowedData.followerId","file":"shared/notification.ts","doc":"","url":"./shared/notification.ts/~/UserFollowedData.followerId.html","deprecated":false},{"id":"namespace_userfolloweddata","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"UserFollowedData.followerUsername","file":"shared/notification.ts","doc":"","url":"./shared/notification.ts/~/UserFollowedData.followerUsername.html","deprecated":false},{"id":"namespace_userdumpposteddata","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"UserDumpPostedData","file":"shared/notification.ts","doc":"Carried by a user_dump_posted notification, sent to the followers of a user who posted a public dump.","url":"./shared/notification.ts/~/UserDumpPostedData.html","deprecated":false},{"id":"namespace_userdumpposteddata","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"UserDumpPostedData.dumperId","file":"shared/notification.ts","doc":"","url":"./shared/notification.ts/~/UserDumpPostedData.dumperId.html","deprecated":false},{"id":"namespace_userdumpposteddata","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"UserDumpPostedData.dumperUsername","file":"shared/notification.ts","doc":"","url":"./shared/notification.ts/~/UserDumpPostedData.dumperUsername.html","deprecated":false},{"id":"namespace_userdumpposteddata","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"UserDumpPostedData.dumpId","file":"shared/notification.ts","doc":"","url":"./shared/notification.ts/~/UserDumpPostedData.dumpId.html","deprecated":false},{"id":"namespace_userdumpposteddata","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"UserDumpPostedData.dumpTitle","file":"shared/notification.ts","doc":"","url":"./shared/notification.ts/~/UserDumpPostedData.dumpTitle.html","deprecated":false},{"id":"namespace_playlistdumpaddeddata","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"PlaylistDumpAddedData","file":"shared/notification.ts","doc":"Carried by a playlist_dump_added notification, sent to the followers of a public playlist when a public dump is added to it.","url":"./shared/notification.ts/~/PlaylistDumpAddedData.html","deprecated":false},{"id":"namespace_playlistdumpaddeddata","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PlaylistDumpAddedData.dumpId","file":"shared/notification.ts","doc":"","url":"./shared/notification.ts/~/PlaylistDumpAddedData.dumpId.html","deprecated":false},{"id":"namespace_playlistdumpaddeddata","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PlaylistDumpAddedData.dumpTitle","file":"shared/notification.ts","doc":"","url":"./shared/notification.ts/~/PlaylistDumpAddedData.dumpTitle.html","deprecated":false},{"id":"namespace_playlistdumpaddeddata","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PlaylistDumpAddedData.playlistId","file":"shared/notification.ts","doc":"","url":"./shared/notification.ts/~/PlaylistDumpAddedData.playlistId.html","deprecated":false},{"id":"namespace_playlistdumpaddeddata","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PlaylistDumpAddedData.playlistTitle","file":"shared/notification.ts","doc":"","url":"./shared/notification.ts/~/PlaylistDumpAddedData.playlistTitle.html","deprecated":false},{"id":"namespace_dumpupvoteddata","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"DumpUpvotedData","file":"shared/notification.ts","doc":"Carried by a dump_upvoted notification, sent to the dump's poster.","url":"./shared/notification.ts/~/DumpUpvotedData.html","deprecated":false},{"id":"namespace_dumpupvoteddata","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DumpUpvotedData.voterId","file":"shared/notification.ts","doc":"","url":"./shared/notification.ts/~/DumpUpvotedData.voterId.html","deprecated":false},{"id":"namespace_dumpupvoteddata","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DumpUpvotedData.voterUsername","file":"shared/notification.ts","doc":"","url":"./shared/notification.ts/~/DumpUpvotedData.voterUsername.html","deprecated":false},{"id":"namespace_dumpupvoteddata","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DumpUpvotedData.dumpId","file":"shared/notification.ts","doc":"","url":"./shared/notification.ts/~/DumpUpvotedData.dumpId.html","deprecated":false},{"id":"namespace_dumpupvoteddata","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DumpUpvotedData.dumpTitle","file":"shared/notification.ts","doc":"","url":"./shared/notification.ts/~/DumpUpvotedData.dumpTitle.html","deprecated":false},{"id":"namespace_usermentioneddata","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"UserMentionedData","file":"shared/notification.ts","doc":"Carried by a user_mentioned notification, sent to a user @mentioned in a comment, a dump, a playlist's description or a chat message, or to every user by a chat message's @everyone. Its DumpRef is the dump's, or the comment's dump's; its PlaylistRef the playlist's.","url":"./shared/notification.ts/~/UserMentionedData.html","deprecated":false},{"id":"namespace_usermentioneddata","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"UserMentionedData.mentionerId","file":"shared/notification.ts","doc":"","url":"./shared/notification.ts/~/UserMentionedData.mentionerId.html","deprecated":false},{"id":"namespace_usermentioneddata","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"UserMentionedData.mentionerUsername","file":"shared/notification.ts","doc":"","url":"./shared/notification.ts/~/UserMentionedData.mentionerUsername.html","deprecated":false},{"id":"namespace_usermentioneddata","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"UserMentionedData.contextType","file":"shared/notification.ts","doc":"","url":"./shared/notification.ts/~/UserMentionedData.contextType.html","deprecated":false},{"id":"namespace_usermentioneddata","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"UserMentionedData.contextId","file":"shared/notification.ts","doc":"The id of the comment, dump, playlist or chat message.","url":"./shared/notification.ts/~/UserMentionedData.contextId.html","deprecated":false},{"id":"namespace_usermentioneddata","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"UserMentionedData.contextTitle","file":"shared/notification.ts","doc":"The title of the dump or playlist, or of the dump a comment is under; empty for the chat.","url":"./shared/notification.ts/~/UserMentionedData.contextTitle.html","deprecated":false},{"id":"namespace_usermentioneddata","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"UserMentionedData.dumpId","file":"shared/notification.ts","doc":"Set only for a comment. It names the dump the comment is under, which the notification's link opens.","url":"./shared/notification.ts/~/UserMentionedData.dumpId.html","deprecated":false},{"id":"namespace_usermentioneddata","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"UserMentionedData.everyone","file":"shared/notification.ts","doc":"Set when the user was reached by @everyone rather than by name. A message naming them as well notifies them once, by name.","url":"./shared/notification.ts/~/UserMentionedData.everyone.html","deprecated":false},{"id":"namespace_dumpcommenteddata","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"DumpCommentedData","file":"shared/notification.ts","doc":"Carried by a dump_commented notification, sent to the dump's poster.","url":"./shared/notification.ts/~/DumpCommentedData.html","deprecated":false},{"id":"namespace_dumpcommenteddata","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DumpCommentedData.commenterId","file":"shared/notification.ts","doc":"","url":"./shared/notification.ts/~/DumpCommentedData.commenterId.html","deprecated":false},{"id":"namespace_dumpcommenteddata","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DumpCommentedData.commenterUsername","file":"shared/notification.ts","doc":"","url":"./shared/notification.ts/~/DumpCommentedData.commenterUsername.html","deprecated":false},{"id":"namespace_dumpcommenteddata","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DumpCommentedData.commentId","file":"shared/notification.ts","doc":"","url":"./shared/notification.ts/~/DumpCommentedData.commentId.html","deprecated":false},{"id":"namespace_dumpcommenteddata","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DumpCommentedData.dumpId","file":"shared/notification.ts","doc":"","url":"./shared/notification.ts/~/DumpCommentedData.dumpId.html","deprecated":false},{"id":"namespace_dumpcommenteddata","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DumpCommentedData.dumpTitle","file":"shared/notification.ts","doc":"","url":"./shared/notification.ts/~/DumpCommentedData.dumpTitle.html","deprecated":false},{"id":"namespace_commentlikeddata","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"CommentLikedData","file":"shared/notification.ts","doc":"Carried by a comment_liked notification, sent to the comment's author.","url":"./shared/notification.ts/~/CommentLikedData.html","deprecated":false},{"id":"namespace_commentlikeddata","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommentLikedData.likerId","file":"shared/notification.ts","doc":"","url":"./shared/notification.ts/~/CommentLikedData.likerId.html","deprecated":false},{"id":"namespace_commentlikeddata","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommentLikedData.likerUsername","file":"shared/notification.ts","doc":"","url":"./shared/notification.ts/~/CommentLikedData.likerUsername.html","deprecated":false},{"id":"namespace_commentlikeddata","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommentLikedData.commentId","file":"shared/notification.ts","doc":"","url":"./shared/notification.ts/~/CommentLikedData.commentId.html","deprecated":false},{"id":"namespace_commentlikeddata","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommentLikedData.dumpId","file":"shared/notification.ts","doc":"","url":"./shared/notification.ts/~/CommentLikedData.dumpId.html","deprecated":false},{"id":"namespace_commentlikeddata","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommentLikedData.dumpTitle","file":"shared/notification.ts","doc":"","url":"./shared/notification.ts/~/CommentLikedData.dumpTitle.html","deprecated":false},{"id":"namespace_notificationdata","kind":[{"char":"T","kind":"TypeAlias","title":"Type Alias"}],"name":"NotificationData","file":"shared/notification.ts","doc":"Stored when the notification is made, so a title changed later still shows the old one. The …Username fields and the refs are joined when it is sent, so they follow a rename. The notification's type says which member it is.","url":"./shared/notification.ts/~/NotificationData.html","deprecated":false},{"id":"namespace_notification","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"Notification","file":"shared/notification.ts","doc":"Pushed to its user's sockets in a notification_created message when it is made, and returned by GET /api/me/notifications.","url":"./shared/notification.ts/~/Notification.html","deprecated":false},{"id":"namespace_notification","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Notification.id","file":"shared/notification.ts","doc":"","url":"./shared/notification.ts/~/Notification.id.html","deprecated":false},{"id":"namespace_notification","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Notification.userId","file":"shared/notification.ts","doc":"","url":"./shared/notification.ts/~/Notification.userId.html","deprecated":false},{"id":"namespace_notification","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Notification.type","file":"shared/notification.ts","doc":"","url":"./shared/notification.ts/~/Notification.type.html","deprecated":false},{"id":"namespace_notification","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Notification.data","file":"shared/notification.ts","doc":"","url":"./shared/notification.ts/~/Notification.data.html","deprecated":false},{"id":"namespace_notification","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Notification.read","file":"shared/notification.ts","doc":"","url":"./shared/notification.ts/~/Notification.read.html","deprecated":false},{"id":"namespace_notification","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Notification.createdAt","file":"shared/notification.ts","doc":"","url":"./shared/notification.ts/~/Notification.createdAt.html","deprecated":false},{"id":"namespace_feed_tabs","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"FEED_TABS","file":"shared/paths.ts","doc":"The feed tabs, in the tab bar's order. Each is a path segment: /hot for every dump, /music/hot for a category. They are reserved at the root, so no category can take one.","url":"./shared/paths.ts/~/FEED_TABS.html","deprecated":false},{"id":"namespace_feedtab","kind":[{"char":"T","kind":"TypeAlias","title":"Type Alias"}],"name":"FeedTab","file":"shared/paths.ts","doc":"One of the FEED_TABS.","url":"./shared/paths.ts/~/FeedTab.html","deprecated":false},{"id":"namespace_profile_tabs","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"PROFILE_TABS","file":"shared/paths.ts","doc":"The tabs of a profile, each a segment after /@name. The bare /@name is the overview.","url":"./shared/paths.ts/~/PROFILE_TABS.html","deprecated":false},{"id":"namespace_profiletab","kind":[{"char":"T","kind":"TypeAlias","title":"Type Alias"}],"name":"ProfileTab","file":"shared/paths.ts","doc":"One of the PROFILE_TABS.","url":"./shared/paths.ts/~/ProfileTab.html","deprecated":false},{"id":"namespace_follow_views","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"FOLLOW_VIEWS","file":"shared/paths.ts","doc":"The views of a follow tab, of what is followed: the users, at the bare tab, or the playlists. A profile's lists them, /@name/follow and /@name/follow/playlists, and a feed's shows their dumps, /follow and /follow/playlists.","url":"./shared/paths.ts/~/FOLLOW_VIEWS.html","deprecated":false},{"id":"namespace_followview","kind":[{"char":"T","kind":"TypeAlias","title":"Type Alias"}],"name":"FollowView","file":"shared/paths.ts","doc":"One of the FOLLOW_VIEWS.","url":"./shared/paths.ts/~/FollowView.html","deprecated":false},{"id":"namespace_search_tabs","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"SEARCH_TABS","file":"shared/paths.ts","doc":"The tabs of the search page: the dumps at /search, the others at /search/.","url":"./shared/paths.ts/~/SEARCH_TABS.html","deprecated":false},{"id":"namespace_searchtab","kind":[{"char":"T","kind":"TypeAlias","title":"Type Alias"}],"name":"SearchTab","file":"shared/paths.ts","doc":"One of the SEARCH_TABS.","url":"./shared/paths.ts/~/SearchTab.html","deprecated":false},{"id":"namespace_playlists_tabs","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"PLAYLISTS_TABS","file":"shared/paths.ts","doc":"The tabs of the playlists page, in the tab bar's order: each order of every public playlist, ?sort=, then the viewer's own playlists, ?mine=1, which only a signed-in user is offered.","url":"./shared/paths.ts/~/PLAYLISTS_TABS.html","deprecated":false},{"id":"namespace_playliststab","kind":[{"char":"T","kind":"TypeAlias","title":"Type Alias"}],"name":"PlaylistsTab","file":"shared/paths.ts","doc":"One of the PLAYLISTS_TABS.","url":"./shared/paths.ts/~/PlaylistsTab.html","deprecated":false},{"id":"namespace_community_views","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"COMMUNITY_VIEWS","file":"shared/paths.ts","doc":"The views of the community page, one per digest cadence: the week at /community, the month at /community/monthly.","url":"./shared/paths.ts/~/COMMUNITY_VIEWS.html","deprecated":false},{"id":"namespace_owneditem","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"OwnedItem","file":"shared/paths.ts","doc":"Passed to dumpPath and playlistPath, usually as the item.","url":"./shared/paths.ts/~/OwnedItem.html","deprecated":false},{"id":"namespace_owneditem","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"OwnedItem.ownerUsername","file":"shared/paths.ts","doc":"","url":"./shared/paths.ts/~/OwnedItem.ownerUsername.html","deprecated":false},{"id":"namespace_owneditem","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"OwnedItem.slug","file":"shared/paths.ts","doc":"","url":"./shared/paths.ts/~/OwnedItem.slug.html","deprecated":false},{"id":"namespace_userpath","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"userPath","file":"shared/paths.ts","doc":"Returns the path of username's profile, of one of its tabs, or of a view of the follow tab. The default view, users, is the bare tab.","url":"./shared/paths.ts/~/userPath.html","deprecated":false},{"id":"namespace_dumppath","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"dumpPath","file":"shared/paths.ts","doc":"Returns the path of a dump's page, /@owner/dumps/, or of its editor, one segment more.","url":"./shared/paths.ts/~/dumpPath.html","deprecated":false},{"id":"namespace_playlistpath","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"playlistPath","file":"shared/paths.ts","doc":"Returns the path of a playlist's page, /@owner/playlists/, or of the page with its editor open, one segment more.","url":"./shared/paths.ts/~/playlistPath.html","deprecated":false},{"id":"namespace_feedpath","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"feedPath","file":"shared/paths.ts","doc":"Returns the path of a feed: every dump's at the root, or a category's at /, on tab, or on the viewer's default tab without one. The follow tab takes a view, the users followed by default.","url":"./shared/paths.ts/~/feedPath.html","deprecated":false},{"id":"namespace_playlistspath","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"playlistsPath","file":"shared/paths.ts","doc":"Returns the path of the page of every public playlist, /playlists, or of a playlist category's at /playlists/, on the tab tab names: an order, the default one without it, or the viewer's own playlists.","url":"./shared/paths.ts/~/playlistsPath.html","deprecated":false},{"id":"namespace_parseplayliststab","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"parsePlaylistsTab","file":"shared/paths.ts","doc":"Returns the tab of the playlists page its query names: the viewer's own playlists with a mine, else the order sort names, as parsePlaylistSort reads it.","url":"./shared/paths.ts/~/parsePlaylistsTab.html","deprecated":false},{"id":"namespace_playlistsortquery","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"playlistSortQuery","file":"shared/paths.ts","doc":"Returns the query string that puts a list of playlists in the order sort names, with its ?, or \"\" for the default order. extra holds the list's other parameters, such as a profile's category.","url":"./shared/paths.ts/~/playlistSortQuery.html","deprecated":false},{"id":"namespace_categorypath","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"categoryPath","file":"shared/paths.ts","doc":"Returns the path of the page of the category of kind at slug: a dump category's feed (feedPath), or a playlist category's playlists (playlistsPath). The category chips link to it.","url":"./shared/paths.ts/~/categoryPath.html","deprecated":false},{"id":"namespace_searchpath","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"searchPath","file":"shared/paths.ts","doc":"Returns the path of the search page on tab, searching query when it is given.","url":"./shared/paths.ts/~/searchPath.html","deprecated":false},{"id":"namespace_communitypath","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"communityPath","file":"shared/paths.ts","doc":"Returns the path of the community page on view, the week by default.","url":"./shared/paths.ts/~/communityPath.html","deprecated":false},{"id":"namespace_pagepath","kind":[{"char":"T","kind":"TypeAlias","title":"Type Alias"}],"name":"PagePath","file":"shared/paths.ts","doc":"Returned by parsePagePath for a path under a user. rest holds the segments after /@name, a profile tab and its view.","url":"./shared/paths.ts/~/PagePath.html","deprecated":false},{"id":"namespace_parsepagepath","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"parsePagePath","file":"shared/paths.ts","doc":"Returns what a page path under a user names: a profile (with its tab), a dump or a playlist (or its editor). It returns null for any other path, a feed or an app page, and for one under a user that no page answers. The names are decoded but not looked up, so the user or the item may not exist.","url":"./shared/paths.ts/~/parsePagePath.html","deprecated":false},{"id":"namespace_permission","kind":[{"char":"T","kind":"TypeAlias","title":"Type Alias"}],"name":"Permission","file":"shared/permissions.ts","doc":"An action only some roles may take. A new one goes in this union and in ALL_PERMISSIONS, which is what grants it to admins.","url":"./shared/permissions.ts/~/Permission.html","deprecated":false},{"id":"namespace_role_permissions","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"ROLE_PERMISSIONS","file":"shared/permissions.ts","doc":"Read through hasPermission. Roles are fixed in code. An admin holds every permission, and a moderator the moderation ones and @everyone in the chat.","url":"./shared/permissions.ts/~/ROLE_PERMISSIONS.html","deprecated":false},{"id":"namespace_haspermission","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"hasPermission","file":"shared/permissions.ts","doc":"Checks whether role grants permission. The server's can and the client's can both wrap it.","url":"./shared/permissions.ts/~/hasPermission.html","deprecated":false},{"id":"namespace_tralbumtrack","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"TralbumTrack","file":"shared/player.ts","doc":"Listed by a Tralbum, in the release's order.","url":"./shared/player.ts/~/TralbumTrack.html","deprecated":false},{"id":"namespace_tralbumtrack","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"TralbumTrack.index","file":"shared/player.ts","doc":"The track's position in the release's list. The player keeps it, with the page URL, to resolve the track again once its stream URL expires.","url":"./shared/player.ts/~/TralbumTrack.index.html","deprecated":false},{"id":"namespace_tralbumtrack","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"TralbumTrack.trackNum","file":"shared/player.ts","doc":"","url":"./shared/player.ts/~/TralbumTrack.trackNum.html","deprecated":false},{"id":"namespace_tralbumtrack","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"TralbumTrack.title","file":"shared/player.ts","doc":"","url":"./shared/player.ts/~/TralbumTrack.title.html","deprecated":false},{"id":"namespace_tralbumtrack","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"TralbumTrack.duration","file":"shared/player.ts","doc":"In seconds, with a fraction.","url":"./shared/player.ts/~/TralbumTrack.duration.html","deprecated":false},{"id":"namespace_tralbumtrack","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"TralbumTrack.streamUrl","file":"shared/player.ts","doc":"A signed URL that expires. Null when the track can't be played.","url":"./shared/player.ts/~/TralbumTrack.streamUrl.html","deprecated":false},{"id":"namespace_tralbumtrack","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"TralbumTrack.streamable","file":"shared/player.ts","doc":"False for preorder, unreleased and still-encoding tracks. They stay in the list so that the numbering matches the release, but the player skips them.","url":"./shared/player.ts/~/TralbumTrack.streamable.html","deprecated":false},{"id":"namespace_tralbumtrack","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"TralbumTrack.capped","file":"shared/player.ts","doc":"Set when Bandcamp capped its free plays, so it may serve only a clip.","url":"./shared/player.ts/~/TralbumTrack.capped.html","deprecated":false},{"id":"namespace_tralbum","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"Tralbum","file":"shared/player.ts","doc":"Returned by GET /api/remote/bandcamp for a Bandcamp album or track page, when the native player plays it.","url":"./shared/player.ts/~/Tralbum.html","deprecated":false},{"id":"namespace_tralbum","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Tralbum.sourceUrl","file":"shared/player.ts","doc":"","url":"./shared/player.ts/~/Tralbum.sourceUrl.html","deprecated":false},{"id":"namespace_tralbum","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Tralbum.itemType","file":"shared/player.ts","doc":"","url":"./shared/player.ts/~/Tralbum.itemType.html","deprecated":false},{"id":"namespace_tralbum","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Tralbum.title","file":"shared/player.ts","doc":"","url":"./shared/player.ts/~/Tralbum.title.html","deprecated":false},{"id":"namespace_tralbum","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Tralbum.artist","file":"shared/player.ts","doc":"","url":"./shared/player.ts/~/Tralbum.artist.html","deprecated":false},{"id":"namespace_tralbum","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Tralbum.artworkUrl","file":"shared/player.ts","doc":"","url":"./shared/player.ts/~/Tralbum.artworkUrl.html","deprecated":false},{"id":"namespace_tralbum","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Tralbum.tracks","file":"shared/player.ts","doc":"","url":"./shared/player.ts/~/Tralbum.tracks.html","deprecated":false},{"id":"namespace_tralbum","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Tralbum.resolvedAt","file":"shared/player.ts","doc":"When the stream URLs were fetched, in epoch ms. The player resolves the page again once they are old enough to have expired.","url":"./shared/player.ts/~/Tralbum.resolvedAt.html","deprecated":false},{"id":"namespace_youtubeplaylisttrack","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"YouTubePlaylistTrack","file":"shared/player.ts","doc":"Listed by a YouTubePlaylist, in the playlist's order.","url":"./shared/player.ts/~/YouTubePlaylistTrack.html","deprecated":false},{"id":"namespace_youtubeplaylisttrack","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"YouTubePlaylistTrack.videoId","file":"shared/player.ts","doc":"","url":"./shared/player.ts/~/YouTubePlaylistTrack.videoId.html","deprecated":false},{"id":"namespace_youtubeplaylisttrack","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"YouTubePlaylistTrack.title","file":"shared/player.ts","doc":"","url":"./shared/player.ts/~/YouTubePlaylistTrack.title.html","deprecated":false},{"id":"namespace_youtubeplaylisttrack","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"YouTubePlaylistTrack.duration","file":"shared/player.ts","doc":"In seconds.","url":"./shared/player.ts/~/YouTubePlaylistTrack.duration.html","deprecated":false},{"id":"namespace_youtubeplaylist","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"YouTubePlaylist","file":"shared/player.ts","doc":"Returned by GET /api/remote/youtube to the player, which shows the titles and lengths of a playlist embed's videos, since the embed exposes neither.","url":"./shared/player.ts/~/YouTubePlaylist.html","deprecated":false},{"id":"namespace_youtubeplaylist","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"YouTubePlaylist.listId","file":"shared/player.ts","doc":"","url":"./shared/player.ts/~/YouTubePlaylist.listId.html","deprecated":false},{"id":"namespace_youtubeplaylist","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"YouTubePlaylist.title","file":"shared/player.ts","doc":"","url":"./shared/player.ts/~/YouTubePlaylist.title.html","deprecated":false},{"id":"namespace_youtubeplaylist","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"YouTubePlaylist.tracks","file":"shared/player.ts","doc":"","url":"./shared/player.ts/~/YouTubePlaylist.tracks.html","deprecated":false},{"id":"namespace_playlist_sorts","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"PLAYLIST_SORTS","file":"shared/playlist.ts","doc":"The orders a list of playlists comes in, the first being the default one: updated, by playlistActivity, the latest first; new, by creation, the newest first; dumps, the fullest first. GET /api/playlists and GET /api/users/:key/playlists take one as ?sort=, the /playlists page and a profile's playlists tab show them as tabs and keep the one picked in their URL's ?sort=.","url":"./shared/playlist.ts/~/PLAYLIST_SORTS.html","deprecated":false},{"id":"namespace_playlistsort","kind":[{"char":"T","kind":"TypeAlias","title":"Type Alias"}],"name":"PlaylistSort","file":"shared/playlist.ts","doc":"One of the PLAYLIST_SORTS.","url":"./shared/playlist.ts/~/PlaylistSort.html","deprecated":false},{"id":"namespace_parseplaylistsort","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"parsePlaylistSort","file":"shared/playlist.ts","doc":"Returns the order a ?sort= names, the default one when it is missing or names none: like a page number, an order never fails a list.","url":"./shared/playlist.ts/~/parsePlaylistSort.html","deprecated":false},{"id":"namespace_playlist","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"Playlist","file":"shared/playlist.ts","doc":"Returned by the playlist routes, and by the search, users and dumps routes that list playlists. The playlist_created and playlist_updated WebSocket messages carry it too.","url":"./shared/playlist.ts/~/Playlist.html","deprecated":false},{"id":"namespace_playlist","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Playlist.id","file":"shared/playlist.ts","doc":"","url":"./shared/playlist.ts/~/Playlist.id.html","deprecated":false},{"id":"namespace_playlist","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Playlist.userId","file":"shared/playlist.ts","doc":"","url":"./shared/playlist.ts/~/Playlist.userId.html","deprecated":false},{"id":"namespace_playlist","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Playlist.title","file":"shared/playlist.ts","doc":"","url":"./shared/playlist.ts/~/Playlist.title.html","deprecated":false},{"id":"namespace_playlist","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Playlist.slug","file":"shared/playlist.ts","doc":"Names the playlist in its page's path, playlistPath (shared/paths.ts) building it with ownerUsername. Made from the title on creation, it changes only when edited, and is unique among its owner's playlists.","url":"./shared/playlist.ts/~/Playlist.slug.html","deprecated":false},{"id":"namespace_playlist","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Playlist.description","file":"shared/playlist.ts","doc":"It is written in Markdown.","url":"./shared/playlist.ts/~/Playlist.description.html","deprecated":false},{"id":"namespace_playlist","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Playlist.isPublic","file":"shared/playlist.ts","doc":"Only its owner sees a private playlist. Moderators don't, though they may still edit or delete it.","url":"./shared/playlist.ts/~/Playlist.isPublic.html","deprecated":false},{"id":"namespace_playlist","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Playlist.createdAt","file":"shared/playlist.ts","doc":"","url":"./shared/playlist.ts/~/Playlist.createdAt.html","deprecated":false},{"id":"namespace_playlist","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Playlist.updatedAt","file":"shared/playlist.ts","doc":"playlistImageUrl puts it on the cover's URL, so a new cover isn't hidden by the cached old one.","url":"./shared/playlist.ts/~/Playlist.updatedAt.html","deprecated":false},{"id":"namespace_playlist","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Playlist.imageMime","file":"shared/playlist.ts","doc":"It is undefined when the playlist has no cover.","url":"./shared/playlist.ts/~/Playlist.imageMime.html","deprecated":false},{"id":"namespace_playlist","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Playlist.dumpCount","file":"shared/playlist.ts","doc":"It counts the dumps the viewer may see in it, as its page lists them. It is undefined when the query didn't count them.","url":"./shared/playlist.ts/~/Playlist.dumpCount.html","deprecated":false},{"id":"namespace_playlist","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Playlist.lastDumpAt","file":"shared/playlist.ts","doc":"When the latest of the dumps the viewer may see was added to it, which playlistActivity reads. It is undefined when it holds none, or when the query didn't count them.","url":"./shared/playlist.ts/~/Playlist.lastDumpAt.html","deprecated":false},{"id":"namespace_playlist","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Playlist.ownerUsername","file":"shared/playlist.ts","doc":"The owner's current name, which the playlist's path starts with.","url":"./shared/playlist.ts/~/Playlist.ownerUsername.html","deprecated":false},{"id":"namespace_playlist","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Playlist.categoryIds","file":"shared/playlist.ts","doc":"The ids of the playlist categories it is filed under. The services fill them in on every playlist they return.","url":"./shared/playlist.ts/~/Playlist.categoryIds.html","deprecated":false},{"id":"namespace_playlistactivity","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"playlistActivity","file":"shared/playlist.ts","doc":"Returns when playlist last took a dump, or was created if it holds none: what the updated order sorts by and the cards show. Its title, cover and description may change after without bringing it back up a list.","url":"./shared/playlist.ts/~/playlistActivity.html","deprecated":false},{"id":"namespace_compareplaylists","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"comparePlaylists","file":"shared/playlist.ts","doc":"Returns the comparison that puts playlists in the order sort names, as the API pages them, the newer first on a tie. usePlaylistListSync finds with it where a playlist the socket announces goes in a list.","url":"./shared/playlist.ts/~/comparePlaylists.html","deprecated":false},{"id":"namespace_playlistwithdumps","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"PlaylistWithDumps","file":"shared/playlist.ts","doc":"Returned by GET /api/users/:key/playlists/:slug to PlaylistDetail, and by GET /api/playlists/:playlistId, with the dumps the caller may see, in the playlist's order.","url":"./shared/playlist.ts/~/PlaylistWithDumps.html","deprecated":false},{"id":"namespace_playlistwithdumps","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PlaylistWithDumps.dumps","file":"shared/playlist.ts","doc":"","url":"./shared/playlist.ts/~/PlaylistWithDumps.dumps.html","deprecated":false},{"id":"namespace_playlistmembership","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"PlaylistMembership","file":"shared/playlist.ts","doc":"Returned by GET /api/me/playlists?contains=:dumpId, one per playlist of the caller's. PlaylistMembershipPanel ticks the playlists with hasDump, in the add-to-playlist modal and the dump form.","url":"./shared/playlist.ts/~/PlaylistMembership.html","deprecated":false},{"id":"namespace_playlistmembership","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PlaylistMembership.playlist","file":"shared/playlist.ts","doc":"","url":"./shared/playlist.ts/~/PlaylistMembership.playlist.html","deprecated":false},{"id":"namespace_playlistmembership","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PlaylistMembership.hasDump","file":"shared/playlist.ts","doc":"","url":"./shared/playlist.ts/~/PlaylistMembership.hasDump.html","deprecated":false},{"id":"namespace_createplaylistrequest","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"CreatePlaylistRequest","file":"shared/playlist.ts","doc":"Passed to POST /api/playlists by PlaylistCreateForm.","url":"./shared/playlist.ts/~/CreatePlaylistRequest.html","deprecated":false},{"id":"namespace_createplaylistrequest","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CreatePlaylistRequest.title","file":"shared/playlist.ts","doc":"","url":"./shared/playlist.ts/~/CreatePlaylistRequest.title.html","deprecated":false},{"id":"namespace_createplaylistrequest","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CreatePlaylistRequest.description","file":"shared/playlist.ts","doc":"","url":"./shared/playlist.ts/~/CreatePlaylistRequest.description.html","deprecated":false},{"id":"namespace_createplaylistrequest","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CreatePlaylistRequest.isPublic","file":"shared/playlist.ts","doc":"","url":"./shared/playlist.ts/~/CreatePlaylistRequest.isPublic.html","deprecated":false},{"id":"namespace_createplaylistrequest","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CreatePlaylistRequest.categoryIds","file":"shared/playlist.ts","doc":"The playlist categories to file it under, none when left out.","url":"./shared/playlist.ts/~/CreatePlaylistRequest.categoryIds.html","deprecated":false},{"id":"namespace_updateplaylistrequest","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"UpdatePlaylistRequest","file":"shared/playlist.ts","doc":"Passed to PUT /api/playlists/:playlistId by PlaylistDetail. A field left out keeps its value.","url":"./shared/playlist.ts/~/UpdatePlaylistRequest.html","deprecated":false},{"id":"namespace_updateplaylistrequest","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"UpdatePlaylistRequest.title","file":"shared/playlist.ts","doc":"","url":"./shared/playlist.ts/~/UpdatePlaylistRequest.title.html","deprecated":false},{"id":"namespace_updateplaylistrequest","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"UpdatePlaylistRequest.slug","file":"shared/playlist.ts","doc":"A new slug, which the edit form's slug field sends. A title change never changes the slug by itself.","url":"./shared/playlist.ts/~/UpdatePlaylistRequest.slug.html","deprecated":false},{"id":"namespace_updateplaylistrequest","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"UpdatePlaylistRequest.description","file":"shared/playlist.ts","doc":"null removes the description.","url":"./shared/playlist.ts/~/UpdatePlaylistRequest.description.html","deprecated":false},{"id":"namespace_updateplaylistrequest","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"UpdatePlaylistRequest.isPublic","file":"shared/playlist.ts","doc":"","url":"./shared/playlist.ts/~/UpdatePlaylistRequest.isPublic.html","deprecated":false},{"id":"namespace_updateplaylistrequest","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"UpdatePlaylistRequest.categoryIds","file":"shared/playlist.ts","doc":"Replaces its playlist categories; [] takes it out of every one.","url":"./shared/playlist.ts/~/UpdatePlaylistRequest.categoryIds.html","deprecated":false},{"id":"namespace_reorderplaylistrequest","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"ReorderPlaylistRequest","file":"shared/playlist.ts","doc":"Passed to PUT /api/playlists/:playlistId/order by PlaylistDetail, after a drag or to put back a dump whose removal was undone.","url":"./shared/playlist.ts/~/ReorderPlaylistRequest.html","deprecated":false},{"id":"namespace_reorderplaylistrequest","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ReorderPlaylistRequest.dumpIds","file":"shared/playlist.ts","doc":"Every dump of the playlist the caller can see, in the new order. The dumps hidden from them keep their slots.","url":"./shared/playlist.ts/~/ReorderPlaylistRequest.dumpIds.html","deprecated":false},{"id":"namespace_searchresults","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"SearchResults","file":"shared/search.ts","doc":"Returned by GET /api/search to the Search page. Only the dumps are paged, and each page brings the users and playlists again.","url":"./shared/search.ts/~/SearchResults.html","deprecated":false},{"id":"namespace_searchresults","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"SearchResults.dumps","file":"shared/search.ts","doc":"It always has its total, which the page shows in the dumps tab's label.","url":"./shared/search.ts/~/SearchResults.dumps.html","deprecated":false},{"id":"namespace_searchresults","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"SearchResults.users","file":"shared/search.ts","doc":"There are 20 at most.","url":"./shared/search.ts/~/SearchResults.users.html","deprecated":false},{"id":"namespace_searchresults","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"SearchResults.playlists","file":"shared/search.ts","doc":"There are 20 at most.","url":"./shared/search.ts/~/SearchResults.playlists.html","deprecated":false},{"id":"namespace_usersettings","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"UserSettings","file":"shared/settings.ts","doc":"Returned by GET /api/me/settings, and by a PATCH once applied. The client's useSettings reads it from the session.","url":"./shared/settings.ts/~/UserSettings.html","deprecated":false},{"id":"namespace_usersettings","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"UserSettings.style","file":"shared/settings.ts","doc":"Null until the user picks one, so the instance's default style (GERBEUR_DEFAULT_STYLE) applies, and so a browser's earlier choice can be carried over on first sign-in.","url":"./shared/settings.ts/~/UserSettings.style.html","deprecated":false},{"id":"namespace_usersettings","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"UserSettings.colorScheme","file":"shared/settings.ts","doc":"Null until the user picks one, which reads as \"auto\".","url":"./shared/settings.ts/~/UserSettings.colorScheme.html","deprecated":false},{"id":"namespace_usersettings","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"UserSettings.digestWeekly","file":"shared/settings.ts","doc":"Whether the weekly digest is sent.","url":"./shared/settings.ts/~/UserSettings.digestWeekly.html","deprecated":false},{"id":"namespace_usersettings","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"UserSettings.digestMonthly","file":"shared/settings.ts","doc":"Whether the monthly recap is sent.","url":"./shared/settings.ts/~/UserSettings.digestMonthly.html","deprecated":false},{"id":"namespace_updatesettingsrequest","kind":[{"char":"T","kind":"TypeAlias","title":"Type Alias"}],"name":"UpdateSettingsRequest","file":"shared/settings.ts","doc":"Sent to PATCH /api/me/settings with the settings to change; the others keep their value.","url":"./shared/settings.ts/~/UpdateSettingsRequest.html","deprecated":false},{"id":"namespace_default_settings","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"DEFAULT_SETTINGS","file":"shared/settings.ts","doc":"The settings of a user who never changed any. Digests are on by default.","url":"./shared/settings.ts/~/DEFAULT_SETTINGS.html","deprecated":false},{"id":"namespace_digest_cadences","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"DIGEST_CADENCES","file":"shared/settings.ts","doc":"Lists how often a digest can come: weekly, or monthly as a recap.","url":"./shared/settings.ts/~/DIGEST_CADENCES.html","deprecated":false},{"id":"namespace_digestcadence","kind":[{"char":"T","kind":"TypeAlias","title":"Type Alias"}],"name":"DigestCadence","file":"shared/settings.ts","doc":"One of the DIGEST_CADENCES. An unsubscribe link names one, which turns off its setting alone.","url":"./shared/settings.ts/~/DigestCadence.html","deprecated":false},{"id":"namespace_period_ms","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"PERIOD_MS","file":"shared/settings.ts","doc":"How long each cadence's period lasts, rolling: a digest covers the one just ended, and the /community page the one ending now.","url":"./shared/settings.ts/~/PERIOD_MS.html","deprecated":false},{"id":"namespace_isdigestcadence","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"isDigestCadence","file":"shared/settings.ts","doc":"Checks whether value is a DigestCadence.","url":"./shared/settings.ts/~/isDigestCadence.html","deprecated":false},{"id":"namespace_digest_setting","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"DIGEST_SETTING","file":"shared/settings.ts","doc":"Names the setting that switches each cadence of digest.","url":"./shared/settings.ts/~/DIGEST_SETTING.html","deprecated":false},{"id":"namespace_slug_max","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"SLUG_MAX","file":"shared/slug.ts","doc":"The longest a dump's or a playlist's slug may be.","url":"./shared/slug.ts/~/SLUG_MAX.html","deprecated":false},{"id":"namespace_slug_re","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"SLUG_RE","file":"shared/slug.ts","doc":"Matches a well-formed slug: lowercase letters and digits, in words joined by single hyphens. Categories, dumps and playlists share it.","url":"./shared/slug.ts/~/SLUG_RE.html","deprecated":false},{"id":"namespace_isvalidslug","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"isValidSlug","file":"shared/slug.ts","doc":"Checks whether slug matches SLUG_RE and is at most max characters long.","url":"./shared/slug.ts/~/isValidSlug.html","deprecated":false},{"id":"namespace_slugify","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"slugify","file":"shared/slug.ts","doc":"Turns title into lowercase ASCII words joined by hyphens, at most max characters long, cut at a hyphen when it must be cut. Accents are dropped, and a title with no ASCII letter or digit gives untitled. The result always passes isValidSlug.","url":"./shared/slug.ts/~/slugify.html","deprecated":false},{"id":"namespace_style_names","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"STYLE_NAMES","file":"shared/theme.ts","doc":"Lists every site style. Each has a stylesheet under src/themes/, keyed on the root element's data-style, and an email style in api/mail/styles.ts read from that stylesheet.","url":"./shared/theme.ts/~/STYLE_NAMES.html","deprecated":false},{"id":"namespace_stylename","kind":[{"char":"T","kind":"TypeAlias","title":"Type Alias"}],"name":"StyleName","file":"shared/theme.ts","doc":"One of the STYLE_NAMES.","url":"./shared/theme.ts/~/StyleName.html","deprecated":false},{"id":"namespace_base_style","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"BASE_STYLE","file":"shared/theme.ts","doc":"The style the stylesheets draw when the root element has no data-style, and the one an unset or unknown GERBEUR_DEFAULT_STYLE means.","url":"./shared/theme.ts/~/BASE_STYLE.html","deprecated":false},{"id":"namespace_color_schemes","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"COLOR_SCHEMES","file":"shared/theme.ts","doc":"Lists every color scheme. \"auto\" follows the system's.","url":"./shared/theme.ts/~/COLOR_SCHEMES.html","deprecated":false},{"id":"namespace_colorscheme","kind":[{"char":"T","kind":"TypeAlias","title":"Type Alias"}],"name":"ColorScheme","file":"shared/theme.ts","doc":"One of the COLOR_SCHEMES.","url":"./shared/theme.ts/~/ColorScheme.html","deprecated":false},{"id":"namespace_default_color_scheme","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"DEFAULT_COLOR_SCHEME","file":"shared/theme.ts","doc":"The scheme of whoever hasn't picked one: the system's.","url":"./shared/theme.ts/~/DEFAULT_COLOR_SCHEME.html","deprecated":false},{"id":"namespace_isstylename","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"isStyleName","file":"shared/theme.ts","doc":"Checks whether value is a StyleName, as a stored choice or an environment variable must be before it is applied.","url":"./shared/theme.ts/~/isStyleName.html","deprecated":false},{"id":"namespace_iscolorscheme","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"isColorScheme","file":"shared/theme.ts","doc":"Checks whether value is a ColorScheme.","url":"./shared/theme.ts/~/isColorScheme.html","deprecated":false},{"id":"namespace_sitehostof","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"siteHostOf","file":"shared/url.ts","doc":"Returns url's host without a leading www.; URL has already lowered its case. www.youtube.com and youtube.com give youtube.com.","url":"./shared/url.ts/~/siteHostOf.html","deprecated":false},{"id":"namespace_sitehost","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"siteHost","file":"shared/url.ts","doc":"Returns siteHostOf the URL raw, or undefined when raw isn't one.","url":"./shared/url.ts/~/siteHost.html","deprecated":false},{"id":"namespace_role","kind":[{"char":"T","kind":"TypeAlias","title":"Type Alias"}],"name":"Role","file":"shared/user.ts","doc":"Sets what a user may do beyond the basics, through ROLE_PERMISSIONS (shared/permissions.ts). An admin changes it with PATCH /api/users/:key/role.","url":"./shared/user.ts/~/Role.html","deprecated":false},{"id":"namespace_roles","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"ROLES","file":"shared/user.ts","doc":"Every Role, least to most privileged.","url":"./shared/user.ts/~/ROLES.html","deprecated":false},{"id":"namespace_isrole","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"isRole","file":"shared/user.ts","doc":"Checks whether value is a Role, as the role endpoint and the row guards must before trusting one.","url":"./shared/user.ts/~/isRole.html","deprecated":false},{"id":"namespace_publicuser","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"PublicUser","file":"shared/user.ts","doc":"Returned by every endpoint that shows a user to others: profiles, the users one follows, search results, and the user_updated socket message. The server makes it with toPublicUser, which drops the email.","url":"./shared/user.ts/~/PublicUser.html","deprecated":false},{"id":"namespace_publicuser","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PublicUser.id","file":"shared/user.ts","doc":"","url":"./shared/user.ts/~/PublicUser.id.html","deprecated":false},{"id":"namespace_publicuser","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PublicUser.username","file":"shared/user.ts","doc":"Picked at sign-up, and changeable since, a former name staying an alias of the user for good. Pages write it as @name (userPath).","url":"./shared/user.ts/~/PublicUser.username.html","deprecated":false},{"id":"namespace_publicuser","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PublicUser.role","file":"shared/user.ts","doc":"","url":"./shared/user.ts/~/PublicUser.role.html","deprecated":false},{"id":"namespace_publicuser","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PublicUser.createdAt","file":"shared/user.ts","doc":"","url":"./shared/user.ts/~/PublicUser.createdAt.html","deprecated":false},{"id":"namespace_publicuser","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PublicUser.updatedAt","file":"shared/user.ts","doc":"Bumped by any profile or avatar change. The client uses it to reload the avatar.","url":"./shared/user.ts/~/PublicUser.updatedAt.html","deprecated":false},{"id":"namespace_publicuser","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PublicUser.avatarMime","file":"shared/user.ts","doc":"Undefined without an avatar.","url":"./shared/user.ts/~/PublicUser.avatarMime.html","deprecated":false},{"id":"namespace_publicuser","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PublicUser.description","file":"shared/user.ts","doc":"Markdown.","url":"./shared/user.ts/~/PublicUser.description.html","deprecated":false},{"id":"namespace_publicuser","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PublicUser.invitedByUsername","file":"shared/user.ts","doc":"","url":"./shared/user.ts/~/PublicUser.invitedByUsername.html","deprecated":false},{"id":"namespace_selfuser","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"SelfUser","file":"shared/user.ts","doc":"Returned to a user about themselves: by sign-up and sign-in in AuthResponse, by GET /api/me, and by an avatar upload.","url":"./shared/user.ts/~/SelfUser.html","deprecated":false},{"id":"namespace_selfuser","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"SelfUser.email","file":"shared/user.ts","doc":"Where password reset links go. It belongs to this account only.","url":"./shared/user.ts/~/SelfUser.email.html","deprecated":false},{"id":"namespace_usersuggestion","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"UserSuggestion","file":"shared/user.ts","doc":"Returned by GET /api/users?q= to the editor's @mention autocomplete.","url":"./shared/user.ts/~/UserSuggestion.html","deprecated":false},{"id":"namespace_usersuggestion","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"UserSuggestion.id","file":"shared/user.ts","doc":"","url":"./shared/user.ts/~/UserSuggestion.id.html","deprecated":false},{"id":"namespace_usersuggestion","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"UserSuggestion.username","file":"shared/user.ts","doc":"","url":"./shared/user.ts/~/UserSuggestion.username.html","deprecated":false},{"id":"namespace_usersuggestion","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"UserSuggestion.avatarMime","file":"shared/user.ts","doc":"Null without an avatar.","url":"./shared/user.ts/~/UserSuggestion.avatarMime.html","deprecated":false},{"id":"namespace_invitee","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"Invitee","file":"shared/user.ts","doc":"Returned, as a flat list in sign-up order, by GET /api/users/:key/invitees. The profile page nests it into a tree by invitedById.","url":"./shared/user.ts/~/Invitee.html","deprecated":false},{"id":"namespace_invitee","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Invitee.id","file":"shared/user.ts","doc":"","url":"./shared/user.ts/~/Invitee.id.html","deprecated":false},{"id":"namespace_invitee","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Invitee.username","file":"shared/user.ts","doc":"","url":"./shared/user.ts/~/Invitee.username.html","deprecated":false},{"id":"namespace_invitee","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Invitee.avatarMime","file":"shared/user.ts","doc":"Undefined without an avatar.","url":"./shared/user.ts/~/Invitee.avatarMime.html","deprecated":false},{"id":"namespace_invitee","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Invitee.invitedById","file":"shared/user.ts","doc":"","url":"./shared/user.ts/~/Invitee.invitedById.html","deprecated":false},{"id":"namespace_invitee","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Invitee.createdAt","file":"shared/user.ts","doc":"","url":"./shared/user.ts/~/Invitee.createdAt.html","deprecated":false},{"id":"namespace_loginuserrequest","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"LoginUserRequest","file":"shared/user.ts","doc":"Sent to POST /api/sessions by the login page.","url":"./shared/user.ts/~/LoginUserRequest.html","deprecated":false},{"id":"namespace_loginuserrequest","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"LoginUserRequest.username","file":"shared/user.ts","doc":"","url":"./shared/user.ts/~/LoginUserRequest.username.html","deprecated":false},{"id":"namespace_loginuserrequest","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"LoginUserRequest.password","file":"shared/user.ts","doc":"","url":"./shared/user.ts/~/LoginUserRequest.password.html","deprecated":false},{"id":"namespace_registeruserrequest","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"RegisterUserRequest","file":"shared/user.ts","doc":"Sent to POST /api/users by the register page.","url":"./shared/user.ts/~/RegisterUserRequest.html","deprecated":false},{"id":"namespace_registeruserrequest","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"RegisterUserRequest.username","file":"shared/user.ts","doc":"","url":"./shared/user.ts/~/RegisterUserRequest.username.html","deprecated":false},{"id":"namespace_registeruserrequest","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"RegisterUserRequest.password","file":"shared/user.ts","doc":"","url":"./shared/user.ts/~/RegisterUserRequest.password.html","deprecated":false},{"id":"namespace_registeruserrequest","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"RegisterUserRequest.inviteToken","file":"shared/user.ts","doc":"From the invite link the register page was opened with.","url":"./shared/user.ts/~/RegisterUserRequest.inviteToken.html","deprecated":false},{"id":"namespace_registeruserrequest","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"RegisterUserRequest.email","file":"shared/user.ts","doc":"","url":"./shared/user.ts/~/RegisterUserRequest.email.html","deprecated":false},{"id":"namespace_updateuserrequest","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"UpdateUserRequest","file":"shared/user.ts","doc":"Passed to updateUser by the users routes and the password reset, and sent by a client to PATCH /api/me, which takes only description and email; the role and the password change through their own endpoints, and the username through renameUser, by a moderator only.","url":"./shared/user.ts/~/UpdateUserRequest.html","deprecated":false},{"id":"namespace_updateuserrequest","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"UpdateUserRequest.password","file":"shared/user.ts","doc":"","url":"./shared/user.ts/~/UpdateUserRequest.password.html","deprecated":false},{"id":"namespace_updateuserrequest","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"UpdateUserRequest.role","file":"shared/user.ts","doc":"","url":"./shared/user.ts/~/UpdateUserRequest.role.html","deprecated":false},{"id":"namespace_updateuserrequest","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"UpdateUserRequest.description","file":"shared/user.ts","doc":"An empty string clears it. Null, like undefined, keeps it.","url":"./shared/user.ts/~/UpdateUserRequest.description.html","deprecated":false},{"id":"namespace_updateuserrequest","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"UpdateUserRequest.email","file":"shared/user.ts","doc":"","url":"./shared/user.ts/~/UpdateUserRequest.email.html","deprecated":false},{"id":"namespace_authtokens","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"AuthTokens","file":"shared/user.ts","doc":"Returned by sign-up, sign-in and a password change. The client keeps both tokens with its session.","url":"./shared/user.ts/~/AuthTokens.html","deprecated":false},{"id":"namespace_authtokens","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"AuthTokens.token","file":"shared/user.ts","doc":"Sent as Authorization: Bearer …, and as ?token= to the WebSocket.","url":"./shared/user.ts/~/AuthTokens.token.html","deprecated":false},{"id":"namespace_authtokens","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"AuthTokens.mediaToken","file":"shared/user.ts","doc":"Carried as ?token= by the URLs of private media. It can read media and nothing else.","url":"./shared/user.ts/~/AuthTokens.mediaToken.html","deprecated":false},{"id":"namespace_authresponse","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"AuthResponse","file":"shared/user.ts","doc":"Returned by sign-up and sign-in.","url":"./shared/user.ts/~/AuthResponse.html","deprecated":false},{"id":"namespace_authresponse","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"AuthResponse.user","file":"shared/user.ts","doc":"","url":"./shared/user.ts/~/AuthResponse.user.html","deprecated":false},{"id":"namespace_mediatokenresponse","kind":[{"char":"T","kind":"TypeAlias","title":"Type Alias"}],"name":"MediaTokenResponse","file":"shared/user.ts","doc":"Returned by GET /api/me/media-token to a session from before media tokens, which has none.","url":"./shared/user.ts/~/MediaTokenResponse.html","deprecated":false},{"id":"namespace_inviteresponse","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"InviteResponse","file":"shared/user.ts","doc":"Returned by POST /api/invites to the profile page, which builds the invite link from token.","url":"./shared/user.ts/~/InviteResponse.html","deprecated":false},{"id":"namespace_inviteresponse","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"InviteResponse.token","file":"shared/user.ts","doc":"","url":"./shared/user.ts/~/InviteResponse.token.html","deprecated":false},{"id":"namespace_validation","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"VALIDATION","file":"shared/validation.ts","doc":"Read by the validators and services, which refuse what breaks a limit, and by the forms, which say so before sending. Lengths are JavaScript string lengths, so an emoji may count for two. The category limits are checked on the server only.","url":"./shared/validation.ts/~/VALIDATION.html","deprecated":false},{"id":"namespace_validation","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"VALIDATION.USERNAME_MIN","file":"shared/validation.ts","doc":"","url":"./shared/validation.ts/~/VALIDATION.USERNAME_MIN.html","deprecated":false},{"id":"namespace_validation","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"VALIDATION.USERNAME_MAX","file":"shared/validation.ts","doc":"","url":"./shared/validation.ts/~/VALIDATION.USERNAME_MAX.html","deprecated":false},{"id":"namespace_validation","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"VALIDATION.PASSWORD_MIN","file":"shared/validation.ts","doc":"","url":"./shared/validation.ts/~/VALIDATION.PASSWORD_MIN.html","deprecated":false},{"id":"namespace_validation","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"VALIDATION.PASSWORD_MAX","file":"shared/validation.ts","doc":"","url":"./shared/validation.ts/~/VALIDATION.PASSWORD_MAX.html","deprecated":false},{"id":"namespace_validation","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"VALIDATION.DUMP_TITLE_MAX","file":"shared/validation.ts","doc":"","url":"./shared/validation.ts/~/VALIDATION.DUMP_TITLE_MAX.html","deprecated":false},{"id":"namespace_validation","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"VALIDATION.DUMP_COMMENT_MAX","file":"shared/validation.ts","doc":"Applies to a dump's note, which the API calls its comment.","url":"./shared/validation.ts/~/VALIDATION.DUMP_COMMENT_MAX.html","deprecated":false},{"id":"namespace_validation","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"VALIDATION.PLAYLIST_TITLE_MAX","file":"shared/validation.ts","doc":"","url":"./shared/validation.ts/~/VALIDATION.PLAYLIST_TITLE_MAX.html","deprecated":false},{"id":"namespace_validation","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"VALIDATION.PLAYLIST_DESCRIPTION_MAX","file":"shared/validation.ts","doc":"","url":"./shared/validation.ts/~/VALIDATION.PLAYLIST_DESCRIPTION_MAX.html","deprecated":false},{"id":"namespace_validation","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"VALIDATION.COMMENT_BODY_MAX","file":"shared/validation.ts","doc":"","url":"./shared/validation.ts/~/VALIDATION.COMMENT_BODY_MAX.html","deprecated":false},{"id":"namespace_validation","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"VALIDATION.USER_DESCRIPTION_MAX","file":"shared/validation.ts","doc":"","url":"./shared/validation.ts/~/VALIDATION.USER_DESCRIPTION_MAX.html","deprecated":false},{"id":"namespace_validation","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"VALIDATION.CATEGORY_NAME_MAX","file":"shared/validation.ts","doc":"","url":"./shared/validation.ts/~/VALIDATION.CATEGORY_NAME_MAX.html","deprecated":false},{"id":"namespace_validation","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"VALIDATION.CATEGORY_SLUG_MAX","file":"shared/validation.ts","doc":"","url":"./shared/validation.ts/~/VALIDATION.CATEGORY_SLUG_MAX.html","deprecated":false},{"id":"namespace_validation","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"VALIDATION.CHAT_MESSAGE_MAX","file":"shared/validation.ts","doc":"","url":"./shared/validation.ts/~/VALIDATION.CHAT_MESSAGE_MAX.html","deprecated":false},{"id":"namespace_username_re","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"USERNAME_RE","file":"shared/validation.ts","doc":"Matches a valid username, made of letters, digits and underscores within the VALIDATION limits. Sign-up and renaming check it on both sides. It uses the same \\w that a handle's pattern (HANDLE_SOURCE) reads a name with; only a user from another instance has the @host part.","url":"./shared/validation.ts/~/USERNAME_RE.html","deprecated":false},{"id":"namespace_host_source","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"HOST_SOURCE","file":"shared/validation.ts","doc":"The pattern of an instance's host as a handle writes it: DNS labels, and a port for instances on one machine (localhost:8001). It ends on a letter or a digit, so the period that ends a sentence after a mention isn't taken in. HANDLE_SOURCE builds on it.","url":"./shared/validation.ts/~/HOST_SOURCE.html","deprecated":false},{"id":"namespace_handle_source","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"HANDLE_SOURCE","file":"shared/validation.ts","doc":"The pattern of a handle, the name a user goes by on this instance: a local user's username, or name@host for a user whose account lives on another gerbeur (federation-service.ts stores it so in users.username). Paths, mentions and the profile links all read names by it, through HANDLE_RE, MENTION_RE (shared/mention.ts) and parsePagePath (shared/paths.ts).","url":"./shared/validation.ts/~/HANDLE_SOURCE.html","deprecated":false},{"id":"namespace_handle_re","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"HANDLE_RE","file":"shared/validation.ts","doc":"Matches a whole handle (HANDLE_SOURCE).","url":"./shared/validation.ts/~/HANDLE_RE.html","deprecated":false},{"id":"namespace_host_re","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"HOST_RE","file":"shared/validation.ts","doc":"Matches a whole host (HOST_SOURCE).","url":"./shared/validation.ts/~/HOST_RE.html","deprecated":false},{"id":"namespace_splithandle","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"splitHandle","file":"shared/validation.ts","doc":"Returns the name and, for a user from another instance, the host of handle. splitHandle(\"alice@music.example\") is { name: \"alice\", host: \"music.example\" }; a local name has no host.","url":"./shared/validation.ts/~/splitHandle.html","deprecated":false},{"id":"namespace_localhandle","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"localHandle","file":"shared/validation.ts","doc":"Returns handle as this instance writes it, isSelfHost telling its own host. Another instance writes a user from here with this one's host, bob@gerbeur.example, who is bob here: a mention or a link copied from there names them so. Any other handle is returned as it is. The server resolves names by it (resolveUsername, the mention notifications), and the chat's highlight (mentionsUser) reads mentions by it.","url":"./shared/validation.ts/~/localHandle.html","deprecated":false},{"id":"namespace_rename_limits","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"RENAME_LIMITS","file":"shared/validation.ts","doc":"How often a dump's or a playlist's slug may change, counted from the aliases the changes left: 3 times a day. Moderators are exempt. slug-service refuses a change past it with a 429, and the edit forms say what the limit is.","url":"./shared/validation.ts/~/RENAME_LIMITS.html","deprecated":false},{"id":"namespace_rename_limits","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"RENAME_LIMITS.SLUG","file":"shared/validation.ts","doc":"","url":"./shared/validation.ts/~/RENAME_LIMITS.SLUG.html","deprecated":false},{"id":"namespace_rename_limits","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"RENAME_LIMITS.SLUG.count","file":"shared/validation.ts","doc":"","url":"./shared/validation.ts/~/RENAME_LIMITS.SLUG.count.html","deprecated":false},{"id":"namespace_rename_limits","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"RENAME_LIMITS.SLUG.windowMs","file":"shared/validation.ts","doc":"","url":"./shared/validation.ts/~/RENAME_LIMITS.SLUG.windowMs.html","deprecated":false},{"id":"namespace_uuid_re","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"UUID_RE","file":"shared/validation.ts","doc":"Matches an id the server makes with crypto.randomUUID(). A route checks one before it names a file on disk, and shared/attachment.ts finds the attachments a text links by it.","url":"./shared/validation.ts/~/UUID_RE.html","deprecated":false},{"id":"namespace_email_re","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"EMAIL_RE","file":"shared/validation.ts","doc":"Matches an email address well enough to catch a typo; only the reset email arriving proves it.","url":"./shared/validation.ts/~/EMAIL_RE.html","deprecated":false},{"id":"namespace_dump_max_file_size_bytes","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"DUMP_MAX_FILE_SIZE_BYTES","file":"shared/validation.ts","doc":"The largest file a file dump may hold, in bytes. dump-service refuses a bigger one, and the create form before uploading it.","url":"./shared/validation.ts/~/DUMP_MAX_FILE_SIZE_BYTES.html","deprecated":false},{"id":"namespace_waveform_peaks","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"WAVEFORM_PEAKS","file":"shared/waveform.ts","doc":"How many peaks, and so bars, a waveform has.","url":"./shared/waveform.ts/~/WAVEFORM_PEAKS.html","deprecated":false},{"id":"namespace_dumpwaveform","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"DumpWaveform","file":"shared/waveform.ts","doc":"Returned by GET /api/dumps/:dumpId/waveform for an audio file dump, to the player's waveform.","url":"./shared/waveform.ts/~/DumpWaveform.html","deprecated":false},{"id":"namespace_dumpwaveform","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DumpWaveform.peaks","file":"shared/waveform.ts","doc":"WAVEFORM_PEAKS heights from 0 to 1, as peaksOf gives.","url":"./shared/waveform.ts/~/DumpWaveform.peaks.html","deprecated":false},{"id":"namespace_peaksof","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"peaksOf","file":"shared/waveform.ts","doc":"Returns n peaks of samples, each the loudest of its slice, scaled so the loudest of all is 1 and rounded to three places: a quiet recording fills the waveform as a loud one does. samples may be signed, as audio is, or already peaks of smaller slices. Silence gives zeros.","url":"./shared/waveform.ts/~/peaksOf.html","deprecated":false},{"id":"namespace_pingmessage","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"PingMessage","file":"shared/ws.ts","doc":"Sent by the server to every socket every 30 s. WSProvider answers PongMessage, and a socket that missed the previous ping is closed. The server also answers a client's ping, though the client never sends one.","url":"./shared/ws.ts/~/PingMessage.html","deprecated":false},{"id":"namespace_pingmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PingMessage.type","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/PingMessage.type.html","deprecated":false},{"id":"namespace_pongmessage","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"PongMessage","file":"shared/ws.ts","doc":"Sent in answer to a PingMessage. The server records the client's to keep its socket open, and the client ignores the server's.","url":"./shared/ws.ts/~/PongMessage.html","deprecated":false},{"id":"namespace_pongmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PongMessage.type","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/PongMessage.type.html","deprecated":false},{"id":"namespace_votecastmessage","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"VoteCastMessage","file":"shared/ws.ts","doc":"Sent by WSProvider when the user upvotes a dump, after it has shown the vote. The server answers VoteAckMessage, or an ErrorMessage naming the dump, on which the client undoes the vote, as it does when neither comes within 5 s.","url":"./shared/ws.ts/~/VoteCastMessage.html","deprecated":false},{"id":"namespace_votecastmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"VoteCastMessage.type","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/VoteCastMessage.type.html","deprecated":false},{"id":"namespace_votecastmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"VoteCastMessage.dumpId","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/VoteCastMessage.dumpId.html","deprecated":false},{"id":"namespace_voteremovemessage","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"VoteRemoveMessage","file":"shared/ws.ts","doc":"Sent by WSProvider to withdraw an upvote, as VoteCastMessage.","url":"./shared/ws.ts/~/VoteRemoveMessage.html","deprecated":false},{"id":"namespace_voteremovemessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"VoteRemoveMessage.type","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/VoteRemoveMessage.type.html","deprecated":false},{"id":"namespace_voteremovemessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"VoteRemoveMessage.dumpId","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/VoteRemoveMessage.dumpId.html","deprecated":false},{"id":"namespace_commentlikecastmessage","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"CommentLikeCastMessage","file":"shared/ws.ts","doc":"Sent by WSProvider when the user likes a comment, and handled as VoteCastMessage is, with CommentLikeAckMessage for the ack.","url":"./shared/ws.ts/~/CommentLikeCastMessage.html","deprecated":false},{"id":"namespace_commentlikecastmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommentLikeCastMessage.type","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/CommentLikeCastMessage.type.html","deprecated":false},{"id":"namespace_commentlikecastmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommentLikeCastMessage.commentId","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/CommentLikeCastMessage.commentId.html","deprecated":false},{"id":"namespace_commentlikeremovemessage","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"CommentLikeRemoveMessage","file":"shared/ws.ts","doc":"Sent by WSProvider to withdraw a like, as CommentLikeCastMessage.","url":"./shared/ws.ts/~/CommentLikeRemoveMessage.html","deprecated":false},{"id":"namespace_commentlikeremovemessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommentLikeRemoveMessage.type","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/CommentLikeRemoveMessage.type.html","deprecated":false},{"id":"namespace_commentlikeremovemessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommentLikeRemoveMessage.commentId","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/CommentLikeRemoveMessage.commentId.html","deprecated":false},{"id":"namespace_chatsendmessage","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"ChatSendMessage","file":"shared/ws.ts","doc":"Sent by WSProvider when the user posts in the chatbox, which shows the message as pending meanwhile. The server broadcasts it as ChatMessageMessage, or answers a chat ErrorMessage.","url":"./shared/ws.ts/~/ChatSendMessage.html","deprecated":false},{"id":"namespace_chatsendmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ChatSendMessage.type","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/ChatSendMessage.type.html","deprecated":false},{"id":"namespace_chatsendmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ChatSendMessage.body","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/ChatSendMessage.body.html","deprecated":false},{"id":"namespace_chatsendmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ChatSendMessage.replyToId","file":"shared/ws.ts","doc":"Ignored if longer than 64 characters or naming no message.","url":"./shared/ws.ts/~/ChatSendMessage.replyToId.html","deprecated":false},{"id":"namespace_chatsendmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ChatSendMessage.nonce","file":"shared/ws.ts","doc":"Chosen by the client, and echoed on the broadcast or the error, so that it can match the outcome to its pending message. Ignored if longer than 64 characters.","url":"./shared/ws.ts/~/ChatSendMessage.nonce.html","deprecated":false},{"id":"namespace_chattypingmessage","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"ChatTypingMessage","file":"shared/ws.ts","doc":"Sent by the chatbox while the user types, every 3 s, and once they pause. The server answers every signed-in socket with ChatTypingUpdateMessage when the user starts or stops, and forgets a typer it hasn't heard from in 6 s.","url":"./shared/ws.ts/~/ChatTypingMessage.html","deprecated":false},{"id":"namespace_chattypingmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ChatTypingMessage.type","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/ChatTypingMessage.type.html","deprecated":false},{"id":"namespace_chattypingmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ChatTypingMessage.typing","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/ChatTypingMessage.typing.html","deprecated":false},{"id":"namespace_chatfocusmessage","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"ChatFocusMessage","file":"shared/ws.ts","doc":"Sent by WSProvider when the chatbox opens or closes, when the tab is hidden or shown, and after each welcome. The server notifies no one of a chat mention while one of their sockets says open.","url":"./shared/ws.ts/~/ChatFocusMessage.html","deprecated":false},{"id":"namespace_chatfocusmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ChatFocusMessage.type","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/ChatFocusMessage.type.html","deprecated":false},{"id":"namespace_chatfocusmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ChatFocusMessage.open","file":"shared/ws.ts","doc":"True only while the chatbox is open in a visible tab.","url":"./shared/ws.ts/~/ChatFocusMessage.open.html","deprecated":false},{"id":"namespace_chateditmessage","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"ChatEditMessage","file":"shared/ws.ts","doc":"Sent by WSProvider when the user edits a chat message, their own or, with chat:moderate, anyone's. The server broadcasts ChatMessageUpdatedMessage, or answers a chat ErrorMessage.","url":"./shared/ws.ts/~/ChatEditMessage.html","deprecated":false},{"id":"namespace_chateditmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ChatEditMessage.type","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/ChatEditMessage.type.html","deprecated":false},{"id":"namespace_chateditmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ChatEditMessage.id","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/ChatEditMessage.id.html","deprecated":false},{"id":"namespace_chateditmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ChatEditMessage.body","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/ChatEditMessage.body.html","deprecated":false},{"id":"namespace_chatdeletemessage","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"ChatDeleteMessage","file":"shared/ws.ts","doc":"Sent by WSProvider when the user deletes a chat message, as ChatEditMessage. The server broadcasts ChatMessageDeletedMessage.","url":"./shared/ws.ts/~/ChatDeleteMessage.html","deprecated":false},{"id":"namespace_chatdeletemessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ChatDeleteMessage.type","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/ChatDeleteMessage.type.html","deprecated":false},{"id":"namespace_chatdeletemessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ChatDeleteMessage.id","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/ChatDeleteMessage.id.html","deprecated":false},{"id":"namespace_chatreadmessage","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"ChatReadMessage","file":"shared/ws.ts","doc":"Sent by WSProvider, at most once a second, as the user reads the chat. The server moves their read marker to at, a message's ISO createdAt, and answers ChatReadUpdateMessage. It drops the message silently when it is malformed or over its rate limit.","url":"./shared/ws.ts/~/ChatReadMessage.html","deprecated":false},{"id":"namespace_chatreadmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ChatReadMessage.type","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/ChatReadMessage.type.html","deprecated":false},{"id":"namespace_chatreadmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ChatReadMessage.at","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/ChatReadMessage.at.html","deprecated":false},{"id":"namespace_clienttoservermessage","kind":[{"char":"T","kind":"TypeAlias","title":"Type Alias"}],"name":"ClientToServerMessage","file":"shared/ws.ts","doc":"Sent by WSProvider, and dispatched by the route's handleMessage, which checks each field's type before using it.","url":"./shared/ws.ts/~/ClientToServerMessage.html","deprecated":false},{"id":"namespace_onlineuser","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"OnlineUser","file":"shared/ws.ts","doc":"Sent by the server in WelcomeMessage, PresenceUpdateMessage and ChatTypingUpdateMessage, once per signed-in user whatever their number of sockets.","url":"./shared/ws.ts/~/OnlineUser.html","deprecated":false},{"id":"namespace_onlineuser","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"OnlineUser.userId","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/OnlineUser.userId.html","deprecated":false},{"id":"namespace_onlineuser","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"OnlineUser.username","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/OnlineUser.username.html","deprecated":false},{"id":"namespace_onlineuser","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"OnlineUser.hasAvatar","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/OnlineUser.hasAvatar.html","deprecated":false},{"id":"namespace_onlineuser","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"OnlineUser.avatarVersion","file":"shared/ws.ts","doc":"Set when the avatar changed while the user was connected, for the client to append to the avatar's URL so it doesn't show the cached one.","url":"./shared/ws.ts/~/OnlineUser.avatarVersion.html","deprecated":false},{"id":"namespace_welcomemessage","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"WelcomeMessage","file":"shared/ws.ts","doc":"Sent by the server to a socket once it opens, just after the PresenceUpdateMessage that announces it. WSProvider replaces its state with this one, dropping its pending votes and likes. After a reconnect, it also bumps connectionEpoch, so that pages refetch what they missed. The per-user fields are empty or zero on an anonymous socket.","url":"./shared/ws.ts/~/WelcomeMessage.html","deprecated":false},{"id":"namespace_welcomemessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"WelcomeMessage.type","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/WelcomeMessage.type.html","deprecated":false},{"id":"namespace_welcomemessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"WelcomeMessage.users","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/WelcomeMessage.users.html","deprecated":false},{"id":"namespace_welcomemessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"WelcomeMessage.myVotes","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/WelcomeMessage.myVotes.html","deprecated":false},{"id":"namespace_welcomemessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"WelcomeMessage.myCommentLikes","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/WelcomeMessage.myCommentLikes.html","deprecated":false},{"id":"namespace_welcomemessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"WelcomeMessage.unreadNotificationCount","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/WelcomeMessage.unreadNotificationCount.html","deprecated":false},{"id":"namespace_welcomemessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"WelcomeMessage.chatReadAt","file":"shared/ws.ts","doc":"Absent on an anonymous socket.","url":"./shared/ws.ts/~/WelcomeMessage.chatReadAt.html","deprecated":false},{"id":"namespace_welcomemessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"WelcomeMessage.unreadChatCount","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/WelcomeMessage.unreadChatCount.html","deprecated":false},{"id":"namespace_presenceupdatemessage","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"PresenceUpdateMessage","file":"shared/ws.ts","doc":"Sent by the server to every socket when a socket opens or closes, and when a connected user's avatar changes.","url":"./shared/ws.ts/~/PresenceUpdateMessage.html","deprecated":false},{"id":"namespace_presenceupdatemessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PresenceUpdateMessage.type","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/PresenceUpdateMessage.type.html","deprecated":false},{"id":"namespace_presenceupdatemessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PresenceUpdateMessage.users","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/PresenceUpdateMessage.users.html","deprecated":false},{"id":"namespace_votesupdatemessage","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"VotesUpdateMessage","file":"shared/ws.ts","doc":"Sent by the server after a vote, to every socket, or to the poster's alone for a private dump. WSProvider updates the count, and when voterId is the user, it updates their votes too, so their other tabs follow.","url":"./shared/ws.ts/~/VotesUpdateMessage.html","deprecated":false},{"id":"namespace_votesupdatemessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"VotesUpdateMessage.type","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/VotesUpdateMessage.type.html","deprecated":false},{"id":"namespace_votesupdatemessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"VotesUpdateMessage.dumpId","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/VotesUpdateMessage.dumpId.html","deprecated":false},{"id":"namespace_votesupdatemessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"VotesUpdateMessage.voteCount","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/VotesUpdateMessage.voteCount.html","deprecated":false},{"id":"namespace_votesupdatemessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"VotesUpdateMessage.voterId","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/VotesUpdateMessage.voterId.html","deprecated":false},{"id":"namespace_votesupdatemessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"VotesUpdateMessage.action","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/VotesUpdateMessage.action.html","deprecated":false},{"id":"namespace_voteackmessage","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"VoteAckMessage","file":"shared/ws.ts","doc":"Sent by the server to the socket that sent a VoteCastMessage or VoteRemoveMessage, once the vote is stored. WSProvider confirms its optimistic vote with it.","url":"./shared/ws.ts/~/VoteAckMessage.html","deprecated":false},{"id":"namespace_voteackmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"VoteAckMessage.type","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/VoteAckMessage.type.html","deprecated":false},{"id":"namespace_voteackmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"VoteAckMessage.dumpId","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/VoteAckMessage.dumpId.html","deprecated":false},{"id":"namespace_voteackmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"VoteAckMessage.action","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/VoteAckMessage.action.html","deprecated":false},{"id":"namespace_voteackmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"VoteAckMessage.voteCount","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/VoteAckMessage.voteCount.html","deprecated":false},{"id":"namespace_commentlikesupdatemessage","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"CommentLikesUpdateMessage","file":"shared/ws.ts","doc":"Sent by the server after a like, as VotesUpdateMessage is after a vote: to the dump's poster alone when the comment is on a private dump.","url":"./shared/ws.ts/~/CommentLikesUpdateMessage.html","deprecated":false},{"id":"namespace_commentlikesupdatemessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommentLikesUpdateMessage.type","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/CommentLikesUpdateMessage.type.html","deprecated":false},{"id":"namespace_commentlikesupdatemessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommentLikesUpdateMessage.commentId","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/CommentLikesUpdateMessage.commentId.html","deprecated":false},{"id":"namespace_commentlikesupdatemessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommentLikesUpdateMessage.likeCount","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/CommentLikesUpdateMessage.likeCount.html","deprecated":false},{"id":"namespace_commentlikesupdatemessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommentLikesUpdateMessage.likerId","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/CommentLikesUpdateMessage.likerId.html","deprecated":false},{"id":"namespace_commentlikesupdatemessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommentLikesUpdateMessage.action","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/CommentLikesUpdateMessage.action.html","deprecated":false},{"id":"namespace_commentlikeackmessage","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"CommentLikeAckMessage","file":"shared/ws.ts","doc":"Sent by the server to the socket that liked or unliked a comment, as VoteAckMessage is for a vote.","url":"./shared/ws.ts/~/CommentLikeAckMessage.html","deprecated":false},{"id":"namespace_commentlikeackmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommentLikeAckMessage.type","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/CommentLikeAckMessage.type.html","deprecated":false},{"id":"namespace_commentlikeackmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommentLikeAckMessage.commentId","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/CommentLikeAckMessage.commentId.html","deprecated":false},{"id":"namespace_commentlikeackmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommentLikeAckMessage.action","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/CommentLikeAckMessage.action.html","deprecated":false},{"id":"namespace_commentlikeackmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommentLikeAckMessage.likeCount","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/CommentLikeAckMessage.likeCount.html","deprecated":false},{"id":"namespace_dumpcreatedmessage","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"DumpCreatedMessage","file":"shared/ws.ts","doc":"Sent by the server when a dump is posted, to every socket if it is public and to its poster's alone if it is private. It also goes to everyone but the poster when a private dump goes public, since to them it is new. WSProvider puts it at the top of its recent dumps.","url":"./shared/ws.ts/~/DumpCreatedMessage.html","deprecated":false},{"id":"namespace_dumpcreatedmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DumpCreatedMessage.type","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/DumpCreatedMessage.type.html","deprecated":false},{"id":"namespace_dumpcreatedmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DumpCreatedMessage.dump","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/DumpCreatedMessage.dump.html","deprecated":false},{"id":"namespace_dumpupdatedmessage","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"DumpUpdatedMessage","file":"shared/ws.ts","doc":"Sent by the server when a dump changes, to every socket if it is public and to its poster's alone if it is private, as when it has just gone private. WSProvider refreshes it in place, without moving it up the feeds.","url":"./shared/ws.ts/~/DumpUpdatedMessage.html","deprecated":false},{"id":"namespace_dumpupdatedmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DumpUpdatedMessage.type","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/DumpUpdatedMessage.type.html","deprecated":false},{"id":"namespace_dumpupdatedmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DumpUpdatedMessage.dump","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/DumpUpdatedMessage.dump.html","deprecated":false},{"id":"namespace_dumpdeletedmessage","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"DumpDeletedMessage","file":"shared/ws.ts","doc":"Sent by the server when a dump is deleted, to every socket if it was public and to its poster's alone if it was private. It also goes to everyone but the poster when a public dump goes private. WSProvider drops it from every list.","url":"./shared/ws.ts/~/DumpDeletedMessage.html","deprecated":false},{"id":"namespace_dumpdeletedmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DumpDeletedMessage.type","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/DumpDeletedMessage.type.html","deprecated":false},{"id":"namespace_dumpdeletedmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DumpDeletedMessage.dumpId","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/DumpDeletedMessage.dumpId.html","deprecated":false},{"id":"namespace_dumprelatedchangedmessage","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"DumpRelatedChangedMessage","file":"shared/ws.ts","doc":"Sent by the server when the dumps related to some dumps changed: a note or a comment gained or lost a link to a dump, or a dump that has such links turned public. It goes to the sockets whose user may see both ends of a link. The Dump page showing one of dumpIds fetches its related dumps again.","url":"./shared/ws.ts/~/DumpRelatedChangedMessage.html","deprecated":false},{"id":"namespace_dumprelatedchangedmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DumpRelatedChangedMessage.type","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/DumpRelatedChangedMessage.type.html","deprecated":false},{"id":"namespace_dumprelatedchangedmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DumpRelatedChangedMessage.dumpIds","file":"shared/ws.ts","doc":"The dump whose links changed, then the dumps at their other end, without those this socket's user may not see.","url":"./shared/ws.ts/~/DumpRelatedChangedMessage.dumpIds.html","deprecated":false},{"id":"namespace_playlistcreatedmessage","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"PlaylistCreatedMessage","file":"shared/ws.ts","doc":"Sent by the server when a playlist is created, to every socket if it is public, else to its owner's. It also goes to everyone but the owner when a private playlist goes public, since to them it is new. WSProvider passes it on to the playlist pages as a playlist event, as it does the three messages below.","url":"./shared/ws.ts/~/PlaylistCreatedMessage.html","deprecated":false},{"id":"namespace_playlistcreatedmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PlaylistCreatedMessage.type","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/PlaylistCreatedMessage.type.html","deprecated":false},{"id":"namespace_playlistcreatedmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PlaylistCreatedMessage.playlist","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/PlaylistCreatedMessage.playlist.html","deprecated":false},{"id":"namespace_playlistupdatedmessage","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"PlaylistUpdatedMessage","file":"shared/ws.ts","doc":"Sent by the server when a playlist changes, to every socket if it is public, else to its owner's, as when it has just gone private. Its dumpCount and lastDumpAt are the socket's user's, as in playlist_created.","url":"./shared/ws.ts/~/PlaylistUpdatedMessage.html","deprecated":false},{"id":"namespace_playlistupdatedmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PlaylistUpdatedMessage.type","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/PlaylistUpdatedMessage.type.html","deprecated":false},{"id":"namespace_playlistupdatedmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PlaylistUpdatedMessage.playlist","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/PlaylistUpdatedMessage.playlist.html","deprecated":false},{"id":"namespace_playlistdeletedmessage","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"PlaylistDeletedMessage","file":"shared/ws.ts","doc":"Sent by the server when a playlist is deleted, to those who could see it. It also goes to everyone but the owner when a public playlist goes private.","url":"./shared/ws.ts/~/PlaylistDeletedMessage.html","deprecated":false},{"id":"namespace_playlistdeletedmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PlaylistDeletedMessage.type","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/PlaylistDeletedMessage.type.html","deprecated":false},{"id":"namespace_playlistdeletedmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PlaylistDeletedMessage.playlistId","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/PlaylistDeletedMessage.playlistId.html","deprecated":false},{"id":"namespace_playlistdeletedmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PlaylistDeletedMessage.userId","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/PlaylistDeletedMessage.userId.html","deprecated":false},{"id":"namespace_playlistdumpsupdatedmessage","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"PlaylistDumpsUpdatedMessage","file":"shared/ws.ts","doc":"Sent by the server when dumps are added to, removed from or reordered in a playlist, to those who can see it, and when one of its dumps is deleted or changes visibility, which changes what its viewers see of it.","url":"./shared/ws.ts/~/PlaylistDumpsUpdatedMessage.html","deprecated":false},{"id":"namespace_playlistdumpsupdatedmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PlaylistDumpsUpdatedMessage.type","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/PlaylistDumpsUpdatedMessage.type.html","deprecated":false},{"id":"namespace_playlistdumpsupdatedmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PlaylistDumpsUpdatedMessage.playlistId","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/PlaylistDumpsUpdatedMessage.playlistId.html","deprecated":false},{"id":"namespace_playlistdumpsupdatedmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PlaylistDumpsUpdatedMessage.dumpIds","file":"shared/ws.ts","doc":"Only the dumps this socket's user may see, in order: another user's private dump is left out.","url":"./shared/ws.ts/~/PlaylistDumpsUpdatedMessage.dumpIds.html","deprecated":false},{"id":"namespace_playlistdumpsupdatedmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PlaylistDumpsUpdatedMessage.lastDumpAt","file":"shared/ws.ts","doc":"When the latest of them was added, the playlist's lastDumpAt for this socket's user. It is missing when dumpIds is empty.","url":"./shared/ws.ts/~/PlaylistDumpsUpdatedMessage.lastDumpAt.html","deprecated":false},{"id":"namespace_userupdatedmessage","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"UserUpdatedMessage","file":"shared/ws.ts","doc":"Sent by the server to every socket after a profile edit, a rename, a role change or an avatar upload. WSProvider refreshes the user's avatar wherever it shows, and passes it on as a user event, which updates their profile and their name on the lists.","url":"./shared/ws.ts/~/UserUpdatedMessage.html","deprecated":false},{"id":"namespace_userupdatedmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"UserUpdatedMessage.type","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/UserUpdatedMessage.type.html","deprecated":false},{"id":"namespace_userupdatedmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"UserUpdatedMessage.user","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/UserUpdatedMessage.user.html","deprecated":false},{"id":"namespace_commentcreatedmessage","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"CommentCreatedMessage","file":"shared/ws.ts","doc":"Sent by the server when a comment is posted, to every socket if its dump is public, else to the dump's poster's. WSProvider passes it on to the dump's page and the dump lists as a comment event, as it does the two messages below.","url":"./shared/ws.ts/~/CommentCreatedMessage.html","deprecated":false},{"id":"namespace_commentcreatedmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommentCreatedMessage.type","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/CommentCreatedMessage.type.html","deprecated":false},{"id":"namespace_commentcreatedmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommentCreatedMessage.comment","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/CommentCreatedMessage.comment.html","deprecated":false},{"id":"namespace_commentupdatedmessage","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"CommentUpdatedMessage","file":"shared/ws.ts","doc":"Sent by the server when a comment is edited, as when one is posted.","url":"./shared/ws.ts/~/CommentUpdatedMessage.html","deprecated":false},{"id":"namespace_commentupdatedmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommentUpdatedMessage.type","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/CommentUpdatedMessage.type.html","deprecated":false},{"id":"namespace_commentupdatedmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommentUpdatedMessage.comment","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/CommentUpdatedMessage.comment.html","deprecated":false},{"id":"namespace_commentdeletedmessage","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"CommentDeletedMessage","file":"shared/ws.ts","doc":"Sent by the server when a comment is deleted, as when one is posted.","url":"./shared/ws.ts/~/CommentDeletedMessage.html","deprecated":false},{"id":"namespace_commentdeletedmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommentDeletedMessage.type","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/CommentDeletedMessage.type.html","deprecated":false},{"id":"namespace_commentdeletedmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommentDeletedMessage.commentId","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/CommentDeletedMessage.commentId.html","deprecated":false},{"id":"namespace_commentdeletedmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommentDeletedMessage.dumpId","file":"shared/ws.ts","doc":"Lets a dump's page ignore the comments of other dumps.","url":"./shared/ws.ts/~/CommentDeletedMessage.dumpId.html","deprecated":false},{"id":"namespace_notificationcreatedmessage","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"NotificationCreatedMessage","file":"shared/ws.ts","doc":"Sent by the notification service to every socket of the notified user. WSProvider bumps the unread count and chimes.","url":"./shared/ws.ts/~/NotificationCreatedMessage.html","deprecated":false},{"id":"namespace_notificationcreatedmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"NotificationCreatedMessage.type","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/NotificationCreatedMessage.type.html","deprecated":false},{"id":"namespace_notificationcreatedmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"NotificationCreatedMessage.notification","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/NotificationCreatedMessage.notification.html","deprecated":false},{"id":"namespace_notificationsreadmessage","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"NotificationsReadMessage","file":"shared/ws.ts","doc":"Sent by the notification service to every socket of a user who opened their notifications, which marks them all read. WSProvider zeroes the bell's count, in the other tabs and devices too.","url":"./shared/ws.ts/~/NotificationsReadMessage.html","deprecated":false},{"id":"namespace_notificationsreadmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"NotificationsReadMessage.type","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/NotificationsReadMessage.type.html","deprecated":false},{"id":"namespace_categorieschangedmessage","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"CategoriesChangedMessage","file":"shared/ws.ts","doc":"Sent by the category service to every socket after a category is created, edited or deleted. CategoriesProvider fetches the categories again.","url":"./shared/ws.ts/~/CategoriesChangedMessage.html","deprecated":false},{"id":"namespace_categorieschangedmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CategoriesChangedMessage.type","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/CategoriesChangedMessage.type.html","deprecated":false},{"id":"namespace_errormessage","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"ErrorMessage","file":"shared/ws.ts","doc":"Sent by the server to the socket whose message failed. With dumpId or commentId, WSProvider undoes that optimistic vote or like at once rather than after its 5 s timeout. With scope, the chatbox shows it, on the pending message nonce names or as a notice. Any other error is ignored.","url":"./shared/ws.ts/~/ErrorMessage.html","deprecated":false},{"id":"namespace_errormessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ErrorMessage.type","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/ErrorMessage.type.html","deprecated":false},{"id":"namespace_errormessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ErrorMessage.message","file":"shared/ws.ts","doc":"In English: the chatbox shows it untranslated.","url":"./shared/ws.ts/~/ErrorMessage.message.html","deprecated":false},{"id":"namespace_errormessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ErrorMessage.dumpId","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/ErrorMessage.dumpId.html","deprecated":false},{"id":"namespace_errormessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ErrorMessage.commentId","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/ErrorMessage.commentId.html","deprecated":false},{"id":"namespace_errormessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ErrorMessage.action","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/ErrorMessage.action.html","deprecated":false},{"id":"namespace_errormessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ErrorMessage.scope","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/ErrorMessage.scope.html","deprecated":false},{"id":"namespace_errormessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ErrorMessage.nonce","file":"shared/ws.ts","doc":"Set only on the failure of a ChatSendMessage that had one.","url":"./shared/ws.ts/~/ErrorMessage.nonce.html","deprecated":false},{"id":"namespace_chatmessagemessage","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"ChatMessageMessage","file":"shared/ws.ts","doc":"Sent by the server to every signed-in socket, the sender's included, when a chat message is posted. WSProvider adds it to the live chat, counts it unread unless the user is reading the chat, and may chime.","url":"./shared/ws.ts/~/ChatMessageMessage.html","deprecated":false},{"id":"namespace_chatmessagemessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ChatMessageMessage.type","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/ChatMessageMessage.type.html","deprecated":false},{"id":"namespace_chatmessagemessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ChatMessageMessage.message","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/ChatMessageMessage.message.html","deprecated":false},{"id":"namespace_chatmessagemessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ChatMessageMessage.nonce","file":"shared/ws.ts","doc":"The sender's ChatSendMessage nonce, by which its client swaps the pending copy for this one.","url":"./shared/ws.ts/~/ChatMessageMessage.nonce.html","deprecated":false},{"id":"namespace_chatmessageupdatedmessage","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"ChatMessageUpdatedMessage","file":"shared/ws.ts","doc":"Sent by the server to every signed-in socket when a chat message is edited.","url":"./shared/ws.ts/~/ChatMessageUpdatedMessage.html","deprecated":false},{"id":"namespace_chatmessageupdatedmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ChatMessageUpdatedMessage.type","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/ChatMessageUpdatedMessage.type.html","deprecated":false},{"id":"namespace_chatmessageupdatedmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ChatMessageUpdatedMessage.message","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/ChatMessageUpdatedMessage.message.html","deprecated":false},{"id":"namespace_chatmessagedeletedmessage","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"ChatMessageDeletedMessage","file":"shared/ws.ts","doc":"Sent by the server to every signed-in socket when a chat message is deleted. The client also keeps the id, to show the replies to it as replies to a deleted message.","url":"./shared/ws.ts/~/ChatMessageDeletedMessage.html","deprecated":false},{"id":"namespace_chatmessagedeletedmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ChatMessageDeletedMessage.type","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/ChatMessageDeletedMessage.type.html","deprecated":false},{"id":"namespace_chatmessagedeletedmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ChatMessageDeletedMessage.id","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/ChatMessageDeletedMessage.id.html","deprecated":false},{"id":"namespace_chattypingupdatemessage","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"ChatTypingUpdateMessage","file":"shared/ws.ts","doc":"Sent by the server to every signed-in socket when a user starts or stops typing in the chat, with everyone typing. The chatbox shows their avatars.","url":"./shared/ws.ts/~/ChatTypingUpdateMessage.html","deprecated":false},{"id":"namespace_chattypingupdatemessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ChatTypingUpdateMessage.type","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/ChatTypingUpdateMessage.type.html","deprecated":false},{"id":"namespace_chattypingupdatemessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ChatTypingUpdateMessage.users","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/ChatTypingUpdateMessage.users.html","deprecated":false},{"id":"namespace_chatreadupdatemessage","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"ChatReadUpdateMessage","file":"shared/ws.ts","doc":"Sent by the server to every socket of a user after their ChatReadMessage, so that all their tabs and devices update the chat's badge.","url":"./shared/ws.ts/~/ChatReadUpdateMessage.html","deprecated":false},{"id":"namespace_chatreadupdatemessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ChatReadUpdateMessage.type","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/ChatReadUpdateMessage.type.html","deprecated":false},{"id":"namespace_chatreadupdatemessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ChatReadUpdateMessage.readAt","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/ChatReadUpdateMessage.readAt.html","deprecated":false},{"id":"namespace_chatreadupdatemessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ChatReadUpdateMessage.unread","file":"shared/ws.ts","doc":"Counts only the messages of other users after readAt.","url":"./shared/ws.ts/~/ChatReadUpdateMessage.unread.html","deprecated":false},{"id":"namespace_followschangedmessage","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"FollowsChangedMessage","file":"shared/ws.ts","doc":"Sent by the server to every socket of a user who followed or unfollowed a user or a playlist, so that FollowProvider in their other tabs refetches the follow status.","url":"./shared/ws.ts/~/FollowsChangedMessage.html","deprecated":false},{"id":"namespace_followschangedmessage","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"FollowsChangedMessage.type","file":"shared/ws.ts","doc":"","url":"./shared/ws.ts/~/FollowsChangedMessage.type.html","deprecated":false},{"id":"namespace_servertoclientmessage","kind":[{"char":"T","kind":"TypeAlias","title":"Type Alias"}],"name":"ServerToClientMessage","file":"shared/ws.ts","doc":"Sent by services/ws-service.ts and the WebSocket route, and handled by WSProvider's onmessage.","url":"./shared/ws.ts/~/ServerToClientMessage.html","deprecated":false},{"id":"namespace_approutes","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"AppRoutes","file":"src/App.tsx","doc":"Renders the route table, and the floating buttons over every page. Exported for the tests, which reach a page through it as a visit does.","url":"./src/App.tsx/~/AppRoutes.html","deprecated":false},{"id":"namespace_app","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"App","file":"src/App.tsx","doc":"Renders the app. The theme, player, socket, follow and chat providers read the session, and ChatProvider reads the URL, so it sits inside the router. GlobalPlayer sits outside the routes, so playback survives navigation.","url":"./src/App.tsx/~/App.html","deprecated":false},{"id":"namespace_categorychipsprops","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"CategoryChipsProps","file":"src/components/category/CategoryChips.tsx","doc":"Passed to CategoryChips by DumpCard and Dump for a dump, and by PlaylistCard and PlaylistHeader for a playlist.","url":"./src/components/category/CategoryChips.tsx/~/CategoryChipsProps.html","deprecated":false},{"id":"namespace_categorychipsprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CategoryChipsProps.kind","file":"src/components/category/CategoryChips.tsx","doc":"Whether ids name dump or playlist categories.","url":"./src/components/category/CategoryChips.tsx/~/CategoryChipsProps.kind.html","deprecated":false},{"id":"namespace_categorychipsprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CategoryChipsProps.ids","file":"src/components/category/CategoryChips.tsx","doc":"The dump's or playlist's categoryIds.","url":"./src/components/category/CategoryChips.tsx/~/CategoryChipsProps.ids.html","deprecated":false},{"id":"namespace_categorychipsprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CategoryChipsProps.className","file":"src/components/category/CategoryChips.tsx","doc":"Added to the row's own class, for a card's grid to place it.","url":"./src/components/category/CategoryChips.tsx/~/CategoryChipsProps.className.html","deprecated":false},{"id":"namespace_categorychipsprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CategoryChipsProps.onClick","file":"src/components/category/CategoryChips.tsx","doc":"Called on a click in the row. A clickable card stops it there, or a chip's click would open the card too.","url":"./src/components/category/CategoryChips.tsx/~/CategoryChipsProps.onClick.html","deprecated":false},{"id":"namespace_categorychips","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"CategoryChips","file":"src/components/category/CategoryChips.tsx","doc":"Renders each category ids names as a chip linking to its page, a dump category's feed or a playlist category's playlists, in the categories' order. Ids of categories since deleted are skipped, and it renders nothing when none is left.","url":"./src/components/category/CategoryChips.tsx/~/CategoryChips.html","deprecated":false},{"id":"namespace_categorymanagerprops","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"CategoryManagerProps","file":"src/components/category/CategoryManager.tsx","doc":"Passed to CategoryManager by Manage, once for each kind.","url":"./src/components/category/CategoryManager.tsx/~/CategoryManagerProps.html","deprecated":false},{"id":"namespace_categorymanagerprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CategoryManagerProps.kind","file":"src/components/category/CategoryManager.tsx","doc":"The set it edits, and the kind of the categories it creates.","url":"./src/components/category/CategoryManager.tsx/~/CategoryManagerProps.kind.html","deprecated":false},{"id":"namespace_categorymanager","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"CategoryManager","file":"src/components/category/CategoryManager.tsx","doc":"Renders the categories of kind as chips that open an inline editor, and a \"+\" chip that creates one. Only one editor is open at a time. A change refetches the app-wide list, so the category switchers follow. Manage shows it only to those who hold category:manage, and the server checks it again.","url":"./src/components/category/CategoryManager.tsx/~/CategoryManager.html","deprecated":false},{"id":"namespace_categoryselectprops","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"CategorySelectProps","file":"src/components/category/CategorySelect.tsx","doc":"Passed to CategorySelect by DumpCreateModal and DumpEdit, and by PlaylistCreateForm and PlaylistEditForm, which hold the selection and send it as the dump's or playlist's categoryIds.","url":"./src/components/category/CategorySelect.tsx/~/CategorySelectProps.html","deprecated":false},{"id":"namespace_categoryselectprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CategorySelectProps.kind","file":"src/components/category/CategorySelect.tsx","doc":"The set it offers: dump categories for a dump, playlist ones for a playlist.","url":"./src/components/category/CategorySelect.tsx/~/CategorySelectProps.kind.html","deprecated":false},{"id":"namespace_categoryselectprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CategorySelectProps.selected","file":"src/components/category/CategorySelect.tsx","doc":"","url":"./src/components/category/CategorySelect.tsx/~/CategorySelectProps.selected.html","deprecated":false},{"id":"namespace_categoryselectprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CategorySelectProps.onToggle","file":"src/components/category/CategorySelect.tsx","doc":"","url":"./src/components/category/CategorySelect.tsx/~/CategorySelectProps.onToggle.html","deprecated":false},{"id":"namespace_categoryselectprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CategorySelectProps.disabled","file":"src/components/category/CategorySelect.tsx","doc":"","url":"./src/components/category/CategorySelect.tsx/~/CategorySelectProps.disabled.html","deprecated":false},{"id":"namespace_categoryselect","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"CategorySelect","file":"src/components/category/CategorySelect.tsx","doc":"Renders the categories of kind as toggle chips, any number of which may be on. It renders nothing while the site has none.","url":"./src/components/category/CategorySelect.tsx/~/CategorySelect.html","deprecated":false},{"id":"namespace_categoryswitcherprops","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"CategorySwitcherProps","file":"src/components/category/CategorySwitcher.tsx","doc":"Passed to CategorySwitcher by FeedTabBar, ProfileDumpsTab, ProfilePlaylistsTab, Playlists and Search, which keep the category in their URL.","url":"./src/components/category/CategorySwitcher.tsx/~/CategorySwitcherProps.html","deprecated":false},{"id":"namespace_categoryswitcherprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CategorySwitcherProps.kind","file":"src/components/category/CategorySwitcher.tsx","doc":"The set it offers: dump categories for dumps, playlist ones for playlists.","url":"./src/components/category/CategorySwitcher.tsx/~/CategorySwitcherProps.kind.html","deprecated":false},{"id":"namespace_categoryswitcherprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CategorySwitcherProps.categorySlug","file":"src/components/category/CategorySwitcher.tsx","doc":"The category shown, or none for every dump or playlist.","url":"./src/components/category/CategorySwitcher.tsx/~/CategorySwitcherProps.categorySlug.html","deprecated":false},{"id":"namespace_categoryswitcherprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CategorySwitcherProps.onSelect","file":"src/components/category/CategorySwitcher.tsx","doc":"Called with the slug of the category picked, or undefined for \"All\".","url":"./src/components/category/CategorySwitcher.tsx/~/CategorySwitcherProps.onSelect.html","deprecated":false},{"id":"namespace_categoryswitcher","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"CategorySwitcher","file":"src/components/category/CategorySwitcher.tsx","doc":"Renders a button naming the category shown, \"All\" without one, that opens the menu of every category of kind. It renders nothing while the site has none.","url":"./src/components/category/CategorySwitcher.tsx/~/CategorySwitcher.html","deprecated":false},{"id":"namespace_chateditboxprops","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"ChatEditBoxProps","file":"src/components/chat/ChatEditBox.tsx","doc":"Passed to ChatEditBox by ChatMessageItem while it is editing.","url":"./src/components/chat/ChatEditBox.tsx/~/ChatEditBoxProps.html","deprecated":false},{"id":"namespace_chateditboxprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ChatEditBoxProps.initial","file":"src/components/chat/ChatEditBox.tsx","doc":"","url":"./src/components/chat/ChatEditBox.tsx/~/ChatEditBoxProps.initial.html","deprecated":false},{"id":"namespace_chateditboxprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ChatEditBoxProps.onSave","file":"src/components/chat/ChatEditBox.tsx","doc":"Receives the trimmed text, only when it changed and can be sent.","url":"./src/components/chat/ChatEditBox.tsx/~/ChatEditBoxProps.onSave.html","deprecated":false},{"id":"namespace_chateditboxprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ChatEditBoxProps.onClose","file":"src/components/chat/ChatEditBox.tsx","doc":"Called once the text is saved, or left, Escape included.","url":"./src/components/chat/ChatEditBox.tsx/~/ChatEditBoxProps.onClose.html","deprecated":false},{"id":"namespace_chateditbox","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"ChatEditBox","file":"src/components/chat/ChatEditBox.tsx","doc":"Renders the field every text edited in place gets, InlineEditField, with Enter saving and Shift+Enter starting a new line, as in the composer. It scrolls itself into the list's view.","url":"./src/components/chat/ChatEditBox.tsx/~/ChatEditBox.html","deprecated":false},{"id":"namespace_chatmessageitemprops","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"ChatMessageItemProps","file":"src/components/chat/ChatMessageItem.tsx","doc":"Passed to ChatMessageItem by ChatModal for each message row. The modal holds the edit, flash and permission state, and sends the edits and deletions over the socket.","url":"./src/components/chat/ChatMessageItem.tsx/~/ChatMessageItemProps.html","deprecated":false},{"id":"namespace_chatmessageitemprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ChatMessageItemProps.message","file":"src/components/chat/ChatMessageItem.tsx","doc":"","url":"./src/components/chat/ChatMessageItem.tsx/~/ChatMessageItemProps.message.html","deprecated":false},{"id":"namespace_chatmessageitemprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ChatMessageItemProps.grouped","file":"src/components/chat/ChatMessageItem.tsx","doc":"Set when the message continues its author's run. It then has no avatar or author line: its time shows in the avatar's place on hover, and its actions float over its top.","url":"./src/components/chat/ChatMessageItem.tsx/~/ChatMessageItemProps.grouped.html","deprecated":false},{"id":"namespace_chatmessageitemprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ChatMessageItemProps.mentionsMe","file":"src/components/chat/ChatMessageItem.tsx","doc":"Highlights a message that @mentions the user, @everyone included, or replies to them.","url":"./src/components/chat/ChatMessageItem.tsx/~/ChatMessageItemProps.mentionsMe.html","deprecated":false},{"id":"namespace_chatmessageitemprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ChatMessageItemProps.replyDeleted","file":"src/components/chat/ChatMessageItem.tsx","doc":"Set when the replied-to message was deleted live, after the server filled in replyToAuthor.","url":"./src/components/chat/ChatMessageItem.tsx/~/ChatMessageItemProps.replyDeleted.html","deprecated":false},{"id":"namespace_chatmessageitemprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ChatMessageItemProps.canEdit","file":"src/components/chat/ChatMessageItem.tsx","doc":"","url":"./src/components/chat/ChatMessageItem.tsx/~/ChatMessageItemProps.canEdit.html","deprecated":false},{"id":"namespace_chatmessageitemprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ChatMessageItemProps.canDelete","file":"src/components/chat/ChatMessageItem.tsx","doc":"","url":"./src/components/chat/ChatMessageItem.tsx/~/ChatMessageItemProps.canDelete.html","deprecated":false},{"id":"namespace_chatmessageitemprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ChatMessageItemProps.flashed","file":"src/components/chat/ChatMessageItem.tsx","doc":"","url":"./src/components/chat/ChatMessageItem.tsx/~/ChatMessageItemProps.flashed.html","deprecated":false},{"id":"namespace_chatmessageitemprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ChatMessageItemProps.editing","file":"src/components/chat/ChatMessageItem.tsx","doc":"","url":"./src/components/chat/ChatMessageItem.tsx/~/ChatMessageItemProps.editing.html","deprecated":false},{"id":"namespace_chatmessageitemprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ChatMessageItemProps.onStartEdit","file":"src/components/chat/ChatMessageItem.tsx","doc":"","url":"./src/components/chat/ChatMessageItem.tsx/~/ChatMessageItemProps.onStartEdit.html","deprecated":false},{"id":"namespace_chatmessageitemprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ChatMessageItemProps.onEndEdit","file":"src/components/chat/ChatMessageItem.tsx","doc":"","url":"./src/components/chat/ChatMessageItem.tsx/~/ChatMessageItemProps.onEndEdit.html","deprecated":false},{"id":"namespace_chatmessageitemprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ChatMessageItemProps.onEdit","file":"src/components/chat/ChatMessageItem.tsx","doc":"Called only when the text changed.","url":"./src/components/chat/ChatMessageItem.tsx/~/ChatMessageItemProps.onEdit.html","deprecated":false},{"id":"namespace_chatmessageitemprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ChatMessageItemProps.onDelete","file":"src/components/chat/ChatMessageItem.tsx","doc":"Called once the user has confirmed.","url":"./src/components/chat/ChatMessageItem.tsx/~/ChatMessageItemProps.onDelete.html","deprecated":false},{"id":"namespace_chatmessageitemprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ChatMessageItemProps.onReply","file":"src/components/chat/ChatMessageItem.tsx","doc":"","url":"./src/components/chat/ChatMessageItem.tsx/~/ChatMessageItemProps.onReply.html","deprecated":false},{"id":"namespace_chatmessageitemprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ChatMessageItemProps.onJumpTo","file":"src/components/chat/ChatMessageItem.tsx","doc":"","url":"./src/components/chat/ChatMessageItem.tsx/~/ChatMessageItemProps.onJumpTo.html","deprecated":false},{"id":"namespace_chatmessageitem","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"ChatMessageItem","file":"src/components/chat/ChatMessageItem.tsx","doc":"Renders a chat message, or the editor over its text while editing. Its height eases between the two. Deleting asks for confirmation first.","url":"./src/components/chat/ChatMessageItem.tsx/~/ChatMessageItem.html","deprecated":false},{"id":"namespace_chatmodalprops","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"ChatModalProps","file":"src/components/chat/ChatModal.tsx","doc":"Passed to ChatModal by ChatProvider.","url":"./src/components/chat/ChatModal.tsx/~/ChatModalProps.html","deprecated":false},{"id":"namespace_chatmodalprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ChatModalProps.onClose","file":"src/components/chat/ChatModal.tsx","doc":"Closes the chat, and drops the ?chat= deep link if there is one.","url":"./src/components/chat/ChatModal.tsx/~/ChatModalProps.onClose.html","deprecated":false},{"id":"namespace_chatmodalprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ChatModalProps.focusId","file":"src/components/chat/ChatModal.tsx","doc":"The message to open on, from a ?chat= deep link. Ignored when it isn't in the first page of history.","url":"./src/components/chat/ChatModal.tsx/~/ChatModalProps.focusId.html","deprecated":false},{"id":"namespace_chatmodal","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"ChatModal","file":"src/components/chat/ChatModal.tsx","doc":"Renders the chat, opening on focusId's message, or on the \"new\" divider, when it is more than a screen above the bottom, else at the bottom. Reaching the bottom of a visible tab moves the read marker. The draft and its reply target survive closing and reloading (utils/chat/draft.ts). While it is open in a visible tab, the server sends the user no notification for the mentions they see live.","url":"./src/components/chat/ChatModal.tsx/~/ChatModal.html","deprecated":false},{"id":"namespace_pendingitemprops","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"PendingItemProps","file":"src/components/chat/PendingItem.tsx","doc":"Passed to PendingItem by ChatModal for each of WSChatContext's pendingChatMessages.","url":"./src/components/chat/PendingItem.tsx/~/PendingItemProps.html","deprecated":false},{"id":"namespace_pendingitemprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PendingItemProps.pending","file":"src/components/chat/PendingItem.tsx","doc":"","url":"./src/components/chat/PendingItem.tsx/~/PendingItemProps.pending.html","deprecated":false},{"id":"namespace_pendingitemprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PendingItemProps.grouped","file":"src/components/chat/PendingItem.tsx","doc":"Set when it continues the user's run, which hides the avatar and name.","url":"./src/components/chat/PendingItem.tsx/~/PendingItemProps.grouped.html","deprecated":false},{"id":"namespace_pendingitemprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PendingItemProps.user","file":"src/components/chat/PendingItem.tsx","doc":"The signed-in user, who sent it.","url":"./src/components/chat/PendingItem.tsx/~/PendingItemProps.user.html","deprecated":false},{"id":"namespace_pendingitemprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PendingItemProps.onRetry","file":"src/components/chat/PendingItem.tsx","doc":"","url":"./src/components/chat/PendingItem.tsx/~/PendingItemProps.onRetry.html","deprecated":false},{"id":"namespace_pendingitemprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PendingItemProps.onDiscard","file":"src/components/chat/PendingItem.tsx","doc":"","url":"./src/components/chat/PendingItem.tsx/~/PendingItemProps.onDiscard.html","deprecated":false},{"id":"namespace_pendingitemprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PendingItemProps.onRestore","file":"src/components/chat/PendingItem.tsx","doc":"Takes the failed text back into the composer, and discards it.","url":"./src/components/chat/PendingItem.tsx/~/PendingItemProps.onRestore.html","deprecated":false},{"id":"namespace_pendingitemprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PendingItemProps.onJumpTo","file":"src/components/chat/PendingItem.tsx","doc":"","url":"./src/components/chat/PendingItem.tsx/~/PendingItemProps.onJumpTo.html","deprecated":false},{"id":"namespace_pendingitem","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"PendingItem","file":"src/components/chat/PendingItem.tsx","doc":"Renders a pending message, dimmed while it is sending. Once it has failed, it shows why and offers to retry it, edit it in the composer, or discard it.","url":"./src/components/chat/PendingItem.tsx/~/PendingItem.html","deprecated":false},{"id":"namespace_replyrefprops","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"ReplyRefProps","file":"src/components/chat/ReplyRef.tsx","doc":"Passed to ReplyRef by ChatMessageItem, from the message's replyTo* fields, and by PendingItem, from its replyTo.","url":"./src/components/chat/ReplyRef.tsx/~/ReplyRefProps.html","deprecated":false},{"id":"namespace_replyrefprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ReplyRefProps.replyToId","file":"src/components/chat/ReplyRef.tsx","doc":"","url":"./src/components/chat/ReplyRef.tsx/~/ReplyRefProps.replyToId.html","deprecated":false},{"id":"namespace_replyrefprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ReplyRefProps.author","file":"src/components/chat/ReplyRef.tsx","doc":"Undefined when the replied-to message was deleted.","url":"./src/components/chat/ReplyRef.tsx/~/ReplyRefProps.author.html","deprecated":false},{"id":"namespace_replyrefprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ReplyRefProps.body","file":"src/components/chat/ReplyRef.tsx","doc":"Possibly cut short by the server, as replyToBody is.","url":"./src/components/chat/ReplyRef.tsx/~/ReplyRefProps.body.html","deprecated":false},{"id":"namespace_replyrefprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ReplyRefProps.onJumpTo","file":"src/components/chat/ReplyRef.tsx","doc":"","url":"./src/components/chat/ReplyRef.tsx/~/ReplyRefProps.onJumpTo.html","deprecated":false},{"id":"namespace_replyref","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"ReplyRef","file":"src/components/chat/ReplyRef.tsx","doc":"Renders the replied-to message's author and a one-line snippet of its text, as a button that scrolls to it. When it was deleted, the button is disabled and says so.","url":"./src/components/chat/ReplyRef.tsx/~/ReplyRef.html","deprecated":false},{"id":"namespace_commentformprops","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"CommentFormProps","file":"src/components/comment/CommentForm.tsx","doc":"Passed to CommentForm by CommentThread, for a new comment, and by CommentNode, for a reply.","url":"./src/components/comment/CommentForm.tsx/~/CommentFormProps.html","deprecated":false},{"id":"namespace_commentformprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommentFormProps.onSubmit","file":"src/components/comment/CommentForm.tsx","doc":"Sends the text. The form empties itself once it resolves. When it throws, as expectOk does, the form keeps the text and shows the error under errorTitle.","url":"./src/components/comment/CommentForm.tsx/~/CommentFormProps.onSubmit.html","deprecated":false},{"id":"namespace_commentformprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommentFormProps.submitLabel","file":"src/components/comment/CommentForm.tsx","doc":"","url":"./src/components/comment/CommentForm.tsx/~/CommentFormProps.submitLabel.html","deprecated":false},{"id":"namespace_commentformprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommentFormProps.pendingLabel","file":"src/components/comment/CommentForm.tsx","doc":"","url":"./src/components/comment/CommentForm.tsx/~/CommentFormProps.pendingLabel.html","deprecated":false},{"id":"namespace_commentformprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommentFormProps.errorTitle","file":"src/components/comment/CommentForm.tsx","doc":"","url":"./src/components/comment/CommentForm.tsx/~/CommentFormProps.errorTitle.html","deprecated":false},{"id":"namespace_commentformprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommentFormProps.placeholder","file":"src/components/comment/CommentForm.tsx","doc":"","url":"./src/components/comment/CommentForm.tsx/~/CommentFormProps.placeholder.html","deprecated":false},{"id":"namespace_commentformprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommentFormProps.onCancel","file":"src/components/comment/CommentForm.tsx","doc":"Without it, the form has no Cancel button.","url":"./src/components/comment/CommentForm.tsx/~/CommentFormProps.onCancel.html","deprecated":false},{"id":"namespace_commentformprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommentFormProps.cancelWhenEmpty","file":"src/components/comment/CommentForm.tsx","doc":"Shows Cancel only once there is text to throw away, and doesn't cancel on Escape. For the new-comment form, which has nothing to close.","url":"./src/components/comment/CommentForm.tsx/~/CommentFormProps.cancelWhenEmpty.html","deprecated":false},{"id":"namespace_commentformprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommentFormProps.editorRef","file":"src/components/comment/CommentForm.tsx","doc":"","url":"./src/components/comment/CommentForm.tsx/~/CommentFormProps.editorRef.html","deprecated":false},{"id":"namespace_commentformprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommentFormProps.layout","file":"src/components/comment/CommentForm.tsx","doc":"top puts leading beside the editor, for the new-comment form. inline is for replies, inside a comment.","url":"./src/components/comment/CommentForm.tsx/~/CommentFormProps.layout.html","deprecated":false},{"id":"namespace_commentformprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommentFormProps.leading","file":"src/components/comment/CommentForm.tsx","doc":"","url":"./src/components/comment/CommentForm.tsx/~/CommentFormProps.leading.html","deprecated":false},{"id":"namespace_commentformprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommentFormProps.className","file":"src/components/comment/CommentForm.tsx","doc":"Applies to the inline layout only.","url":"./src/components/comment/CommentForm.tsx/~/CommentFormProps.className.html","deprecated":false},{"id":"namespace_commentform","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"CommentForm","file":"src/components/comment/CommentForm.tsx","doc":"Renders a comment editor and its submit button, disabled while the text is blank or longer than VALIDATION.COMMENT_BODY_MAX.","url":"./src/components/comment/CommentForm.tsx/~/CommentForm.html","deprecated":false},{"id":"namespace_commentnodeprops","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"CommentNodeProps","file":"src/components/comment/CommentNode.tsx","doc":"Passed to CommentNode by CommentThread for each top-level comment, and by CommentNode for each reply. The callbacks are CommentThread's, passed down unchanged.","url":"./src/components/comment/CommentNode.tsx/~/CommentNodeProps.html","deprecated":false},{"id":"namespace_commentnodeprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommentNodeProps.comment","file":"src/components/comment/CommentNode.tsx","doc":"","url":"./src/components/comment/CommentNode.tsx/~/CommentNodeProps.comment.html","deprecated":false},{"id":"namespace_commentnodeprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommentNodeProps.tree","file":"src/components/comment/CommentNode.tsx","doc":"The replies of every comment, by parent id, from CommentThread.","url":"./src/components/comment/CommentNode.tsx/~/CommentNodeProps.tree.html","deprecated":false},{"id":"namespace_commentnodeprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommentNodeProps.depth","file":"src/components/comment/CommentNode.tsx","doc":"Sets the replies' --depth: the deeper, the narrower their indent.","url":"./src/components/comment/CommentNode.tsx/~/CommentNodeProps.depth.html","deprecated":false},{"id":"namespace_commentnodeprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommentNodeProps.dumpId","file":"src/components/comment/CommentNode.tsx","doc":"","url":"./src/components/comment/CommentNode.tsx/~/CommentNodeProps.dumpId.html","deprecated":false},{"id":"namespace_commentnodeprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommentNodeProps.currentUser","file":"src/components/comment/CommentNode.tsx","doc":"","url":"./src/components/comment/CommentNode.tsx/~/CommentNodeProps.currentUser.html","deprecated":false},{"id":"namespace_commentnodeprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommentNodeProps.onCommentCreated","file":"src/components/comment/CommentNode.tsx","doc":"","url":"./src/components/comment/CommentNode.tsx/~/CommentNodeProps.onCommentCreated.html","deprecated":false},{"id":"namespace_commentnodeprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommentNodeProps.onCommentDeleted","file":"src/components/comment/CommentNode.tsx","doc":"","url":"./src/components/comment/CommentNode.tsx/~/CommentNodeProps.onCommentDeleted.html","deprecated":false},{"id":"namespace_commentnodeprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommentNodeProps.onCommentUpdated","file":"src/components/comment/CommentNode.tsx","doc":"","url":"./src/components/comment/CommentNode.tsx/~/CommentNodeProps.onCommentUpdated.html","deprecated":false},{"id":"namespace_commentnode","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"CommentNode","file":"src/components/comment/CommentNode.tsx","doc":"Renders a comment with its like button, and the reply, edit and delete actions for whoever may use them. Its author and moderators may edit and delete it. A deleted comment shows as \"[deleted]\", with its replies. The element's id, comment-, is the anchor notifications link to.","url":"./src/components/comment/CommentNode.tsx/~/CommentNode.html","deprecated":false},{"id":"namespace_commentthreadprops","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"CommentThreadProps","file":"src/components/comment/CommentThread.tsx","doc":"Passed to CommentThread by the Dump page, which holds the comments. The page applies the changes this user makes through the callbacks, and the ones others make from the socket's comment events, so a change can come both ways and must be applied once.","url":"./src/components/comment/CommentThread.tsx/~/CommentThreadProps.html","deprecated":false},{"id":"namespace_commentthreadprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommentThreadProps.dumpId","file":"src/components/comment/CommentThread.tsx","doc":"","url":"./src/components/comment/CommentThread.tsx/~/CommentThreadProps.dumpId.html","deprecated":false},{"id":"namespace_commentthreadprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommentThreadProps.comments","file":"src/components/comment/CommentThread.tsx","doc":"Every comment on the dump, flat and oldest first, deleted ones included so their replies keep their place.","url":"./src/components/comment/CommentThread.tsx/~/CommentThreadProps.comments.html","deprecated":false},{"id":"namespace_commentthreadprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommentThreadProps.currentUser","file":"src/components/comment/CommentThread.tsx","doc":"","url":"./src/components/comment/CommentThread.tsx/~/CommentThreadProps.currentUser.html","deprecated":false},{"id":"namespace_commentthreadprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommentThreadProps.onCommentCreated","file":"src/components/comment/CommentThread.tsx","doc":"","url":"./src/components/comment/CommentThread.tsx/~/CommentThreadProps.onCommentCreated.html","deprecated":false},{"id":"namespace_commentthreadprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommentThreadProps.onCommentDeleted","file":"src/components/comment/CommentThread.tsx","doc":"","url":"./src/components/comment/CommentThread.tsx/~/CommentThreadProps.onCommentDeleted.html","deprecated":false},{"id":"namespace_commentthreadprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CommentThreadProps.onCommentUpdated","file":"src/components/comment/CommentThread.tsx","doc":"","url":"./src/components/comment/CommentThread.tsx/~/CommentThreadProps.onCommentUpdated.html","deprecated":false},{"id":"namespace_commentthread","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"CommentThread","file":"src/components/comment/CommentThread.tsx","doc":"Renders the comment count, the form that posts a comment when someone is signed in, and the tree of CommentNode.","url":"./src/components/comment/CommentThread.tsx/~/CommentThread.html","deprecated":false},{"id":"namespace_dumpcardprops","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"DumpCardProps","file":"src/components/dump/DumpCard.tsx","doc":"Passed to DumpCard by each list of dumps. The vote state comes from the parent, usually WSContext's passed down through the feed's props.","url":"./src/components/dump/DumpCard.tsx/~/DumpCardProps.html","deprecated":false},{"id":"namespace_dumpcardprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DumpCardProps.dump","file":"src/components/dump/DumpCard.tsx","doc":"","url":"./src/components/dump/DumpCard.tsx/~/DumpCardProps.dump.html","deprecated":false},{"id":"namespace_dumpcardprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DumpCardProps.voteCount","file":"src/components/dump/DumpCard.tsx","doc":"The socket's live count if it has one, else dump.voteCount.","url":"./src/components/dump/DumpCard.tsx/~/DumpCardProps.voteCount.html","deprecated":false},{"id":"namespace_dumpcardprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DumpCardProps.voted","file":"src/components/dump/DumpCard.tsx","doc":"","url":"./src/components/dump/DumpCard.tsx/~/DumpCardProps.voted.html","deprecated":false},{"id":"namespace_dumpcardprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DumpCardProps.canVote","file":"src/components/dump/DumpCard.tsx","doc":"","url":"./src/components/dump/DumpCard.tsx/~/DumpCardProps.canVote.html","deprecated":false},{"id":"namespace_dumpcardprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DumpCardProps.castVote","file":"src/components/dump/DumpCard.tsx","doc":"","url":"./src/components/dump/DumpCard.tsx/~/DumpCardProps.castVote.html","deprecated":false},{"id":"namespace_dumpcardprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DumpCardProps.removeVote","file":"src/components/dump/DumpCard.tsx","doc":"","url":"./src/components/dump/DumpCard.tsx/~/DumpCardProps.removeVote.html","deprecated":false},{"id":"namespace_dumpcardprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DumpCardProps.className","file":"src/components/dump/DumpCard.tsx","doc":"","url":"./src/components/dump/DumpCard.tsx/~/DumpCardProps.className.html","deprecated":false},{"id":"namespace_dumpcardprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DumpCardProps.isOwner","file":"src/components/dump/DumpCard.tsx","doc":"Hides the unread dot and shows the \"private\" badge.","url":"./src/components/dump/DumpCard.tsx/~/DumpCardProps.isOwner.html","deprecated":false},{"id":"namespace_dumpcard","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"DumpCard","file":"src/components/dump/DumpCard.tsx","doc":"Renders a dump as a card that opens the dump when clicked. A ctrl-click or middle click opens it in a new tab (useDumpCardLink). The card is an
, for a
. It is memoized because feeds re-render on every live event, so its vote callbacks must be stable (WSContext's are).","url":"./src/components/dump/DumpCard.tsx/~/DumpCard.html","deprecated":false},{"id":"namespace_livedumpcardprops","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"LiveDumpCardProps","file":"src/components/dump/DumpCardList.tsx","doc":"Passed to LiveDumpCard by DumpCardList, and by PlaylistDumpList, which wraps each card in its drag handle and buttons.","url":"./src/components/dump/DumpCardList.tsx/~/LiveDumpCardProps.html","deprecated":false},{"id":"namespace_livedumpcardprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"LiveDumpCardProps.dump","file":"src/components/dump/DumpCardList.tsx","doc":"","url":"./src/components/dump/DumpCardList.tsx/~/LiveDumpCardProps.dump.html","deprecated":false},{"id":"namespace_livedumpcardprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"LiveDumpCardProps.className","file":"src/components/dump/DumpCardList.tsx","doc":"It comes from fadeClassName for a fading card.","url":"./src/components/dump/DumpCardList.tsx/~/LiveDumpCardProps.className.html","deprecated":false},{"id":"namespace_livedumpcard","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"LiveDumpCard","file":"src/components/dump/DumpCardList.tsx","doc":"Renders dump as a DumpCard, an
. The vote counts and calls come from WSContext, a dump missing from its counts showing its fetched voteCount. Voting takes a signed-in user, and a card is its owner's when it is the signed-in user's own dump.","url":"./src/components/dump/DumpCardList.tsx/~/LiveDumpCard.html","deprecated":false},{"id":"namespace_dumpcardlistprops","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"DumpCardListProps","file":"src/components/dump/DumpCardList.tsx","doc":"Passed to DumpCardList by every plain list of dump cards.","url":"./src/components/dump/DumpCardList.tsx/~/DumpCardListProps.html","deprecated":false},{"id":"namespace_dumpcardlistprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DumpCardListProps.dumps","file":"src/components/dump/DumpCardList.tsx","doc":"","url":"./src/components/dump/DumpCardList.tsx/~/DumpCardListProps.dumps.html","deprecated":false},{"id":"namespace_dumpcardlistprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DumpCardListProps.cardClassName","file":"src/components/dump/DumpCardList.tsx","doc":"Gives a card a class, as fadeClassName gives a fading one.","url":"./src/components/dump/DumpCardList.tsx/~/DumpCardListProps.cardClassName.html","deprecated":false},{"id":"namespace_dumpcardlist","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"DumpCardList","file":"src/components/dump/DumpCardList.tsx","doc":"Renders dumps as a .dump-feed of LiveDumpCard.","url":"./src/components/dump/DumpCardList.tsx/~/DumpCardList.html","deprecated":false},{"id":"namespace_filepreviewprops","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"FilePreviewProps","file":"src/components/dump/FilePreview.tsx","doc":"Passed to FilePreview by DumpCard (compact), by Dump (global) and by DumpEdit (neither).","url":"./src/components/dump/FilePreview.tsx/~/FilePreviewProps.html","deprecated":false},{"id":"namespace_filepreviewprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"FilePreviewProps.dump","file":"src/components/dump/FilePreview.tsx","doc":"Expected to be a file dump. A link dump has no fileMime, so it shows as a download.","url":"./src/components/dump/FilePreview.tsx/~/FilePreviewProps.dump.html","deprecated":false},{"id":"namespace_filepreviewprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"FilePreviewProps.compact","file":"src/components/dump/FilePreview.tsx","doc":"Shows a card's thumbnail, whose play button uses the global player.","url":"./src/components/dump/FilePreview.tsx/~/FilePreviewProps.compact.html","deprecated":false},{"id":"namespace_filepreviewprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"FilePreviewProps.global","file":"src/components/dump/FilePreview.tsx","doc":"Plays full-size audio and video in the global player, not inline.","url":"./src/components/dump/FilePreview.tsx/~/FilePreviewProps.global.html","deprecated":false},{"id":"namespace_filepreview","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"FilePreview","file":"src/components/dump/FilePreview.tsx","doc":"Renders an uploaded file by its MIME type. Compact, it is a thumbnail or an icon. Full size, it is the image, a player, the embedded PDF, or a download link for anything else. File URLs carry the viewer's media token, so private files load too.","url":"./src/components/dump/FilePreview.tsx/~/FilePreview.html","deprecated":false},{"id":"namespace_journalcardprops","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"JournalCardProps","file":"src/components/dump/JournalCard.tsx","doc":"Passed to JournalCard by JournalFeed, with the vote state Index takes from WSContext, as for DumpCard.","url":"./src/components/dump/JournalCard.tsx/~/JournalCardProps.html","deprecated":false},{"id":"namespace_journalcardprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"JournalCardProps.dump","file":"src/components/dump/JournalCard.tsx","doc":"","url":"./src/components/dump/JournalCard.tsx/~/JournalCardProps.dump.html","deprecated":false},{"id":"namespace_journalcardprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"JournalCardProps.shape","file":"src/components/dump/JournalCard.tsx","doc":"From composeJournal. It sets the tile's grid span, not its look.","url":"./src/components/dump/JournalCard.tsx/~/JournalCardProps.shape.html","deprecated":false},{"id":"namespace_journalcardprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"JournalCardProps.voteCount","file":"src/components/dump/JournalCard.tsx","doc":"The socket's live count if it has one, else dump.voteCount.","url":"./src/components/dump/JournalCard.tsx/~/JournalCardProps.voteCount.html","deprecated":false},{"id":"namespace_journalcardprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"JournalCardProps.voted","file":"src/components/dump/JournalCard.tsx","doc":"","url":"./src/components/dump/JournalCard.tsx/~/JournalCardProps.voted.html","deprecated":false},{"id":"namespace_journalcardprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"JournalCardProps.canVote","file":"src/components/dump/JournalCard.tsx","doc":"","url":"./src/components/dump/JournalCard.tsx/~/JournalCardProps.canVote.html","deprecated":false},{"id":"namespace_journalcardprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"JournalCardProps.castVote","file":"src/components/dump/JournalCard.tsx","doc":"","url":"./src/components/dump/JournalCard.tsx/~/JournalCardProps.castVote.html","deprecated":false},{"id":"namespace_journalcardprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"JournalCardProps.removeVote","file":"src/components/dump/JournalCard.tsx","doc":"","url":"./src/components/dump/JournalCard.tsx/~/JournalCardProps.removeVote.html","deprecated":false},{"id":"namespace_journalcardprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"JournalCardProps.isOwner","file":"src/components/dump/JournalCard.tsx","doc":"Hides the unread dot and shows the \"private\" badge.","url":"./src/components/dump/JournalCard.tsx/~/JournalCardProps.isOwner.html","deprecated":false},{"id":"namespace_journalcard","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"JournalCard","file":"src/components/dump/JournalCard.tsx","doc":"Renders a dump as an image, a pull-quote or a text tile, depending on whether it has a thumbnail or a note. Clicking an image tile plays its media when it can, a link's or an uploaded audio or video file, and pauses a file once it plays; any other tile opens the dump. It is memoized like DumpCard, so its vote callbacks must be stable.","url":"./src/components/dump/JournalCard.tsx/~/JournalCard.html","deprecated":false},{"id":"namespace_newdumpbutton","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"NewDumpButton","file":"src/components/dump/NewDumpButton.tsx","doc":"Renders a \"+ New dump\" button, as NewPlaylistButton does for playlists, that opens DumpCreateModal. The modal hands the new dump to WSContext itself, so the button takes no callback.","url":"./src/components/dump/NewDumpButton.tsx/~/NewDumpButton.html","deprecated":false},{"id":"namespace_richcontentcardprops","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"RichContentCardProps","file":"src/components/dump/RichContentCard.tsx","doc":"Passed to RichContentCard by DumpCard (compact), Dump, DumpEdit and DumpCreateModal, the last two without a dump to play from.","url":"./src/components/dump/RichContentCard.tsx/~/RichContentCardProps.html","deprecated":false},{"id":"namespace_richcontentcardprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"RichContentCardProps.richContent","file":"src/components/dump/RichContentCard.tsx","doc":"","url":"./src/components/dump/RichContentCard.tsx/~/RichContentCardProps.richContent.html","deprecated":false},{"id":"namespace_richcontentcardprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"RichContentCardProps.compact","file":"src/components/dump/RichContentCard.tsx","doc":"Shows a card's thumbnail alone, as a play button or a link out.","url":"./src/components/dump/RichContentCard.tsx/~/RichContentCardProps.compact.html","deprecated":false},{"id":"namespace_richcontentcardprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"RichContentCardProps.thumbnailOverrideUrl","file":"src/components/dump/RichContentCard.tsx","doc":"The dump's uploaded thumbnail, shown instead of the provider's and used as the player's artwork.","url":"./src/components/dump/RichContentCard.tsx/~/RichContentCardProps.thumbnailOverrideUrl.html","deprecated":false},{"id":"namespace_richcontentcardprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"RichContentCardProps.dumpHref","file":"src/components/dump/RichContentCard.tsx","doc":"The dump's page, which the global player's title links to.","url":"./src/components/dump/RichContentCard.tsx/~/RichContentCardProps.dumpHref.html","deprecated":false},{"id":"namespace_richcontentcard","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"RichContentCard","file":"src/components/dump/RichContentCard.tsx","doc":"Renders a link's preview. Its thumbnail plays the media in the global player when it can be played, and otherwise opens the link in a new tab. Full size, it also shows the site, title and description, linking out.","url":"./src/components/dump/RichContentCard.tsx/~/RichContentCard.html","deprecated":false},{"id":"namespace_dumpcreatemodalprops","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"DumpCreateModalProps","file":"src/components/dump/create/DumpCreateModal.tsx","doc":"Passed to DumpCreateModal by the button that opens it. The parent unmounts the modal on onClose, which the modal also calls after a confirmed dismissal.","url":"./src/components/dump/create/DumpCreateModal.tsx/~/DumpCreateModalProps.html","deprecated":false},{"id":"namespace_dumpcreatemodalprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DumpCreateModalProps.onClose","file":"src/components/dump/create/DumpCreateModal.tsx","doc":"","url":"./src/components/dump/create/DumpCreateModal.tsx/~/DumpCreateModalProps.onClose.html","deprecated":false},{"id":"namespace_dumpcreatemodalprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DumpCreateModalProps.initialUrl","file":"src/components/dump/create/DumpCreateModal.tsx","doc":"A link shared from Android's share sheet, which AppHeader passes on from Index. It replaces any saved draft.","url":"./src/components/dump/create/DumpCreateModal.tsx/~/DumpCreateModalProps.initialUrl.html","deprecated":false},{"id":"namespace_dumpcreatemodal","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"DumpCreateModal","file":"src/components/dump/create/DumpCreateModal.tsx","doc":"Renders the dump creation modal. The first panel takes a link, previewed through GET /api/remote/preview and checked against GET /api/dumps?url=, or a file. The second takes the \"why\", categories and visibility, and posts to POST /api/dumps. The third adds the new dump to playlists. The new dump is handed to WSContext's injectDump so the feeds show it at once. Everything but the file is saved as a draft (utils/dump/draft.ts) until it is posted.","url":"./src/components/dump/create/DumpCreateModal.tsx/~/DumpCreateModal.html","deprecated":false},{"id":"namespace_duplicatenoticeprops","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"DuplicateNoticeProps","file":"src/components/dump/create/DuplicateNotice.tsx","doc":"Passed to DuplicateNotice by DumpCreateModal, with the matches of GET /api/dumps?url=.","url":"./src/components/dump/create/DuplicateNotice.tsx/~/DuplicateNoticeProps.html","deprecated":false},{"id":"namespace_duplicatenoticeprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DuplicateNoticeProps.matches","file":"src/components/dump/create/DuplicateNotice.tsx","doc":"Non-empty, latest first: the notice links the first one.","url":"./src/components/dump/create/DuplicateNotice.tsx/~/DuplicateNoticeProps.matches.html","deprecated":false},{"id":"namespace_duplicatenoticeprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DuplicateNoticeProps.onNavigate","file":"src/components/dump/create/DuplicateNotice.tsx","doc":"Closes the modal when the poster follows the link.","url":"./src/components/dump/create/DuplicateNotice.tsx/~/DuplicateNoticeProps.onNavigate.html","deprecated":false},{"id":"namespace_duplicatenotice","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"DuplicateNotice","file":"src/components/dump/create/DuplicateNotice.tsx","doc":"Renders the \"already dumped\" hint. It doesn't block posting, since a repost is sometimes on purpose.","url":"./src/components/dump/create/DuplicateNotice.tsx/~/DuplicateNotice.html","deprecated":false},{"id":"namespace_localfilepreviewprops","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"LocalFilePreviewProps","file":"src/components/dump/create/LocalFilePreview.tsx","doc":"Passed to LocalFilePreview by DumpCreateModal.","url":"./src/components/dump/create/LocalFilePreview.tsx/~/LocalFilePreviewProps.html","deprecated":false},{"id":"namespace_localfilepreviewprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"LocalFilePreviewProps.file","file":"src/components/dump/create/LocalFilePreview.tsx","doc":"","url":"./src/components/dump/create/LocalFilePreview.tsx/~/LocalFilePreviewProps.file.html","deprecated":false},{"id":"namespace_localfilepreview","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"LocalFilePreview","file":"src/components/dump/create/LocalFilePreview.tsx","doc":"Renders an image, video or audio file from a blob URL, which it revokes when file changes or it unmounts. Any other file renders nothing.","url":"./src/components/dump/create/LocalFilePreview.tsx/~/LocalFilePreview.html","deprecated":false},{"id":"namespace_step","kind":[{"char":"T","kind":"TypeAlias","title":"Type Alias"}],"name":"Step","file":"src/components/dump/create/StepIndicator.tsx","doc":"A panel of DumpCreateModal, in the order they are walked. Categories and visibility have a panel of their own, \"details\", because behind a disclosure they went untouched.","url":"./src/components/dump/create/StepIndicator.tsx/~/Step.html","deprecated":false},{"id":"namespace_stepindicatorprops","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"StepIndicatorProps","file":"src/components/dump/create/StepIndicator.tsx","doc":"Passed to StepIndicator by DumpCreateModal.","url":"./src/components/dump/create/StepIndicator.tsx/~/StepIndicatorProps.html","deprecated":false},{"id":"namespace_stepindicatorprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"StepIndicatorProps.current","file":"src/components/dump/create/StepIndicator.tsx","doc":"","url":"./src/components/dump/create/StepIndicator.tsx/~/StepIndicatorProps.current.html","deprecated":false},{"id":"namespace_stepindicator","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"StepIndicator","file":"src/components/dump/create/StepIndicator.tsx","doc":"Renders the three panels as numbered steps, the passed ones ticked.","url":"./src/components/dump/create/StepIndicator.tsx/~/StepIndicator.html","deprecated":false},{"id":"namespace_titlefieldprops","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"TitleFieldProps","file":"src/components/dump/create/TitleField.tsx","doc":"Passed to TitleField by DumpCreateModal, which owns the editing state: it marks the title as the poster's own on onEdit.","url":"./src/components/dump/create/TitleField.tsx/~/TitleFieldProps.html","deprecated":false},{"id":"namespace_titlefieldprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"TitleFieldProps.registration","file":"src/components/dump/create/TitleField.tsx","doc":"","url":"./src/components/dump/create/TitleField.tsx/~/TitleFieldProps.registration.html","deprecated":false},{"id":"namespace_titlefieldprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"TitleFieldProps.editing","file":"src/components/dump/create/TitleField.tsx","doc":"","url":"./src/components/dump/create/TitleField.tsx/~/TitleFieldProps.editing.html","deprecated":false},{"id":"namespace_titlefieldprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"TitleFieldProps.onEdit","file":"src/components/dump/create/TitleField.tsx","doc":"","url":"./src/components/dump/create/TitleField.tsx/~/TitleFieldProps.onEdit.html","deprecated":false},{"id":"namespace_titlefieldprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"TitleFieldProps.onReset","file":"src/components/dump/create/TitleField.tsx","doc":"Puts the suggested title back. Without it, no reset button shows.","url":"./src/components/dump/create/TitleField.tsx/~/TitleFieldProps.onReset.html","deprecated":false},{"id":"namespace_titlefieldprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"TitleFieldProps.disabled","file":"src/components/dump/create/TitleField.tsx","doc":"","url":"./src/components/dump/create/TitleField.tsx/~/TitleFieldProps.disabled.html","deprecated":false},{"id":"namespace_titlefield","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"TitleField","file":"src/components/dump/create/TitleField.tsx","doc":"Renders the title of a link or file dump. The suggested title, from the link's preview or the file's name, stays read-only until the ✎ button is pressed, so stray typing can't change it.","url":"./src/components/dump/create/TitleField.tsx/~/TitleField.html","deprecated":false},{"id":"namespace_emojipickerpopupprops","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"EmojiPickerPopupProps","file":"src/components/editor/EmojiPickerPopup.tsx","doc":"Passed to EmojiPickerPopup by TextEditor, which keeps the refs to detect outside presses, focus the search and step the keyboard into the grid.","url":"./src/components/editor/EmojiPickerPopup.tsx/~/EmojiPickerPopupProps.html","deprecated":false},{"id":"namespace_emojipickerpopupprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"EmojiPickerPopupProps.floatRef","file":"src/components/editor/EmojiPickerPopup.tsx","doc":"","url":"./src/components/editor/EmojiPickerPopup.tsx/~/EmojiPickerPopupProps.floatRef.html","deprecated":false},{"id":"namespace_emojipickerpopupprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"EmojiPickerPopupProps.searchRef","file":"src/components/editor/EmojiPickerPopup.tsx","doc":"","url":"./src/components/editor/EmojiPickerPopup.tsx/~/EmojiPickerPopupProps.searchRef.html","deprecated":false},{"id":"namespace_emojipickerpopupprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"EmojiPickerPopupProps.viewportRef","file":"src/components/editor/EmojiPickerPopup.tsx","doc":"Focused by TextEditor to hand the arrow keys to frimousse.","url":"./src/components/editor/EmojiPickerPopup.tsx/~/EmojiPickerPopupProps.viewportRef.html","deprecated":false},{"id":"namespace_emojipickerpopupprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"EmojiPickerPopupProps.style","file":"src/components/editor/EmojiPickerPopup.tsx","doc":"From useAnchoredFloat, or hidden until it has placed the picker.","url":"./src/components/editor/EmojiPickerPopup.tsx/~/EmojiPickerPopupProps.style.html","deprecated":false},{"id":"namespace_emojipickerpopupprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"EmojiPickerPopupProps.inline","file":"src/components/editor/EmojiPickerPopup.tsx","doc":"Set for a :query typed in the textarea. The search field then only mirrors query and can't take focus.","url":"./src/components/editor/EmojiPickerPopup.tsx/~/EmojiPickerPopupProps.inline.html","deprecated":false},{"id":"namespace_emojipickerpopupprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"EmojiPickerPopupProps.query","file":"src/components/editor/EmojiPickerPopup.tsx","doc":"","url":"./src/components/editor/EmojiPickerPopup.tsx/~/EmojiPickerPopupProps.query.html","deprecated":false},{"id":"namespace_emojipickerpopupprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"EmojiPickerPopupProps.onQueryChange","file":"src/components/editor/EmojiPickerPopup.tsx","doc":"","url":"./src/components/editor/EmojiPickerPopup.tsx/~/EmojiPickerPopupProps.onQueryChange.html","deprecated":false},{"id":"namespace_emojipickerpopupprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"EmojiPickerPopupProps.onSelect","file":"src/components/editor/EmojiPickerPopup.tsx","doc":"","url":"./src/components/editor/EmojiPickerPopup.tsx/~/EmojiPickerPopupProps.onSelect.html","deprecated":false},{"id":"namespace_emojipickerpopupprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"EmojiPickerPopupProps.onClose","file":"src/components/editor/EmojiPickerPopup.tsx","doc":"","url":"./src/components/editor/EmojiPickerPopup.tsx/~/EmojiPickerPopupProps.onClose.html","deprecated":false},{"id":"namespace_emojipickerpopupprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"EmojiPickerPopupProps.onKeyDownCapture","file":"src/components/editor/EmojiPickerPopup.tsx","doc":"Runs before frimousse sees the key, so it can take Escape and Enter.","url":"./src/components/editor/EmojiPickerPopup.tsx/~/EmojiPickerPopupProps.onKeyDownCapture.html","deprecated":false},{"id":"namespace_emojipickerpopup","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"EmojiPickerPopup","file":"src/components/editor/EmojiPickerPopup.tsx","doc":"Renders the picker in the current locale, with the skin tone last picked on this device. It fetches its emoji data from the site itself, where the Vite build copies it (VITE_EMOJIBASE_URL).","url":"./src/components/editor/EmojiPickerPopup.tsx/~/EmojiPickerPopup.html","deprecated":false},{"id":"namespace_markdownprops","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"MarkdownProps","file":"src/components/editor/Markdown.tsx","doc":"Passed to Markdown by any component that shows a user's text.","url":"./src/components/editor/Markdown.tsx/~/MarkdownProps.html","deprecated":false},{"id":"namespace_markdownprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"MarkdownProps.children","file":"src/components/editor/Markdown.tsx","doc":"","url":"./src/components/editor/Markdown.tsx/~/MarkdownProps.children.html","deprecated":false},{"id":"namespace_markdownprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"MarkdownProps.className","file":"src/components/editor/Markdown.tsx","doc":"","url":"./src/components/editor/Markdown.tsx/~/MarkdownProps.className.html","deprecated":false},{"id":"namespace_markdownprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"MarkdownProps.inline","file":"src/components/editor/Markdown.tsx","doc":"Drops the images, for a line-clamped teaser in a card, where an image would break the layout. The full text is one click away.","url":"./src/components/editor/Markdown.tsx/~/MarkdownProps.inline.html","deprecated":false},{"id":"namespace_markdownprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"MarkdownProps.everyone","file":"src/components/editor/Markdown.tsx","doc":"Shows @everyone as a mention, from a chat message's mentionsEveryone. Without it, @everyone is plain text: anyone may type it, and it reaches no one.","url":"./src/components/editor/Markdown.tsx/~/MarkdownProps.everyone.html","deprecated":false},{"id":"namespace_markdown","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"Markdown","file":"src/components/editor/Markdown.tsx","doc":"Renders GFM with @mentions as profile links and single newlines kept. It is memoized because parsing runs the whole remark pipeline, and the text rarely changes when its parent re-renders.","url":"./src/components/editor/Markdown.tsx/~/Markdown.html","deprecated":false},{"id":"namespace_mentiondropdownprops","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"MentionDropdownProps","file":"src/components/editor/MentionDropdown.tsx","doc":"Passed to MentionDropdown by TextEditor, from the state of useMentionAutocomplete.","url":"./src/components/editor/MentionDropdown.tsx/~/MentionDropdownProps.html","deprecated":false},{"id":"namespace_mentiondropdownprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"MentionDropdownProps.id","file":"src/components/editor/MentionDropdown.tsx","doc":"The textarea's aria-controls. Option i gets the id ${id}-${i}, which the textarea names as its aria-activedescendant.","url":"./src/components/editor/MentionDropdown.tsx/~/MentionDropdownProps.id.html","deprecated":false},{"id":"namespace_mentiondropdownprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"MentionDropdownProps.results","file":"src/components/editor/MentionDropdown.tsx","doc":"","url":"./src/components/editor/MentionDropdown.tsx/~/MentionDropdownProps.results.html","deprecated":false},{"id":"namespace_mentiondropdownprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"MentionDropdownProps.selectedIndex","file":"src/components/editor/MentionDropdown.tsx","doc":"","url":"./src/components/editor/MentionDropdown.tsx/~/MentionDropdownProps.selectedIndex.html","deprecated":false},{"id":"namespace_mentiondropdownprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"MentionDropdownProps.onSelect","file":"src/components/editor/MentionDropdown.tsx","doc":"","url":"./src/components/editor/MentionDropdown.tsx/~/MentionDropdownProps.onSelect.html","deprecated":false},{"id":"namespace_mentiondropdownprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"MentionDropdownProps.style","file":"src/components/editor/MentionDropdown.tsx","doc":"From useAnchoredFloat, or hidden until it has placed the list.","url":"./src/components/editor/MentionDropdown.tsx/~/MentionDropdownProps.style.html","deprecated":false},{"id":"namespace_mentiondropdown","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"MentionDropdown","file":"src/components/editor/MentionDropdown.tsx","doc":"Renders the matching users as a listbox, scrolled to keep the highlighted one in view, or nothing when none match. The keyboard stays in the textarea.","url":"./src/components/editor/MentionDropdown.tsx/~/MentionDropdown.html","deprecated":false},{"id":"namespace_texteditorhandle","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"TextEditorHandle","file":"src/components/editor/TextEditor.tsx","doc":"Exposed through the ref of TextEditor, so that the component that opens an editor (a reply, an edit, the chat composer) can focus it.","url":"./src/components/editor/TextEditor.tsx/~/TextEditorHandle.html","deprecated":false},{"id":"namespace_texteditorhandle","kind":[{"char":"m","kind":"Method","title":"Method"}],"name":"TextEditorHandle.focus","file":"src/components/editor/TextEditor.tsx","doc":"Focuses the textarea. atEnd puts the caret after the last character and scrolls the text there. preventScroll leaves the page and its scrollers where they are.","url":"./src/components/editor/TextEditor.tsx/~/TextEditorHandle.focus.html","deprecated":false},{"id":"namespace_texteditorprops","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"TextEditorProps","file":"src/components/editor/TextEditor.tsx","doc":"Passed to TextEditor by the component that owns the text, which keeps it in its state (the editor is controlled).","url":"./src/components/editor/TextEditor.tsx/~/TextEditorProps.html","deprecated":false},{"id":"namespace_texteditorprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"TextEditorProps.value","file":"src/components/editor/TextEditor.tsx","doc":"","url":"./src/components/editor/TextEditor.tsx/~/TextEditorProps.value.html","deprecated":false},{"id":"namespace_texteditorprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"TextEditorProps.onChange","file":"src/components/editor/TextEditor.tsx","doc":"Called on typing, and with the Markdown of the images once uploaded.","url":"./src/components/editor/TextEditor.tsx/~/TextEditorProps.onChange.html","deprecated":false},{"id":"namespace_texteditorprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"TextEditorProps.placeholder","file":"src/components/editor/TextEditor.tsx","doc":"","url":"./src/components/editor/TextEditor.tsx/~/TextEditorProps.placeholder.html","deprecated":false},{"id":"namespace_texteditorprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"TextEditorProps.disabled","file":"src/components/editor/TextEditor.tsx","doc":"","url":"./src/components/editor/TextEditor.tsx/~/TextEditorProps.disabled.html","deprecated":false},{"id":"namespace_texteditorprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"TextEditorProps.rows","file":"src/components/editor/TextEditor.tsx","doc":"","url":"./src/components/editor/TextEditor.tsx/~/TextEditorProps.rows.html","deprecated":false},{"id":"namespace_texteditorprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"TextEditorProps.id","file":"src/components/editor/TextEditor.tsx","doc":"","url":"./src/components/editor/TextEditor.tsx/~/TextEditorProps.id.html","deprecated":false},{"id":"namespace_texteditorprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"TextEditorProps.className","file":"src/components/editor/TextEditor.tsx","doc":"","url":"./src/components/editor/TextEditor.tsx/~/TextEditorProps.className.html","deprecated":false},{"id":"namespace_texteditorprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"TextEditorProps.autoResize","file":"src/components/editor/TextEditor.tsx","doc":"Grows the textarea with its text instead of scrolling it.","url":"./src/components/editor/TextEditor.tsx/~/TextEditorProps.autoResize.html","deprecated":false},{"id":"namespace_texteditorprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"TextEditorProps.onSubmit","file":"src/components/editor/TextEditor.tsx","doc":"Called on Ctrl/Cmd+Enter, but not while an image is still uploading.","url":"./src/components/editor/TextEditor.tsx/~/TextEditorProps.onSubmit.html","deprecated":false},{"id":"namespace_texteditorprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"TextEditorProps.onCancel","file":"src/components/editor/TextEditor.tsx","doc":"Called on Escape when no popup of the editor is left to close. Inline editors (an edit, a reply) pass it to mean \"never mind\".","url":"./src/components/editor/TextEditor.tsx/~/TextEditorProps.onCancel.html","deprecated":false},{"id":"namespace_texteditorprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"TextEditorProps.onKeyDown","file":"src/components/editor/TextEditor.tsx","doc":"Runs after the editor's own keys (autocompletes, Ctrl+Enter), and never while an IME is composing, so an Enter that confirms a candidate isn't taken for \"send\".","url":"./src/components/editor/TextEditor.tsx/~/TextEditorProps.onKeyDown.html","deprecated":false},{"id":"namespace_texteditorprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"TextEditorProps.maxLength","file":"src/components/editor/TextEditor.tsx","doc":"Shows a counter and marks the textarea invalid past it. It doesn't stop the typing, so the caller must still refuse a longer text.","url":"./src/components/editor/TextEditor.tsx/~/TextEditorProps.maxLength.html","deprecated":false},{"id":"namespace_texteditorprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"TextEditorProps.countFrom","file":"src/components/editor/TextEditor.tsx","doc":"The length from which the counter shows, 80% of maxLength by default: a standing \"0 / 5000\" is noise, but the counter should turn up well before the warning colour does.","url":"./src/components/editor/TextEditor.tsx/~/TextEditorProps.countFrom.html","deprecated":false},{"id":"namespace_texteditorprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"TextEditorProps.mentionEveryone","file":"src/components/editor/TextEditor.tsx","doc":"Offers @everyone among the mention suggestions. The chat's composer sets it for a role with chat:everyone, the one place it notifies.","url":"./src/components/editor/TextEditor.tsx/~/TextEditorProps.mentionEveryone.html","deprecated":false},{"id":"namespace_texteditorprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"TextEditorProps.aria-invalid","file":"src/components/editor/TextEditor.tsx","doc":"","url":"./src/components/editor/TextEditor.tsx/~/TextEditorProps.aria-invalid.html","deprecated":false},{"id":"namespace_texteditorprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"TextEditorProps.aria-describedby","file":"src/components/editor/TextEditor.tsx","doc":"Joined with the id of the editor's own upload notice when it shows one.","url":"./src/components/editor/TextEditor.tsx/~/TextEditorProps.aria-describedby.html","deprecated":false},{"id":"namespace_texteditor","kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"TextEditor","file":"src/components/editor/TextEditor.tsx","doc":"Renders a textarea that completes @mentions and :emoji, opens an emoji picker from its button, and counts characters near maxLength. A pasted or dropped image is uploaded to POST /api/attachments with the session's token and inserted as Markdown, so the editor must sit under AuthProvider. The textarea is read-only while an upload runs.","url":"./src/components/editor/TextEditor.tsx/~/TextEditor.html","deprecated":false},{"id":"namespace_federatedsigninprops","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"FederatedSignInProps","file":"src/components/federation/FederatedSignIn.tsx","doc":"Passed to FederatedSignIn by UserLogin and UserRegister.","url":"./src/components/federation/FederatedSignIn.tsx/~/FederatedSignInProps.html","deprecated":false},{"id":"namespace_federatedsigninprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"FederatedSignInProps.inviteToken","file":"src/components/federation/FederatedSignIn.tsx","doc":"The invite the register page was opened with, which lets a user of any instance join; the login page has none, and offers the trusted instances.","url":"./src/components/federation/FederatedSignIn.tsx/~/FederatedSignInProps.inviteToken.html","deprecated":false},{"id":"namespace_federatedsignin","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"FederatedSignIn","file":"src/components/federation/FederatedSignIn.tsx","doc":"Renders a button per trusted instance (GET /api/federation/peers) and a field for any other's address. Either starts the sign-in (POST /api/federation/logins) and leaves for that instance's /authorize page, which sends the user back to /federation/callback.","url":"./src/components/federation/FederatedSignIn.tsx/~/FederatedSignIn.html","deprecated":false},{"id":"namespace_grantlist","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"GrantList","file":"src/components/federation/GrantList.tsx","doc":"Renders each instance (GET /api/me/grants), when it last signed the user in, and a button that withdraws it (DELETE /api/me/grants/:host), which signs them out there; signing in there again asks them again.","url":"./src/components/federation/GrantList.tsx/~/GrantList.html","deprecated":false},{"id":"namespace_peermanager","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"PeerManager","file":"src/components/federation/PeerManager.tsx","doc":"Renders each listed instance with its status, which a click changes (PUT /api/federation/peers), and a button that takes it off the lists (DELETE /api/federation/peers/:host), then a field that adds one. The server checks that it answers as a gerbeur, and the permission again. Without FEDERATION_INCOMING it lists and adds only blocked instances; the trusted ones are kept for when it is back.","url":"./src/components/federation/PeerManager.tsx/~/PeerManager.html","deprecated":false},{"id":"namespace_dumpfeedstate","kind":[{"char":"T","kind":"TypeAlias","title":"Type Alias"}],"name":"DumpFeedState","file":"src/components/feed/DumpFeed.tsx","doc":"Held by usePagedList for Index's feed and for each section of FollowedFeed.","url":"./src/components/feed/DumpFeed.tsx/~/DumpFeedState.html","deprecated":false},{"id":"namespace_mainfeedprops","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"MainFeedProps","file":"src/components/feed/DumpFeed.tsx","doc":"Passed by Index to whichever of the \"hot\", \"new\" and \"journal\" tabs is showing. The tabs share this one state, so switching tabs doesn't refetch.","url":"./src/components/feed/DumpFeed.tsx/~/MainFeedProps.html","deprecated":false},{"id":"namespace_mainfeedprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"MainFeedProps.state","file":"src/components/feed/DumpFeed.tsx","doc":"The tabs read its status and paging, and show dumps instead of its items.","url":"./src/components/feed/DumpFeed.tsx/~/MainFeedProps.state.html","deprecated":false},{"id":"namespace_mainfeedprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"MainFeedProps.dumps","file":"src/components/feed/DumpFeed.tsx","doc":"It holds the loaded dumps, with those WSContext added since and without the deleted ones.","url":"./src/components/feed/DumpFeed.tsx/~/MainFeedProps.dumps.html","deprecated":false},{"id":"namespace_mainfeedprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"MainFeedProps.sentinelRef","file":"src/components/feed/DumpFeed.tsx","doc":"It comes from useInfiniteScroll, and goes after the last card.","url":"./src/components/feed/DumpFeed.tsx/~/MainFeedProps.sentinelRef.html","deprecated":false},{"id":"namespace_dumpfeedprops","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"DumpFeedProps","file":"src/components/feed/DumpFeed.tsx","doc":"Passed to DumpFeed by Index for the \"hot\" and \"new\" tabs. It adds the active tab, as order, to the state all tabs share.","url":"./src/components/feed/DumpFeed.tsx/~/DumpFeedProps.html","deprecated":false},{"id":"namespace_dumpfeedprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DumpFeedProps.order","file":"src/components/feed/DumpFeed.tsx","doc":"","url":"./src/components/feed/DumpFeed.tsx/~/DumpFeedProps.order.html","deprecated":false},{"id":"namespace_dumpfeed","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"DumpFeed","file":"src/components/feed/DumpFeed.tsx","doc":"Renders the \"hot\" and \"new\" tabs as a DumpCardList, sorted on the client, followed by the infinite-scroll sentinel, or the loading, error or empty state. Index is its only user.","url":"./src/components/feed/DumpFeed.tsx/~/DumpFeed.html","deprecated":false},{"id":"namespace_feedfooterprops","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"FeedFooterProps","file":"src/components/feed/FeedFooter.tsx","doc":"Passed to FeedFooter by every list that loads its next page on scroll.","url":"./src/components/feed/FeedFooter.tsx/~/FeedFooterProps.html","deprecated":false},{"id":"namespace_feedfooterprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"FeedFooterProps.hasMore","file":"src/components/feed/FeedFooter.tsx","doc":"","url":"./src/components/feed/FeedFooter.tsx/~/FeedFooterProps.hasMore.html","deprecated":false},{"id":"namespace_feedfooterprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"FeedFooterProps.loadingMore","file":"src/components/feed/FeedFooter.tsx","doc":"","url":"./src/components/feed/FeedFooter.tsx/~/FeedFooterProps.loadingMore.html","deprecated":false},{"id":"namespace_feedfooterprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"FeedFooterProps.sentinelRef","file":"src/components/feed/FeedFooter.tsx","doc":"It comes from useInfiniteScroll.","url":"./src/components/feed/FeedFooter.tsx/~/FeedFooterProps.sentinelRef.html","deprecated":false},{"id":"namespace_feedfooter","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"FeedFooter","file":"src/components/feed/FeedFooter.tsx","doc":"Renders the sentinel while there is more to load, \"Loading more…\" while it loads, and \"You've reached the end.\" once there is no more. The list renders it after a non-empty list only, since an empty list has its own message.","url":"./src/components/feed/FeedFooter.tsx/~/FeedFooter.html","deprecated":false},{"id":"namespace_feedtabbarprops","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"FeedTabBarProps","file":"src/components/feed/FeedTabBar.tsx","doc":"Passed to FeedTabBar by Index, from the URL it renders.","url":"./src/components/feed/FeedTabBar.tsx/~/FeedTabBarProps.html","deprecated":false},{"id":"namespace_feedtabbarprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"FeedTabBarProps.categorySlug","file":"src/components/feed/FeedTabBar.tsx","doc":"The category whose feed is shown, or none for every dump.","url":"./src/components/feed/FeedTabBar.tsx/~/FeedTabBarProps.categorySlug.html","deprecated":false},{"id":"namespace_feedtabbarprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"FeedTabBarProps.tab","file":"src/components/feed/FeedTabBar.tsx","doc":"The tab shown, the viewer's default one on a bare path.","url":"./src/components/feed/FeedTabBar.tsx/~/FeedTabBarProps.tab.html","deprecated":false},{"id":"namespace_feedtabbarprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"FeedTabBarProps.followView","file":"src/components/feed/FeedTabBar.tsx","doc":"The view of the \"follow\" tab, which picking a category keeps.","url":"./src/components/feed/FeedTabBar.tsx/~/FeedTabBarProps.followView.html","deprecated":false},{"id":"namespace_feedtabbar","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"FeedTabBar","file":"src/components/feed/FeedTabBar.tsx","doc":"Renders the \"hot\", \"new\" and \"journal\" tabs, and \"followed\" for a signed-in user. A tab leads to the same scope: /new for every dump, /music/new for a category, and the viewer's default tab to the bare / or /music. A tab is a view of the same page, so it takes the place of the current history entry, while picking a category, another page, adds one and keeps the tab and its view, from /music/follow/playlists to /cinema/follow/playlists. Index renders it twice, in the header and below it, and CSS shows one by screen width.","url":"./src/components/feed/FeedTabBar.tsx/~/FeedTabBar.html","deprecated":false},{"id":"namespace_followedfeedprops","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"FollowedFeedProps","file":"src/components/feed/FollowedFeed.tsx","doc":"Passed to FollowedFeed by Index, which renders the tab for a signed-in user only. Unlike the other tabs, it loads its own dumps.","url":"./src/components/feed/FollowedFeed.tsx/~/FollowedFeedProps.html","deprecated":false},{"id":"namespace_followedfeedprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"FollowedFeedProps.categorySlug","file":"src/components/feed/FollowedFeed.tsx","doc":"Scopes both views to a category.","url":"./src/components/feed/FollowedFeed.tsx/~/FollowedFeedProps.categorySlug.html","deprecated":false},{"id":"namespace_followedfeedprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"FollowedFeedProps.view","file":"src/components/feed/FollowedFeed.tsx","doc":"The view the path names: /follow, or /follow/playlists.","url":"./src/components/feed/FollowedFeed.tsx/~/FollowedFeedProps.view.html","deprecated":false},{"id":"namespace_followedfeed","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"FollowedFeed","file":"src/components/feed/FollowedFeed.tsx","doc":"Renders the \"follow\" tab in two views, \"from people\" at /follow and \"from playlists\" at /follow/playlists, from GET /api/dumps?follow=users and GET /api/dumps?follow=playlists. Both load at once, so switching is instant, and each keeps its own pages, cached like the index's feed. Switching takes the place of the current history entry, as a tab does.","url":"./src/components/feed/FollowedFeed.tsx/~/FollowedFeed.html","deprecated":false},{"id":"namespace_journalfeed","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"JournalFeed","file":"src/components/feed/JournalFeed.tsx","doc":"Renders the feed Index passes as blocks of JournalCard, laid out by composeJournal, followed by the infinite-scroll sentinel, or the loading, error or empty state. The votes come from WSContext.","url":"./src/components/feed/JournalFeed.tsx/~/JournalFeed.html","deprecated":false},{"id":"namespace_presencerowprops","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"PresenceRowProps","file":"src/components/feed/PresenceRow.tsx","doc":"Passed to PresenceRow by Index, which renders one in the header and one below it. Both selectors go to useRoomBeside.","url":"./src/components/feed/PresenceRow.tsx/~/PresenceRowProps.html","deprecated":false},{"id":"namespace_presencerowprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PresenceRowProps.fitWithin","file":"src/components/feed/PresenceRow.tsx","doc":"The ancestor that bounds the row the avatars share.","url":"./src/components/feed/PresenceRow.tsx/~/PresenceRowProps.fitWithin.html","deprecated":false},{"id":"namespace_presencerowprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PresenceRowProps.fitBeside","file":"src/components/feed/PresenceRow.tsx","doc":"The tabs, which keep their width before the avatars get any.","url":"./src/components/feed/PresenceRow.tsx/~/PresenceRowProps.fitBeside.html","deprecated":false},{"id":"namespace_presencerow","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"PresenceRow","file":"src/components/feed/PresenceRow.tsx","doc":"Renders the online users from WSContext as overlapping avatars linking to their profiles, as many as the tabs leave room for, and a \"+N\" counter for the others. It renders nothing when nobody is online.","url":"./src/components/feed/PresenceRow.tsx/~/PresenceRow.html","deprecated":false},{"id":"namespace_deletebuttonprops","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"DeleteButtonProps","file":"src/components/form/DeleteButton.tsx","doc":"Passed to DeleteButton by an edit form.","url":"./src/components/form/DeleteButton.tsx/~/DeleteButtonProps.html","deprecated":false},{"id":"namespace_deletebuttonprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DeleteButtonProps.label","file":"src/components/form/DeleteButton.tsx","doc":"Its accessible name, which names what goes, such as \"Delete dump\".","url":"./src/components/form/DeleteButton.tsx/~/DeleteButtonProps.label.html","deprecated":false},{"id":"namespace_deletebuttonprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"DeleteButtonProps.onClick","file":"src/components/form/DeleteButton.tsx","doc":"Opens the page's confirmation, which deletes.","url":"./src/components/form/DeleteButton.tsx/~/DeleteButtonProps.onClick.html","deprecated":false},{"id":"namespace_deletebutton","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"DeleteButton","file":"src/components/form/DeleteButton.tsx","doc":"Renders a compact \"Delete\" button, at the start of the bar's .form-actions. A bar too narrow for it beside Cancel and Save shows its icon instead (.form-delete-icon).","url":"./src/components/form/DeleteButton.tsx/~/DeleteButton.html","deprecated":false},{"id":"namespace_filedropzoneprops","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"FileDropZoneProps","file":"src/components/form/FileDropZone.tsx","doc":"Passed to FileDropZone by FileField, from the form's state. The zone keeps no file of its own.","url":"./src/components/form/FileDropZone.tsx/~/FileDropZoneProps.html","deprecated":false},{"id":"namespace_filedropzoneprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"FileDropZoneProps.file","file":"src/components/form/FileDropZone.tsx","doc":"","url":"./src/components/form/FileDropZone.tsx/~/FileDropZoneProps.file.html","deprecated":false},{"id":"namespace_filedropzoneprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"FileDropZoneProps.onChange","file":"src/components/form/FileDropZone.tsx","doc":"Called with the file dropped or picked, or with null when it is removed.","url":"./src/components/form/FileDropZone.tsx/~/FileDropZoneProps.onChange.html","deprecated":false},{"id":"namespace_filedropzoneprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"FileDropZoneProps.disabled","file":"src/components/form/FileDropZone.tsx","doc":"","url":"./src/components/form/FileDropZone.tsx/~/FileDropZoneProps.disabled.html","deprecated":false},{"id":"namespace_filedropzoneprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"FileDropZoneProps.hint","file":"src/components/form/FileDropZone.tsx","doc":"Replaces the \"Drop a file here\" prompt.","url":"./src/components/form/FileDropZone.tsx/~/FileDropZoneProps.hint.html","deprecated":false},{"id":"namespace_filedropzoneprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"FileDropZoneProps.maxBytes","file":"src/components/form/FileDropZone.tsx","doc":"Stated under the prompt when showLimit is on. FileField refuses a larger file.","url":"./src/components/form/FileDropZone.tsx/~/FileDropZoneProps.maxBytes.html","deprecated":false},{"id":"namespace_filedropzoneprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"FileDropZoneProps.showLimit","file":"src/components/form/FileDropZone.tsx","doc":"","url":"./src/components/form/FileDropZone.tsx/~/FileDropZoneProps.showLimit.html","deprecated":false},{"id":"namespace_filedropzone","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"FileDropZone","file":"src/components/form/FileDropZone.tsx","doc":"Renders a zone that takes a dropped file, or opens the file picker on a click or Enter. Once a file is chosen, it shows its name and size and a button to remove it. Only the first of several dropped files is kept.","url":"./src/components/form/FileDropZone.tsx/~/FileDropZone.html","deprecated":false},{"id":"namespace_filefieldprops","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"FileFieldProps","file":"src/components/form/FileField.tsx","doc":"Passed to FileField by a dump form. The field it names holds the File itself, or null.","url":"./src/components/form/FileField.tsx/~/FileFieldProps.html","deprecated":false},{"id":"namespace_filefieldprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"FileFieldProps.name","file":"src/components/form/FileField.tsx","doc":"","url":"./src/components/form/FileField.tsx/~/FileFieldProps.name.html","deprecated":false},{"id":"namespace_filefieldprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"FileFieldProps.label","file":"src/components/form/FileField.tsx","doc":"","url":"./src/components/form/FileField.tsx/~/FileFieldProps.label.html","deprecated":false},{"id":"namespace_filefieldprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"FileFieldProps.hint","file":"src/components/form/FileField.tsx","doc":"","url":"./src/components/form/FileField.tsx/~/FileFieldProps.hint.html","deprecated":false},{"id":"namespace_filefieldprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"FileFieldProps.maxBytes","file":"src/components/form/FileField.tsx","doc":"Refuses a larger file, as a field error, as soon as it is picked.","url":"./src/components/form/FileField.tsx/~/FileFieldProps.maxBytes.html","deprecated":false},{"id":"namespace_filefieldprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"FileFieldProps.showLimit","file":"src/components/form/FileField.tsx","doc":"States maxBytes in the drop zone.","url":"./src/components/form/FileField.tsx/~/FileFieldProps.showLimit.html","deprecated":false},{"id":"namespace_filefieldprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"FileFieldProps.disabled","file":"src/components/form/FileField.tsx","doc":"","url":"./src/components/form/FileField.tsx/~/FileFieldProps.disabled.html","deprecated":false},{"id":"namespace_filefieldprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"FileFieldProps.rules","file":"src/components/form/FileField.tsx","doc":"","url":"./src/components/form/FileField.tsx/~/FileFieldProps.rules.html","deprecated":false},{"id":"namespace_filefieldprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"FileFieldProps.onValueChange","file":"src/components/form/FileField.tsx","doc":"Called after the form's value is set, for a side effect such as deriving the title from the file's name.","url":"./src/components/form/FileField.tsx/~/FileFieldProps.onValueChange.html","deprecated":false},{"id":"namespace_filefield","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"FileField","file":"src/components/form/FileField.tsx","doc":"Renders the drop zone with its label and the field's error. It must sit under a react-hook-form FormProvider, such as one given useApiForm's result.","url":"./src/components/form/FileField.tsx/~/FileField.html","deprecated":false},{"id":"namespace_formactionsprops","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"FormActionsProps","file":"src/components/form/FormActions.tsx","doc":"Passed to FormActions by a form, with its submit button as child.","url":"./src/components/form/FormActions.tsx/~/FormActionsProps.html","deprecated":false},{"id":"namespace_formactionsprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"FormActionsProps.children","file":"src/components/form/FormActions.tsx","doc":"","url":"./src/components/form/FormActions.tsx/~/FormActionsProps.children.html","deprecated":false},{"id":"namespace_formactionsprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"FormActionsProps.onCancel","file":"src/components/form/FormActions.tsx","doc":"Adds a Cancel button, which calls it.","url":"./src/components/form/FormActions.tsx/~/FormActionsProps.onCancel.html","deprecated":false},{"id":"namespace_formactionsprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"FormActionsProps.cancelLabel","file":"src/components/form/FormActions.tsx","doc":"Replaces the \"Cancel\" label.","url":"./src/components/form/FormActions.tsx/~/FormActionsProps.cancelLabel.html","deprecated":false},{"id":"namespace_formactionsprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"FormActionsProps.disabled","file":"src/components/form/FormActions.tsx","doc":"Disables the Cancel button only, not the children.","url":"./src/components/form/FormActions.tsx/~/FormActionsProps.disabled.html","deprecated":false},{"id":"namespace_formactions","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"FormActions","file":"src/components/form/FormActions.tsx","doc":"Renders the Cancel button, if any, then the children, aligned right. The Cancel button is type=\"button\", so it never submits the form.","url":"./src/components/form/FormActions.tsx/~/FormActions.html","deprecated":false},{"id":"namespace_formerrorprops","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"FormErrorProps","file":"src/components/form/FormError.tsx","doc":"Passed to FormError by a form, to say what failed.","url":"./src/components/form/FormError.tsx/~/FormErrorProps.html","deprecated":false},{"id":"namespace_formerrorprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"FormErrorProps.title","file":"src/components/form/FormError.tsx","doc":"Replaces the \"Something went wrong\" title.","url":"./src/components/form/FormError.tsx/~/FormErrorProps.title.html","deprecated":false},{"id":"namespace_formerror","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"FormError","file":"src/components/form/FormError.tsx","doc":"Renders the form's root error as an ErrorCard, or nothing without one. useApiForm's submit sets that error when the request fails. It must sit under a react-hook-form FormProvider.","url":"./src/components/form/FormError.tsx/~/FormError.html","deprecated":false},{"id":"namespace_inlineeditprops","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"InlineEditProps","file":"src/components/form/InlineEdit.tsx","doc":"Passed to InlineEdit by the component showing the text, which renders it as children and saves it in onSave.","url":"./src/components/form/InlineEdit.tsx/~/InlineEditProps.html","deprecated":false},{"id":"namespace_inlineeditprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"InlineEditProps.value","file":"src/components/form/InlineEdit.tsx","doc":"The text as saved, which the field opens on.","url":"./src/components/form/InlineEdit.tsx/~/InlineEditProps.value.html","deprecated":false},{"id":"namespace_inlineeditprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"InlineEditProps.editable","file":"src/components/form/InlineEdit.tsx","doc":"Without it, children show alone.","url":"./src/components/form/InlineEdit.tsx/~/InlineEditProps.editable.html","deprecated":false},{"id":"namespace_inlineeditprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"InlineEditProps.label","file":"src/components/form/InlineEdit.tsx","doc":"Names the action, such as \"Edit title\": the text's tooltip.","url":"./src/components/form/InlineEdit.tsx/~/InlineEditProps.label.html","deprecated":false},{"id":"namespace_inlineeditprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"InlineEditProps.onSave","file":"src/components/form/InlineEdit.tsx","doc":"Saves the trimmed text, and shows it: the field closes once it resolves. A thrown error, such as expectOk's, stays open under the field. A text left as it was closes the field without calling it.","url":"./src/components/form/InlineEdit.tsx/~/InlineEditProps.onSave.html","deprecated":false},{"id":"namespace_inlineeditprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"InlineEditProps.kind","file":"src/components/form/InlineEdit.tsx","doc":"A one-line field (text, email), where Enter saves, or the Markdown editor (markdown), where Ctrl/Cmd+Enter does. Escape cancels in both.","url":"./src/components/form/InlineEdit.tsx/~/InlineEditProps.kind.html","deprecated":false},{"id":"namespace_inlineeditprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"InlineEditProps.required","file":"src/components/form/InlineEdit.tsx","doc":"Refuses to save an empty text.","url":"./src/components/form/InlineEdit.tsx/~/InlineEditProps.required.html","deprecated":false},{"id":"namespace_inlineeditprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"InlineEditProps.maxLength","file":"src/components/form/InlineEdit.tsx","doc":"","url":"./src/components/form/InlineEdit.tsx/~/InlineEditProps.maxLength.html","deprecated":false},{"id":"namespace_inlineeditprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"InlineEditProps.placeholder","file":"src/components/form/InlineEdit.tsx","doc":"","url":"./src/components/form/InlineEdit.tsx/~/InlineEditProps.placeholder.html","deprecated":false},{"id":"namespace_inlineeditprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"InlineEditProps.className","file":"src/components/form/InlineEdit.tsx","doc":"Added to the wrapper, which the text and the field both sit in.","url":"./src/components/form/InlineEdit.tsx/~/InlineEditProps.className.html","deprecated":false},{"id":"namespace_inlineeditprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"InlineEditProps.fieldClassName","file":"src/components/form/InlineEdit.tsx","doc":"Added to the field: see InlineEditFieldProps.","url":"./src/components/form/InlineEdit.tsx/~/InlineEditProps.fieldClassName.html","deprecated":false},{"id":"namespace_inlineeditprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"InlineEditProps.children","file":"src/components/form/InlineEdit.tsx","doc":"","url":"./src/components/form/InlineEdit.tsx/~/InlineEditProps.children.html","deprecated":false},{"id":"namespace_inlineedit","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"InlineEdit","file":"src/components/form/InlineEdit.tsx","doc":"Renders children, which a click on them, or the ✎ button after them, swaps for a field holding value, with Save and Cancel under it. The ✎ shows on hover and on keyboard focus. A click on a link in the text, or one that ends a selection, follows the link or keeps the selection instead. Closing the field gives the focus back to the ✎ when the field had it.","url":"./src/components/form/InlineEdit.tsx/~/InlineEdit.html","deprecated":false},{"id":"namespace_inlineeditfieldprops","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"InlineEditFieldProps","file":"src/components/form/InlineEdit.tsx","doc":"Passed to InlineEditField by InlineEdit, and by the components that open it with an action of their own, CommentNode and ChatMessageItem, in place of the text while it is edited.","url":"./src/components/form/InlineEdit.tsx/~/InlineEditFieldProps.html","deprecated":false},{"id":"namespace_inlineeditfieldprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"InlineEditFieldProps.onSave","file":"src/components/form/InlineEdit.tsx","doc":"Saves the trimmed text. The field closes once it is done, and stays open under the error it throws. A text left as it was isn't passed to it.","url":"./src/components/form/InlineEdit.tsx/~/InlineEditFieldProps.onSave.html","deprecated":false},{"id":"namespace_inlineeditfieldprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"InlineEditFieldProps.onClose","file":"src/components/form/InlineEdit.tsx","doc":"Called once the text is saved, or left: the field is to unmount.","url":"./src/components/form/InlineEdit.tsx/~/InlineEditFieldProps.onClose.html","deprecated":false},{"id":"namespace_inlineeditfieldprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"InlineEditFieldProps.label","file":"src/components/form/InlineEdit.tsx","doc":"Names a one-line field, such as \"Edit title\".","url":"./src/components/form/InlineEdit.tsx/~/InlineEditFieldProps.label.html","deprecated":false},{"id":"namespace_inlineeditfieldprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"InlineEditFieldProps.fieldClassName","file":"src/components/form/InlineEdit.tsx","doc":"Added to the field: for a one-line one, the class of the text it edits, such as dump-title, so that it takes on its type in every style.","url":"./src/components/form/InlineEdit.tsx/~/InlineEditFieldProps.fieldClassName.html","deprecated":false},{"id":"namespace_inlineeditfieldprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"InlineEditFieldProps.enterSaves","file":"src/components/form/InlineEdit.tsx","doc":"In the Markdown editor, saves on Enter, a line breaking on Shift+Enter, as the chat's composer does. Ctrl/Cmd+Enter saves in either case.","url":"./src/components/form/InlineEdit.tsx/~/InlineEditFieldProps.enterSaves.html","deprecated":false},{"id":"namespace_inlineeditfieldprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"InlineEditFieldProps.countFrom","file":"src/components/form/InlineEdit.tsx","doc":"Where the Markdown editor's counter starts, near maxLength.","url":"./src/components/form/InlineEdit.tsx/~/InlineEditFieldProps.countFrom.html","deprecated":false},{"id":"namespace_inlineeditfieldprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"InlineEditFieldProps.returnFocusTo","file":"src/components/form/InlineEdit.tsx","doc":"Takes the focus once the field is gone, if it had it and no one has taken it since: the button that opened it, back in its place.","url":"./src/components/form/InlineEdit.tsx/~/InlineEditFieldProps.returnFocusTo.html","deprecated":false},{"id":"namespace_inlineeditfield","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"InlineEditField","file":"src/components/form/InlineEdit.tsx","doc":"Renders the field holding value, focused with the caret at its end, and Save and Cancel under it. Enter saves a line, Ctrl/Cmd+Enter a Markdown text, Escape leaves. Saving is refused while the text is empty and required, or longer than maxLength. It is mounted afresh on each opening, so that it starts from value.","url":"./src/components/form/InlineEdit.tsx/~/InlineEditField.html","deprecated":false},{"id":"namespace_richtextfieldprops","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"RichTextFieldProps","file":"src/components/form/RichTextField.tsx","doc":"Passed to RichTextField by a form that holds a string field.","url":"./src/components/form/RichTextField.tsx/~/RichTextFieldProps.html","deprecated":false},{"id":"namespace_richtextfieldprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"RichTextFieldProps.name","file":"src/components/form/RichTextField.tsx","doc":"","url":"./src/components/form/RichTextField.tsx/~/RichTextFieldProps.name.html","deprecated":false},{"id":"namespace_richtextfieldprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"RichTextFieldProps.label","file":"src/components/form/RichTextField.tsx","doc":"","url":"./src/components/form/RichTextField.tsx/~/RichTextFieldProps.label.html","deprecated":false},{"id":"namespace_richtextfieldprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"RichTextFieldProps.placeholder","file":"src/components/form/RichTextField.tsx","doc":"","url":"./src/components/form/RichTextField.tsx/~/RichTextFieldProps.placeholder.html","deprecated":false},{"id":"namespace_richtextfieldprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"RichTextFieldProps.rows","file":"src/components/form/RichTextField.tsx","doc":"","url":"./src/components/form/RichTextField.tsx/~/RichTextFieldProps.rows.html","deprecated":false},{"id":"namespace_richtextfieldprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"RichTextFieldProps.maxLength","file":"src/components/form/RichTextField.tsx","doc":"Counted in the editor and checked on submit, with a message. It overrides a maxLength in rules.","url":"./src/components/form/RichTextField.tsx/~/RichTextFieldProps.maxLength.html","deprecated":false},{"id":"namespace_richtextfieldprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"RichTextFieldProps.autoResize","file":"src/components/form/RichTextField.tsx","doc":"","url":"./src/components/form/RichTextField.tsx/~/RichTextFieldProps.autoResize.html","deprecated":false},{"id":"namespace_richtextfieldprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"RichTextFieldProps.disabled","file":"src/components/form/RichTextField.tsx","doc":"","url":"./src/components/form/RichTextField.tsx/~/RichTextFieldProps.disabled.html","deprecated":false},{"id":"namespace_richtextfieldprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"RichTextFieldProps.rules","file":"src/components/form/RichTextField.tsx","doc":"","url":"./src/components/form/RichTextField.tsx/~/RichTextFieldProps.rules.html","deprecated":false},{"id":"namespace_richtextfieldprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"RichTextFieldProps.editorRef","file":"src/components/form/RichTextField.tsx","doc":"The editor's ref, for a caller that focuses it.","url":"./src/components/form/RichTextField.tsx/~/RichTextFieldProps.editorRef.html","deprecated":false},{"id":"namespace_richtextfieldprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"RichTextFieldProps.onSubmit","file":"src/components/form/RichTextField.tsx","doc":"Called on Ctrl/Cmd+Enter.","url":"./src/components/form/RichTextField.tsx/~/RichTextFieldProps.onSubmit.html","deprecated":false},{"id":"namespace_richtextfield","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"RichTextField","file":"src/components/form/RichTextField.tsx","doc":"Renders the editor with its label and the field's error. It must sit under a react-hook-form FormProvider, such as one given useApiForm's result.","url":"./src/components/form/RichTextField.tsx/~/RichTextField.html","deprecated":false},{"id":"namespace_segmentedfieldprops","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"SegmentedFieldProps","file":"src/components/form/SegmentedField.tsx","doc":"Passed to SegmentedField by a form, or by VisibilityToggle.","url":"./src/components/form/SegmentedField.tsx/~/SegmentedFieldProps.html","deprecated":false},{"id":"namespace_segmentedfieldprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"SegmentedFieldProps.name","file":"src/components/form/SegmentedField.tsx","doc":"","url":"./src/components/form/SegmentedField.tsx/~/SegmentedFieldProps.name.html","deprecated":false},{"id":"namespace_segmentedfieldprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"SegmentedFieldProps.options","file":"src/components/form/SegmentedField.tsx","doc":"","url":"./src/components/form/SegmentedField.tsx/~/SegmentedFieldProps.options.html","deprecated":false},{"id":"namespace_segmentedfieldprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"SegmentedFieldProps.label","file":"src/components/form/SegmentedField.tsx","doc":"","url":"./src/components/form/SegmentedField.tsx/~/SegmentedFieldProps.label.html","deprecated":false},{"id":"namespace_segmentedfieldprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"SegmentedFieldProps.disabled","file":"src/components/form/SegmentedField.tsx","doc":"","url":"./src/components/form/SegmentedField.tsx/~/SegmentedFieldProps.disabled.html","deprecated":false},{"id":"namespace_segmentedfield","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"SegmentedField","file":"src/components/form/SegmentedField.tsx","doc":"Renders a Segmented bound to the field name, under its label. It must sit under a react-hook-form FormProvider.","url":"./src/components/form/SegmentedField.tsx/~/SegmentedField.html","deprecated":false},{"id":"namespace_visibilitytoggleprops","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"VisibilityToggleProps","file":"src/components/form/SegmentedField.tsx","doc":"Passed to VisibilityToggle by a dump or playlist form.","url":"./src/components/form/SegmentedField.tsx/~/VisibilityToggleProps.html","deprecated":false},{"id":"namespace_visibilitytoggleprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"VisibilityToggleProps.name","file":"src/components/form/SegmentedField.tsx","doc":"A boolean field, true for public.","url":"./src/components/form/SegmentedField.tsx/~/VisibilityToggleProps.name.html","deprecated":false},{"id":"namespace_visibilitytoggleprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"VisibilityToggleProps.label","file":"src/components/form/SegmentedField.tsx","doc":"","url":"./src/components/form/SegmentedField.tsx/~/VisibilityToggleProps.label.html","deprecated":false},{"id":"namespace_visibilitytoggleprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"VisibilityToggleProps.disabled","file":"src/components/form/SegmentedField.tsx","doc":"","url":"./src/components/form/SegmentedField.tsx/~/VisibilityToggleProps.disabled.html","deprecated":false},{"id":"namespace_visibilitytoggle","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"VisibilityToggle","file":"src/components/form/SegmentedField.tsx","doc":"Renders a Public/Private toggle on a boolean field that is true for public. A dump's API takes isPrivate instead, so the dump forms bind the toggle to an isPublic field and invert it on submit.","url":"./src/components/form/SegmentedField.tsx/~/VisibilityToggle.html","deprecated":false},{"id":"namespace_slugfieldprops","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"SlugFieldProps","file":"src/components/form/SlugField.tsx","doc":"Passed to SlugField by DumpEdit's and PlaylistEditForm's forms, which send the slug only when it differs from saved.slug.","url":"./src/components/form/SlugField.tsx/~/SlugFieldProps.html","deprecated":false},{"id":"namespace_slugfieldprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"SlugFieldProps.name","file":"src/components/form/SlugField.tsx","doc":"The form's slug field.","url":"./src/components/form/SlugField.tsx/~/SlugFieldProps.name.html","deprecated":false},{"id":"namespace_slugfieldprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"SlugFieldProps.titleName","file":"src/components/form/SlugField.tsx","doc":"The form's title field, which the slug follows until it is typed in.","url":"./src/components/form/SlugField.tsx/~/SlugFieldProps.titleName.html","deprecated":false},{"id":"namespace_slugfieldprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"SlugFieldProps.prefix","file":"src/components/form/SlugField.tsx","doc":"The page's path up to the slug, such as /@bob/dumps/.","url":"./src/components/form/SlugField.tsx/~/SlugFieldProps.prefix.html","deprecated":false},{"id":"namespace_slugfieldprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"SlugFieldProps.saved","file":"src/components/form/SlugField.tsx","doc":"The item as saved, whose slug a title put back to its own restores.","url":"./src/components/form/SlugField.tsx/~/SlugFieldProps.saved.html","deprecated":false},{"id":"namespace_slugfieldprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"SlugFieldProps.saved.title","file":"src/components/form/SlugField.tsx","doc":"","url":"./src/components/form/SlugField.tsx/~/SlugFieldProps.saved.title.html","deprecated":false},{"id":"namespace_slugfieldprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"SlugFieldProps.saved.slug","file":"src/components/form/SlugField.tsx","doc":"","url":"./src/components/form/SlugField.tsx/~/SlugFieldProps.saved.slug.html","deprecated":false},{"id":"namespace_slugfieldprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"SlugFieldProps.inputClassName","file":"src/components/form/SlugField.tsx","doc":"For a form outside .form, whose inputs take their own class.","url":"./src/components/form/SlugField.tsx/~/SlugFieldProps.inputClassName.html","deprecated":false},{"id":"namespace_slugfield","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"SlugField","file":"src/components/form/SlugField.tsx","doc":"Renders the slug's input after its path, and its error. Until the user types in it, it follows the title, proposing slugify(title), or the saved slug when the title slugifies as the saved one does. It must sit under a react-hook-form FormProvider.","url":"./src/components/form/SlugField.tsx/~/SlugField.html","deprecated":false},{"id":"namespace_submitbuttonprops","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"SubmitButtonProps","file":"src/components/form/SubmitButton.tsx","doc":"Passed to SubmitButton by a form, usually inside FormActions.","url":"./src/components/form/SubmitButton.tsx/~/SubmitButtonProps.html","deprecated":false},{"id":"namespace_submitbuttonprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"SubmitButtonProps.children","file":"src/components/form/SubmitButton.tsx","doc":"","url":"./src/components/form/SubmitButton.tsx/~/SubmitButtonProps.children.html","deprecated":false},{"id":"namespace_submitbuttonprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"SubmitButtonProps.pendingLabel","file":"src/components/form/SubmitButton.tsx","doc":"Replaces the label while the form is submitting, such as \"Saving…\".","url":"./src/components/form/SubmitButton.tsx/~/SubmitButtonProps.pendingLabel.html","deprecated":false},{"id":"namespace_submitbuttonprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"SubmitButtonProps.disabled","file":"src/components/form/SubmitButton.tsx","doc":"Disables the button, which is disabled while submitting anyway.","url":"./src/components/form/SubmitButton.tsx/~/SubmitButtonProps.disabled.html","deprecated":false},{"id":"namespace_submitbuttonprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"SubmitButtonProps.className","file":"src/components/form/SubmitButton.tsx","doc":"Replaces the btn-primary class.","url":"./src/components/form/SubmitButton.tsx/~/SubmitButtonProps.className.html","deprecated":false},{"id":"namespace_submitbuttonprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"SubmitButtonProps.aria-label","file":"src/components/form/SubmitButton.tsx","doc":"Names an icon-only button, such as \"✓\".","url":"./src/components/form/SubmitButton.tsx/~/SubmitButtonProps.aria-label.html","deprecated":false},{"id":"namespace_submitbutton","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"SubmitButton","file":"src/components/form/SubmitButton.tsx","doc":"Renders a submit button that is disabled while the form submits, so that a second click can't post twice. It reads the form's state, so it must sit under a react-hook-form FormProvider.","url":"./src/components/form/SubmitButton.tsx/~/SubmitButton.html","deprecated":false},{"id":"namespace_textfieldprops","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"TextFieldProps","file":"src/components/form/TextField.tsx","doc":"Passed to TextField by a form that holds a string field.","url":"./src/components/form/TextField.tsx/~/TextFieldProps.html","deprecated":false},{"id":"namespace_textfieldprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"TextFieldProps.name","file":"src/components/form/TextField.tsx","doc":"","url":"./src/components/form/TextField.tsx/~/TextFieldProps.name.html","deprecated":false},{"id":"namespace_textfieldprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"TextFieldProps.label","file":"src/components/form/TextField.tsx","doc":"","url":"./src/components/form/TextField.tsx/~/TextFieldProps.label.html","deprecated":false},{"id":"namespace_textfieldprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"TextFieldProps.labelAction","file":"src/components/form/TextField.tsx","doc":"Shown at the right of the label, such as a reset button.","url":"./src/components/form/TextField.tsx/~/TextFieldProps.labelAction.html","deprecated":false},{"id":"namespace_textfieldprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"TextFieldProps.type","file":"src/components/form/TextField.tsx","doc":"","url":"./src/components/form/TextField.tsx/~/TextFieldProps.type.html","deprecated":false},{"id":"namespace_textfieldprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"TextFieldProps.placeholder","file":"src/components/form/TextField.tsx","doc":"","url":"./src/components/form/TextField.tsx/~/TextFieldProps.placeholder.html","deprecated":false},{"id":"namespace_textfieldprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"TextFieldProps.autoComplete","file":"src/components/form/TextField.tsx","doc":"","url":"./src/components/form/TextField.tsx/~/TextFieldProps.autoComplete.html","deprecated":false},{"id":"namespace_textfieldprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"TextFieldProps.autoFocus","file":"src/components/form/TextField.tsx","doc":"","url":"./src/components/form/TextField.tsx/~/TextFieldProps.autoFocus.html","deprecated":false},{"id":"namespace_textfieldprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"TextFieldProps.disabled","file":"src/components/form/TextField.tsx","doc":"","url":"./src/components/form/TextField.tsx/~/TextFieldProps.disabled.html","deprecated":false},{"id":"namespace_textfieldprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"TextFieldProps.rules","file":"src/components/form/TextField.tsx","doc":"","url":"./src/components/form/TextField.tsx/~/TextFieldProps.rules.html","deprecated":false},{"id":"namespace_textfieldprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"TextFieldProps.maxLength","file":"src/components/form/TextField.tsx","doc":"Stops the typing at this length, through the input's own maxLength. Unlike RichTextField's, it adds no rule, so a value set from code isn't checked.","url":"./src/components/form/TextField.tsx/~/TextFieldProps.maxLength.html","deprecated":false},{"id":"namespace_textfieldprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"TextFieldProps.showCount","file":"src/components/form/TextField.tsx","doc":"Shows an n / maxLength counter, only when maxLength is set.","url":"./src/components/form/TextField.tsx/~/TextFieldProps.showCount.html","deprecated":false},{"id":"namespace_textfield","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"TextField","file":"src/components/form/TextField.tsx","doc":"Renders the input with its label and the field's error. It must sit under a react-hook-form FormProvider, such as one given useApiForm's result.","url":"./src/components/form/TextField.tsx/~/TextField.html","deprecated":false},{"id":"namespace_appheaderprops","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"AppHeaderProps","file":"src/components/layout/AppHeader.tsx","doc":"Passed to AppHeader by the index page. The other pages leave these props out.","url":"./src/components/layout/AppHeader.tsx/~/AppHeaderProps.html","deprecated":false},{"id":"namespace_appheaderprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"AppHeaderProps.centerSlot","file":"src/components/layout/AppHeader.tsx","doc":"Shown beside the search. The index page puts its feed tabs there.","url":"./src/components/layout/AppHeader.tsx/~/AppHeaderProps.centerSlot.html","deprecated":false},{"id":"namespace_appheaderprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"AppHeaderProps.disableNew","file":"src/components/layout/AppHeader.tsx","doc":"Set by the index page while its feed fails to load.","url":"./src/components/layout/AppHeader.tsx/~/AppHeaderProps.disableNew.html","deprecated":false},{"id":"namespace_appheaderprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"AppHeaderProps.initialDumpUrl","file":"src/components/layout/AppHeader.tsx","doc":"Opens the dump creation dialog at mount, with this link. The index page passes the link shared to the app from Android's share sheet.","url":"./src/components/layout/AppHeader.tsx/~/AppHeaderProps.initialDumpUrl.html","deprecated":false},{"id":"namespace_appheader","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"AppHeader","file":"src/components/layout/AppHeader.tsx","doc":"Renders the site's header. It holds the search, which stays open on the results page and slides open under the header on small screens, the link to the playlists page, the signed-in user's menu and buttons or a guest's \"Log in\", and a banner while live updates are down. It also hosts the dump creation dialog that its \"+ Dump\" button opens.","url":"./src/components/layout/AppHeader.tsx/~/AppHeader.html","deprecated":false},{"id":"namespace_chatbutton","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"ChatButton","file":"src/components/layout/ChatButton.tsx","doc":"Renders the button that opens the chat, filled with the accent and dotted while the socket counts unread messages; the count itself is in its label. ChatFab takes over, with the count, once the header scrolls away.","url":"./src/components/layout/ChatButton.tsx/~/ChatButton.html","deprecated":false},{"id":"namespace_chatfab","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"ChatFab","file":"src/components/layout/ChatFab.tsx","doc":"Renders the chat button that floats above DumpFab once the header, and its ChatButton, have scrolled out of view. It renders nothing when signed out.","url":"./src/components/layout/ChatFab.tsx/~/ChatFab.html","deprecated":false},{"id":"namespace_dumpfab","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"DumpFab","file":"src/components/layout/DumpFab.tsx","doc":"Renders the button that opens the dump creation dialog once the header, and its \"+ Dump\" button, have scrolled out of view. It renders nothing when signed out. The stylesheet lifts it above the global player.","url":"./src/components/layout/DumpFab.tsx/~/DumpFab.html","deprecated":false},{"id":"namespace_marquee","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"Marquee","file":"src/components/layout/Marquee.tsx","doc":"Renders the marquee for a signed-in user in the GeoCities style, an empty band until the feed is loaded, so that the page under it doesn't move when it comes.","url":"./src/components/layout/Marquee.tsx/~/Marquee.html","deprecated":false},{"id":"namespace_naviconprops","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"NavIconProps","file":"src/components/layout/NavIcons.tsx","doc":"Passed to every icon, so a caller can add its own class (the bell rings).","url":"./src/components/layout/NavIcons.tsx/~/NavIconProps.html","deprecated":false},{"id":"namespace_naviconprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"NavIconProps.className","file":"src/components/layout/NavIcons.tsx","doc":"","url":"./src/components/layout/NavIcons.tsx/~/NavIconProps.className.html","deprecated":false},{"id":"namespace_iconsearch","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"IconSearch","file":"src/components/layout/NavIcons.tsx","doc":"Renders a magnifier, for the header's search toggle and the search bar.","url":"./src/components/layout/NavIcons.tsx/~/IconSearch.html","deprecated":false},{"id":"namespace_iconclose","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"IconClose","file":"src/components/layout/NavIcons.tsx","doc":"Renders the ✕ the search toggle turns into while the search is open.","url":"./src/components/layout/NavIcons.tsx/~/IconClose.html","deprecated":false},{"id":"namespace_iconchat","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"IconChat","file":"src/components/layout/NavIcons.tsx","doc":"Renders a speech bubble, for ChatButton and ChatFab.","url":"./src/components/layout/NavIcons.tsx/~/IconChat.html","deprecated":false},{"id":"namespace_iconbell","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"IconBell","file":"src/components/layout/NavIcons.tsx","doc":"Renders a bell, for NotificationBell.","url":"./src/components/layout/NavIcons.tsx/~/IconBell.html","deprecated":false},{"id":"namespace_notificationbell","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"NotificationBell","file":"src/components/layout/NotificationBell.tsx","doc":"Renders the bell that leads to /notifications. While the socket counts unread notifications it fills with the accent and wears a dot; the count itself is in its label and the tab's title. It rings when the socket pushes a new one.","url":"./src/components/layout/NotificationBell.tsx/~/NotificationBell.html","deprecated":false},{"id":"namespace_pageerrorprops","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"PageErrorProps","file":"src/components/layout/PageError.tsx","doc":"Passed to PageError by a page whose load failed.","url":"./src/components/layout/PageError.tsx/~/PageErrorProps.html","deprecated":false},{"id":"namespace_pageerrorprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PageErrorProps.title","file":"src/components/layout/PageError.tsx","doc":"Defaults to \"Something went wrong\".","url":"./src/components/layout/PageError.tsx/~/PageErrorProps.title.html","deprecated":false},{"id":"namespace_pageerrorprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PageErrorProps.message","file":"src/components/layout/PageError.tsx","doc":"","url":"./src/components/layout/PageError.tsx/~/PageErrorProps.message.html","deprecated":false},{"id":"namespace_pageerrorprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PageErrorProps.actions","file":"src/components/layout/PageError.tsx","doc":"Buttons under the message, such as a retry.","url":"./src/components/layout/PageError.tsx/~/PageErrorProps.actions.html","deprecated":false},{"id":"namespace_pageerror","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"PageError","file":"src/components/layout/PageError.tsx","doc":"Renders an error card as the whole page, under the header, so the user can still navigate away.","url":"./src/components/layout/PageError.tsx/~/PageError.html","deprecated":false},{"id":"namespace_pagegroupprops","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"PageGroupProps","file":"src/components/layout/PageGroup.tsx","doc":"Passed to PageGroup by Settings, Manage and Notifications.","url":"./src/components/layout/PageGroup.tsx/~/PageGroupProps.html","deprecated":false},{"id":"namespace_pagegroupprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PageGroupProps.label","file":"src/components/layout/PageGroup.tsx","doc":"It shows as a small capitalized label, ruled to the column's end.","url":"./src/components/layout/PageGroup.tsx/~/PageGroupProps.label.html","deprecated":false},{"id":"namespace_pagegroupprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PageGroupProps.children","file":"src/components/layout/PageGroup.tsx","doc":"Usually a .page-card, or the notifications' list of cards.","url":"./src/components/layout/PageGroup.tsx/~/PageGroupProps.children.html","deprecated":false},{"id":"namespace_pagegroup","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"PageGroup","file":"src/components/layout/PageGroup.tsx","doc":"Renders a headed by label as its h2.","url":"./src/components/layout/PageGroup.tsx/~/PageGroup.html","deprecated":false},{"id":"namespace_pageheaderprops","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"PageHeaderProps","file":"src/components/layout/PageHeader.tsx","doc":"Passed to PageHeader by Settings, Manage, Notifications and Playlists.","url":"./src/components/layout/PageHeader.tsx/~/PageHeaderProps.html","deprecated":false},{"id":"namespace_pageheaderprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PageHeaderProps.icon","file":"src/components/layout/PageHeader.tsx","doc":"An emoji before the title, hidden from screen readers.","url":"./src/components/layout/PageHeader.tsx/~/PageHeaderProps.icon.html","deprecated":false},{"id":"namespace_pageheaderprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PageHeaderProps.title","file":"src/components/layout/PageHeader.tsx","doc":"","url":"./src/components/layout/PageHeader.tsx/~/PageHeaderProps.title.html","deprecated":false},{"id":"namespace_pageheaderprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PageHeaderProps.children","file":"src/components/layout/PageHeader.tsx","doc":"It goes at the end of the row, such as the notifications' unread count or the playlists' category menu and order tabs.","url":"./src/components/layout/PageHeader.tsx/~/PageHeaderProps.children.html","deprecated":false},{"id":"namespace_pageheader","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"PageHeader","file":"src/components/layout/PageHeader.tsx","doc":"Renders the page's h1 with its icon, then children, as the first block of a PageShell: a narrow one's PageGroups follow it, or the playlists page's grid.","url":"./src/components/layout/PageHeader.tsx/~/PageHeader.html","deprecated":false},{"id":"namespace_pageshellprops","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"PageShellProps","file":"src/components/layout/PageShell.tsx","doc":"Passed to PageShell by a page, around its content.","url":"./src/components/layout/PageShell.tsx/~/PageShellProps.html","deprecated":false},{"id":"namespace_pageshellprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PageShellProps.children","file":"src/components/layout/PageShell.tsx","doc":"","url":"./src/components/layout/PageShell.tsx/~/PageShellProps.children.html","deprecated":false},{"id":"namespace_pageshellprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PageShellProps.centered","file":"src/components/layout/PageShell.tsx","doc":"Centers the content, for a lone card such as a form or an error.","url":"./src/components/layout/PageShell.tsx/~/PageShellProps.centered.html","deprecated":false},{"id":"namespace_pageshellprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"PageShellProps.narrow","file":"src/components/layout/PageShell.tsx","doc":"Narrows the content to the column the user menu's and the bell's pages share, under a PageHeader.","url":"./src/components/layout/PageShell.tsx/~/PageShellProps.narrow.html","deprecated":false},{"id":"namespace_pageshell","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"PageShell","file":"src/components/layout/PageShell.tsx","doc":"Renders AppHeader, then the page's content as the .","url":"./src/components/layout/PageShell.tsx/~/PageShell.html","deprecated":false},{"id":"namespace_searchbarprops","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"SearchBarProps","file":"src/components/layout/SearchBar.tsx","doc":"Passed to SearchBar by AppHeader, which holds the query and decides where a search leads.","url":"./src/components/layout/SearchBar.tsx/~/SearchBarProps.html","deprecated":false},{"id":"namespace_searchbarprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"SearchBarProps.expanded","file":"src/components/layout/SearchBar.tsx","doc":"","url":"./src/components/layout/SearchBar.tsx/~/SearchBarProps.expanded.html","deprecated":false},{"id":"namespace_searchbarprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"SearchBarProps.value","file":"src/components/layout/SearchBar.tsx","doc":"","url":"./src/components/layout/SearchBar.tsx/~/SearchBarProps.value.html","deprecated":false},{"id":"namespace_searchbarprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"SearchBarProps.onValueChange","file":"src/components/layout/SearchBar.tsx","doc":"","url":"./src/components/layout/SearchBar.tsx/~/SearchBarProps.onValueChange.html","deprecated":false},{"id":"namespace_searchbarprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"SearchBarProps.onSubmit","file":"src/components/layout/SearchBar.tsx","doc":"Called with the trimmed query, never an empty one.","url":"./src/components/layout/SearchBar.tsx/~/SearchBarProps.onSubmit.html","deprecated":false},{"id":"namespace_searchbarprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"SearchBarProps.onCancel","file":"src/components/layout/SearchBar.tsx","doc":"Called when Escape is pressed in the input.","url":"./src/components/layout/SearchBar.tsx/~/SearchBarProps.onCancel.html","deprecated":false},{"id":"namespace_searchbar","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"SearchBar","file":"src/components/layout/SearchBar.tsx","doc":"Renders the search form. AppHeader renders two over one state, one in its center and one in the row that slides open under it on small screens, so the query survives crossing the breakpoint. Opening it focuses the input.","url":"./src/components/layout/SearchBar.tsx/~/SearchBar.html","deprecated":false},{"id":"namespace_usermenuprops","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"UserMenuProps","file":"src/components/layout/UserMenu.tsx","doc":"Passed to UserMenu by AppHeader, for a signed-in user.","url":"./src/components/layout/UserMenu.tsx/~/UserMenuProps.html","deprecated":false},{"id":"namespace_usermenuprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"UserMenuProps.user","file":"src/components/layout/UserMenu.tsx","doc":"","url":"./src/components/layout/UserMenu.tsx/~/UserMenuProps.user.html","deprecated":false},{"id":"namespace_usermenu","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"UserMenu","file":"src/components/layout/UserMenu.tsx","doc":"Renders the signed-in user's avatar, which opens a menu with links to their profile, /playlists, /community and /settings, to /manage for those who hold category:manage or federation:manage, and a Log out button. A click outside or Escape closes it.","url":"./src/components/layout/UserMenu.tsx/~/UserMenu.html","deprecated":false},{"id":"namespace_globalplayer","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"GlobalPlayer","file":"src/components/player/GlobalPlayer.tsx","doc":"Renders what PlayerContext plays, with a link to its dump: a MediaPlayer for a file or a stream, the provider's iframe for an embed, and the tracklist of the queue or of a YouTube playlist. It renders nothing while nothing plays.","url":"./src/components/player/GlobalPlayer.tsx/~/GlobalPlayer.html","deprecated":false},{"id":"namespace_mediaplayerprops","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"MediaPlayerProps","file":"src/components/player/MediaPlayer.tsx","doc":"Passed to MediaPlayer by GlobalPlayer, which wires the callbacks and the handles to PlayerContext, and by the file previews, which pass only the media.","url":"./src/components/player/MediaPlayer.tsx/~/MediaPlayerProps.html","deprecated":false},{"id":"namespace_mediaplayerprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"MediaPlayerProps.src","file":"src/components/player/MediaPlayer.tsx","doc":"","url":"./src/components/player/MediaPlayer.tsx/~/MediaPlayerProps.src.html","deprecated":false},{"id":"namespace_mediaplayerprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"MediaPlayerProps.kind","file":"src/components/player/MediaPlayer.tsx","doc":"","url":"./src/components/player/MediaPlayer.tsx/~/MediaPlayerProps.kind.html","deprecated":false},{"id":"namespace_mediaplayerprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"MediaPlayerProps.poster","file":"src/components/player/MediaPlayer.tsx","doc":"Shown before a video plays.","url":"./src/components/player/MediaPlayer.tsx/~/MediaPlayerProps.poster.html","deprecated":false},{"id":"namespace_mediaplayerprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"MediaPlayerProps.autoplay","file":"src/components/player/MediaPlayer.tsx","doc":"","url":"./src/components/player/MediaPlayer.tsx/~/MediaPlayerProps.autoplay.html","deprecated":false},{"id":"namespace_mediaplayerprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"MediaPlayerProps.startTime","file":"src/components/player/MediaPlayer.tsx","doc":"In seconds. Read on mount only: later seeks go through seekRef.","url":"./src/components/player/MediaPlayer.tsx/~/MediaPlayerProps.startTime.html","deprecated":false},{"id":"namespace_mediaplayerprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"MediaPlayerProps.onPlayStateChange","file":"src/components/player/MediaPlayer.tsx","doc":"","url":"./src/components/player/MediaPlayer.tsx/~/MediaPlayerProps.onPlayStateChange.html","deprecated":false},{"id":"namespace_mediaplayerprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"MediaPlayerProps.onTimeUpdate","file":"src/components/player/MediaPlayer.tsx","doc":"","url":"./src/components/player/MediaPlayer.tsx/~/MediaPlayerProps.onTimeUpdate.html","deprecated":false},{"id":"namespace_mediaplayerprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"MediaPlayerProps.onEnded","file":"src/components/player/MediaPlayer.tsx","doc":"Called at the media's end, where GlobalPlayer plays the next item.","url":"./src/components/player/MediaPlayer.tsx/~/MediaPlayerProps.onEnded.html","deprecated":false},{"id":"namespace_mediaplayerprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"MediaPlayerProps.onError","file":"src/components/player/MediaPlayer.tsx","doc":"Called when the media fails to load or decode, where a stream's URL is re-resolved.","url":"./src/components/player/MediaPlayer.tsx/~/MediaPlayerProps.onError.html","deprecated":false},{"id":"namespace_mediaplayerprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"MediaPlayerProps.waveform","file":"src/components/player/MediaPlayer.tsx","doc":"Where an audio file's waveform comes from. Without it, as for a stream whose bytes another site serves, audio seeks on a plain bar.","url":"./src/components/player/MediaPlayer.tsx/~/MediaPlayerProps.waveform.html","deprecated":false},{"id":"namespace_mediaplayerprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"MediaPlayerProps.seekRef","file":"src/components/player/MediaPlayer.tsx","doc":"Receives its seek handle while mounted, for PlayerContext's seekTo.","url":"./src/components/player/MediaPlayer.tsx/~/MediaPlayerProps.seekRef.html","deprecated":false},{"id":"namespace_mediaplayerprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"MediaPlayerProps.seekRef.current","file":"src/components/player/MediaPlayer.tsx","doc":"","url":"./src/components/player/MediaPlayer.tsx/~/MediaPlayerProps.seekRef.current.html","deprecated":false},{"id":"namespace_mediaplayerprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"MediaPlayerProps.toggleRef","file":"src/components/player/MediaPlayer.tsx","doc":"Receives its play/pause handle while mounted, for togglePlay.","url":"./src/components/player/MediaPlayer.tsx/~/MediaPlayerProps.toggleRef.html","deprecated":false},{"id":"namespace_mediaplayerprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"MediaPlayerProps.toggleRef.current","file":"src/components/player/MediaPlayer.tsx","doc":"","url":"./src/components/player/MediaPlayer.tsx/~/MediaPlayerProps.toggleRef.current.html","deprecated":false},{"id":"namespace_mediaplayer","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"MediaPlayer","file":"src/components/player/MediaPlayer.tsx","doc":"Renders a media element with the site's own controls. Audio seeks on its waveform when it has one; video gets a slim bar, a fullscreen button, and controls that hide while it plays. Whether it plays is read from the element's own events, so a media key or the OS's controls show too. The volume carries over to the next MediaPlayer, which matters since GlobalPlayer mounts a new one for each track.","url":"./src/components/player/MediaPlayer.tsx/~/MediaPlayer.html","deprecated":false},{"id":"namespace_iconplay","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"IconPlay","file":"src/components/player/PlayerIcons.tsx","doc":"Renders the play icon, nudged right so the triangle looks centred.","url":"./src/components/player/PlayerIcons.tsx/~/IconPlay.html","deprecated":false},{"id":"namespace_iconpause","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"IconPause","file":"src/components/player/PlayerIcons.tsx","doc":"Renders the pause icon, the play button's other state.","url":"./src/components/player/PlayerIcons.tsx/~/IconPause.html","deprecated":false},{"id":"namespace_iconvolumeprops","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"IconVolumeProps","file":"src/components/player/PlayerIcons.tsx","doc":"Passed to IconVolume by MediaPlayer's mute button.","url":"./src/components/player/PlayerIcons.tsx/~/IconVolumeProps.html","deprecated":false},{"id":"namespace_iconvolumeprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"IconVolumeProps.muted","file":"src/components/player/PlayerIcons.tsx","doc":"","url":"./src/components/player/PlayerIcons.tsx/~/IconVolumeProps.muted.html","deprecated":false},{"id":"namespace_iconvolume","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"IconVolume","file":"src/components/player/PlayerIcons.tsx","doc":"Renders the mute button's icon, crossed when muted.","url":"./src/components/player/PlayerIcons.tsx/~/IconVolume.html","deprecated":false},{"id":"namespace_iconfullscreen","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"IconFullscreen","file":"src/components/player/PlayerIcons.tsx","doc":"Renders the icon of a video's fullscreen button.","url":"./src/components/player/PlayerIcons.tsx/~/IconFullscreen.html","deprecated":false},{"id":"namespace_scrubberprops","kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"ScrubberProps","file":"src/components/player/Scrubber.tsx","doc":"Passed to Scrubber by MediaPlayer and FilePreview. Times are in seconds.","url":"./src/components/player/Scrubber.tsx/~/ScrubberProps.html","deprecated":false},{"id":"namespace_scrubberprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ScrubberProps.current","file":"src/components/player/Scrubber.tsx","doc":"","url":"./src/components/player/Scrubber.tsx/~/ScrubberProps.current.html","deprecated":false},{"id":"namespace_scrubberprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ScrubberProps.duration","file":"src/components/player/Scrubber.tsx","doc":"","url":"./src/components/player/Scrubber.tsx/~/ScrubberProps.duration.html","deprecated":false},{"id":"namespace_scrubberprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ScrubberProps.onSeek","file":"src/components/player/Scrubber.tsx","doc":"Called once a click, a drag or a key lands somewhere.","url":"./src/components/player/Scrubber.tsx/~/ScrubberProps.onSeek.html","deprecated":false},{"id":"namespace_scrubberprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ScrubberProps.onScrub","file":"src/components/player/Scrubber.tsx","doc":"Called with the time under the pointer while it holds the scrubber, and with null once it lets go, so MediaPlayer's clock can follow the drag.","url":"./src/components/player/Scrubber.tsx/~/ScrubberProps.onScrub.html","deprecated":false},{"id":"namespace_scrubberprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ScrubberProps.peaks","file":"src/components/player/Scrubber.tsx","doc":"The waveform's heights from 0 to 1; without them, a plain bar.","url":"./src/components/player/Scrubber.tsx/~/ScrubberProps.peaks.html","deprecated":false},{"id":"namespace_scrubberprops","kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ScrubberProps.slim","file":"src/components/player/Scrubber.tsx","doc":"Draws the thin bar of a video's controls instead of the audio track.","url":"./src/components/player/Scrubber.tsx/~/ScrubberProps.slim.html","deprecated":false},{"id":"namespace_scrubber","kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"Scrubber","file":"src/components/player/Scrubber.tsx","doc":"Renders a slider over the media's timeline. A pointer seeks where it lets go, showing where it is while held; arrows seek KEY_STEP seconds, Home and End to either end. The played part of the waveform is the same path clipped to the playhead by a nested