diff --git a/app/components/MobileNav.tsx b/app/components/MobileNav.tsx index 8828fc2f1..ffb92bae7 100644 --- a/app/components/MobileNav.tsx +++ b/app/components/MobileNav.tsx @@ -20,7 +20,6 @@ import { ScheduleNudge } from "~/features/availability/components/ScheduleNudge" import { useChatContext } from "~/features/chat/ChatProvider"; import { FriendMenu } from "~/features/friends/components/FriendMenu"; import { SENDOUQ_ACTIVITY_LABEL } from "~/features/friends/friends-constants"; -import { canAccessTrophies } from "~/features/trophies/trophies-utils"; import { useClosePopoversOnNavigation } from "~/hooks/useClosePopoversOnNavigation"; import { useScrollLock } from "~/hooks/useScrollLock"; import { useUnseenFriendRequests } from "~/hooks/useUnseenFriendRequests"; @@ -435,29 +434,25 @@ function MenuPanel({ diff --git a/app/components/layout/AnythingAdder.tsx b/app/components/layout/AnythingAdder.tsx index 6c2b19d08..deeada446 100644 --- a/app/components/layout/AnythingAdder.tsx +++ b/app/components/layout/AnythingAdder.tsx @@ -6,7 +6,6 @@ import { useUser } from "~/features/auth/core/user"; import { useGlobalStatus } from "~/features/global-status/GlobalStatusProvider"; import { lfgNewPostPage } from "~/features/lfg/lfg-urls"; import { plusSuggestionsNewPage } from "~/features/plus-suggestions/plus-suggestions-urls"; -import { canAccessTrophies } from "~/features/trophies/trophies-utils"; import { userNewBuildPage } from "~/features/user-page/user-page-urls"; import { newVodPage } from "~/features/vods/vods-urls"; import { @@ -103,15 +102,13 @@ export function AnythingAdder() { imagePath: navIconUrl("plus"), href: plusSuggestionsNewPage(), }, - canAccessTrophies(user) - ? { - id: "trophy", - children: t("header.adder.trophy"), - imagePath: navIconUrl("trophies"), - href: NEW_TROPHY_PAGE, - } - : null, - ].filter((item) => item !== null); + { + id: "trophy", + children: t("header.adder.trophy"), + imagePath: navIconUrl("trophies"), + href: NEW_TROPHY_PAGE, + }, + ]; return ( { if ("staffOnly" in item && !showStaffOnly) return false; - if (item.name === "trophies" && !canAccessTrophies(user)) return false; return true; }); diff --git a/app/db/seed/constants.ts b/app/db/seed/constants.ts index f47a2c80c..f047727ed 100644 --- a/app/db/seed/constants.ts +++ b/app/db/seed/constants.ts @@ -8,3 +8,5 @@ export const ORG_ADMIN_TEST_ID = 3; /** Matches STAFF_IDS[0] (Panda) so the seeded user is recognized as STAFF. */ export const STAFF_TEST_ID = 11329; export const STAFF_TEST_DISCORD_ID = "138757634500067328"; +/** Matches DEV_IDS[0] so the seeded user is recognized as DEV. */ +export const DEV_TEST_ID = 27883; diff --git a/app/db/seed/dev/misc.ts b/app/db/seed/dev/misc.ts index 2708fd14c..d39631279 100644 --- a/app/db/seed/dev/misc.ts +++ b/app/db/seed/dev/misc.ts @@ -23,6 +23,19 @@ import type { SeededTournaments } from "./tournaments"; import type { SeededUsers } from "./users"; const NZAP_PLAYER_SPL_ID = "qx6imlx72tfeqrhqfnmm"; +const NZAP_XP_TROPHY_PLACEMENTS: Array<{ + weaponSplId: MainWeaponId; + power: number; + region: Tables["XRankPlacement"]["region"]; + mode: ModeShort; + month: number; +}> = [ + { weaponSplId: 40, power: 3621.4, region: "WEST", mode: "SZ", month: 2 }, + { weaponSplId: 40, power: 3544.9, region: "JPN", mode: "TC", month: 3 }, + { weaponSplId: 2030, power: 3238.2, region: "WEST", mode: "RM", month: 4 }, + { weaponSplId: 1010, power: 3071.6, region: "JPN", mode: "CB", month: 5 }, + { weaponSplId: 6000, power: 4012.8, region: "WEST", mode: "SZ", month: 6 }, +]; const FRIEND_COUNT = 8; /** Friends of the admin, none of them a teammate, so that friends-only surfaces have something to show. */ const ADMIN_FRIEND_COUNT = 3; @@ -77,15 +90,25 @@ async function seedXRankPlacements(users: SeededUsers) { ? unaffiliatedTopPlayerId : undefined; + await XRankPlacementFactory.create({ + ...placement, + mode: placement.mode as ModeShort, + region: placement.region as Tables["XRankPlacement"]["region"], + weaponSplId: placement.weaponSplId as MainWeaponId, + playerUserId, + }); + } + + for (const [i, placement] of NZAP_XP_TROPHY_PLACEMENTS.entries()) { await XRankPlacementFactory.create( { ...placement, - mode: placement.mode as ModeShort, - region: placement.region as Tables["XRankPlacement"]["region"], - weaponSplId: placement.weaponSplId as MainWeaponId, - playerUserId, + year: 2024, + rank: 10 + i, + playerSplId: NZAP_PLAYER_SPL_ID, + playerUserId: users.nzapId, }, - { refreshPeakXp: i === placements.length - 1 }, + { refreshPeakXp: i === NZAP_XP_TROPHY_PLACEMENTS.length - 1 }, ); } } @@ -96,10 +119,10 @@ async function seedArts(users: SeededUsers) { for (const authorId of [users.nzapId, ...users.artistIds]) { const artCount = faker.helpers.arrayElement([1, 2, 3, 3, 4]); - for (let i = 0; i < artCount; i++) { + for (let i = 0; i < artCount && nextUrl < SEED_ART_URLS.length; i++) { await ArtFactory.create({ authorId, - url: getArtFilename(nextUrl++ % SEED_ART_URLS.length), + url: getArtFilename(nextUrl++), description: faker.number.float(1) < 0.5 ? faker.lorem.paragraph() : null, linkedUsers: diff --git a/app/db/seed/dev/tournaments.ts b/app/db/seed/dev/tournaments.ts index feb683dd2..d6b9d3f1b 100644 --- a/app/db/seed/dev/tournaments.ts +++ b/app/db/seed/dev/tournaments.ts @@ -74,6 +74,8 @@ const LUTI_MIN_MEMBERS = 4; const LUTI_MAX_MEMBERS = 8; const HISTORICAL_COUNT = 5; +/** PICNIC editions from before the series had a trophy, to backfill it for. */ +const PRE_TROPHY_PICNIC_COUNT = 3; /** Showcase users seeded into every played tournament, so their results paginate. */ const CORE_PLAYER_COUNT = 8; /** Share of teams registering as one of the site's teams, the rest being pickups. */ @@ -229,6 +231,14 @@ export async function seedTournaments({ seriesLogoImgIds, }); + await seedPreTrophyPicnics({ + users, + organizations, + badges, + rosters, + seriesLogoImgIds, + }); + return { regOpen: inTheZone, nzapTeamIds, luti }; } @@ -793,6 +803,44 @@ async function seedHistoricalTournaments({ return nzapTeamIds; } +async function seedPreTrophyPicnics({ + users, + organizations, + badges, + rosters, + seriesLogoImgIds, +}: Ctx & { badges: SeededBadges; seriesLogoImgIds: Map }) { + const stem = TOURNAMENT_NAME_STEMS[0]; + const organizationId = organizations[0].id; + + for (let i = 0; i < PRE_TROPHY_PICNIC_COUNT; i++) { + const startsAt = sub(new Date(), { months: 10 + i }); + const authorId = users.adminId; + + const tournament = await TournamentFactory.create( + { + name: `${stem.name} ${PRE_TROPHY_PICNIC_COUNT - i}`, + avatarImgId: await seriesLogoImgId(seriesLogoImgIds, stem, authorId), + authorId, + organizationId, + startTimes: [dateToDatabaseTimestamp(startsAt)], + bracketProgression: DOUBLE_ELIMINATION, + badges: i === 0 ? [badges.ids[0]] : [], + }, + { tier: 4 }, + ); + + await registerTeams({ + tournamentId: tournament.id, + rosters: rosters.take({ teamCount: 8, teamSize: 5 }), + isCheckedIn: true, + registeredAt: sub(startsAt, { days: 2 }), + }); + + await TournamentFactory.playOut(tournament.id, "all"); + } +} + /** Editions of a series share one logo image, an image row not being allowed the url of another. */ async function seriesLogoImgId( imgIds: Map, diff --git a/app/db/seed/dev/trophies.ts b/app/db/seed/dev/trophies.ts index a2f6ff806..d414afaf1 100644 --- a/app/db/seed/dev/trophies.ts +++ b/app/db/seed/dev/trophies.ts @@ -1,8 +1,3 @@ -import * as TrophyRepository from "~/features/trophies/TrophyRepository.server"; -import { - SUPPORTER_TROPHY_CODE, - XP_TROPHY_CODE_PREFIX, -} from "~/features/trophies/trophies-constants"; import { faker } from "../core/faker"; import trophies from "../data/trophies.json"; import * as TrophyFactory from "../factories/TrophyFactory"; @@ -44,27 +39,9 @@ export async function seedTrophies({ return { ids }; } -/** Non-tournament trophies handed to everybody eligible like the nightly sync. Runs last: eligibility follows from patrons and X Rank placements. */ +/** X Power trophies handed to everybody eligible like the X Rank placement import does. Runs last: eligibility follows from X Rank placements. */ export async function seedSpecialTrophies() { - const models = TrophyFactory.MODELS; - - await TrophyFactory.create({ - name: "Supporter", - model: models[0], - code: SUPPORTER_TROPHY_CODE, - }); - await TrophyFactory.create({ - name: "3000 X Power", - model: models[1], - code: `${XP_TROPHY_CODE_PREFIX}3000`, - }); - await TrophyFactory.create({ - name: "2600 X Power", - model: models[2], - code: `${XP_TROPHY_CODE_PREFIX}2600`, - }); - - await TrophyRepository.syncSpecialTrophies(); + await TrophyFactory.createXpTrophies(); } async function seedPendingTrophies({ diff --git a/app/db/seed/factories/TrophyFactory.ts b/app/db/seed/factories/TrophyFactory.ts index 621d39607..4e012cabb 100644 --- a/app/db/seed/factories/TrophyFactory.ts +++ b/app/db/seed/factories/TrophyFactory.ts @@ -1,5 +1,6 @@ import { db } from "~/db/sql"; import type { TablesInsertable } from "~/db/tables"; +import * as XpTrophy from "~/features/trophies/core/XpTrophy"; import * as TrophyRepository from "~/features/trophies/TrophyRepository.server"; import { defineFactory } from "../core/defineFactory"; // the e2e process loads this factory as plain ESM, where the attribute is required @@ -26,6 +27,23 @@ export const { create } = defineFactory({ .executeTakeFirstOrThrow(), }); +/** Every X Power trophy, awarded for the placements already in like the migration adding them does. */ +export async function createXpTrophies() { + const created: Array<{ id: number; code: string }> = []; + for (const variant of XpTrophy.VARIANTS) { + const trophy = await create({ + name: variant.name, + code: variant.code, + model: "", + }); + created.push({ id: trophy.id, code: variant.code }); + } + + await TrophyRepository.syncSpecialTrophies(); + + return created; +} + type PendingOptions = { /** Who approves the submission; enough of them and the trophy is created. */ approverUserIds?: number[]; diff --git a/app/db/seed/factories/UserFactory.ts b/app/db/seed/factories/UserFactory.ts index 0aa40c46c..5e6badcfa 100644 --- a/app/db/seed/factories/UserFactory.ts +++ b/app/db/seed/factories/UserFactory.ts @@ -9,6 +9,7 @@ import * as UserCardRepository from "~/features/user-card/UserCardRepository.ser import * as UserRepository from "~/features/user-page/UserRepository.server"; import { invariant } from "~/utils/invariant"; import { + DEV_TEST_ID, ORG_ADMIN_TEST_ID, REGULAR_USER_TEST_ID, STAFF_TEST_ID, @@ -250,6 +251,12 @@ export const createStaff = ( options?: Options, ) => createPinned(STAFF_TEST_ID, overrides, options); +/** The dev id user. Create after every unpinned user so the ids in between stay free. */ +export const createDev = ( + overrides?: Partial | null, + options?: Options, +) => createPinned(DEV_TEST_ID, overrides, options); + async function createPinned( pinnedId: number, overrides?: Partial | null, diff --git a/app/features/admin/AdminRepository.server.ts b/app/features/admin/AdminRepository.server.ts index f34851ecb..953f8e496 100644 --- a/app/features/admin/AdminRepository.server.ts +++ b/app/features/admin/AdminRepository.server.ts @@ -476,8 +476,6 @@ export async function forcePatron(args: { }) .where("User.id", "=", args.id) .execute(); - - await TrophyRepository.syncSpecialTrophies(); } export async function findAllBannedUsers() { diff --git a/app/features/calendar/actions/calendar.new.server.ts b/app/features/calendar/actions/calendar.new.server.ts index 66e815404..d8cb6ab51 100644 --- a/app/features/calendar/actions/calendar.new.server.ts +++ b/app/features/calendar/actions/calendar.new.server.ts @@ -12,7 +12,6 @@ import { tournamentFromDB, } from "~/features/tournament-bracket/core/Tournament.server"; import * as TrophyRepository from "~/features/trophies/TrophyRepository.server"; -import { canAccessTrophies } from "~/features/trophies/trophies-utils"; import { parseFormDataWithImages } from "~/form/parse.server"; import { requirePermission, @@ -78,10 +77,6 @@ export const action: ActionFunction = async ({ request }) => { } if (data.trophyId) { - if (!canAccessTrophies(user)) { - errorToast("Trophies are not released yet"); - } - const trophyOrganizationId = await TrophyRepository.findOrganizationIdById( data.trophyId, ); diff --git a/app/features/calendar/calendar-types.ts b/app/features/calendar/calendar-types.ts index cc2bb39c4..1aed473f7 100644 --- a/app/features/calendar/calendar-types.ts +++ b/app/features/calendar/calendar-types.ts @@ -28,6 +28,10 @@ interface CommonEvent { slug: string; } | null; authorId: number; + badges: Array< + Pick + > | null; + trophy: Pick | null; } export interface CalendarEvent extends CommonEvent { @@ -39,10 +43,6 @@ export interface CalendarEvent extends CommonEvent { normalizedTeamCount: number; /** For multi-day tournaments, which day of the event is this */ day?: number; - badges: Array< - Pick - > | null; - trophy: Pick | null; } export interface ShowcaseCalendarEvent extends CommonEvent { diff --git a/app/features/calendar/components/TournamentCard.tsx b/app/features/calendar/components/TournamentCard.tsx index 37df13eec..1a8064004 100644 --- a/app/features/calendar/components/TournamentCard.tsx +++ b/app/features/calendar/components/TournamentCard.tsx @@ -153,9 +153,8 @@ export function TournamentCard({ ) : null} {modes ? : null}
- {isCalendar && - (tournament.trophy || - (tournament.badges && tournament.badges.length > 0)) ? ( + {tournament.trophy || + (tournament.badges && tournament.badges.length > 0) ? ( { typeof org === "string" ? [] : [org.id], ); - const trophies = canAccessTrophies(user) - ? await TrophyRepository.findByOrganizationIds(validOrganizationIds) - : []; + const trophies = + await TrophyRepository.findByOrganizationIds(validOrganizationIds); const eventToCopy = eventToCopyRaw ? { diff --git a/app/features/calendar/loaders/calendar.server.ts b/app/features/calendar/loaders/calendar.server.ts index de8e5f613..c6c7c8bc6 100644 --- a/app/features/calendar/loaders/calendar.server.ts +++ b/app/features/calendar/loaders/calendar.server.ts @@ -7,7 +7,6 @@ import { getUser } from "~/features/auth/core/user.server"; import { DAYS_SHOWN_AT_A_TIME } from "~/features/calendar/calendar-constants"; import { calendarFiltersSearchParamsSchema } from "~/features/calendar/calendar-schemas"; import { calendarSearchParams } from "~/features/calendar/calendar-search-params"; -import { canAccessTrophies } from "~/features/trophies/trophies-utils"; import type { SerializeFrom } from "~/utils/remix"; import * as CalendarRepository from "../CalendarRepository.server"; import * as CalendarEvent from "../core/CalendarEvent"; @@ -54,24 +53,8 @@ export const loader = async (args: LoaderFunctionArgs) => { : CalendarEvent.defaultFilters(), ); - const eventTimes = canAccessTrophies(user) - ? filtered - : filtered.map((time) => ({ - ...time, - events: { - shown: time.events.shown.map((event) => ({ - ...event, - trophy: null, - })), - hidden: time.events.hidden.map((event) => ({ - ...event, - trophy: null, - })), - }, - })); - return { - eventTimes, + eventTimes: filtered, dateViewed, filters, canSaveAsDefault, diff --git a/app/features/front-page/core/ShowcaseTournaments.server.ts b/app/features/front-page/core/ShowcaseTournaments.server.ts index b93baf2aa..f8d1421da 100644 --- a/app/features/front-page/core/ShowcaseTournaments.server.ts +++ b/app/features/front-page/core/ShowcaseTournaments.server.ts @@ -316,6 +316,8 @@ function mapTournamentFromDB( minMembersPerTeam: tournament.settings.minMembersPerTeam ?? 4, modes: null, hasVods: (tournament.vodCount ?? 0) > 0, + badges: tournament.badges, + trophy: tournament.trophy, firstPlacers, }; } diff --git a/app/features/front-page/routes/index.tsx b/app/features/front-page/routes/index.tsx index 9beb9e783..ee5924c3d 100644 --- a/app/features/front-page/routes/index.tsx +++ b/app/features/front-page/routes/index.tsx @@ -23,7 +23,6 @@ import { SplatoonRotations } from "~/features/front-page/components/SplatoonRota import type * as Changelog from "~/features/front-page/core/Changelog.server"; import { leaderboardsPage } from "~/features/leaderboards/leaderboards-urls"; import * as Seasons from "~/features/mmr/core/Seasons"; -import { canAccessTrophies } from "~/features/trophies/trophies-utils"; import styles from "~/styles/front.module.css"; import { databaseTimestampToDate } from "~/utils/dates"; import type { SendouRouteHandle } from "~/utils/remix.server"; @@ -334,12 +333,9 @@ const DISCOVER_EXCLUDED_ITEMS = new Set(["settings", "luti"]); function DiscoverFeatures() { const { t } = useTranslation(["front", "common"]); const data = useLoaderData(); - const user = useUser(); const filteredNavItems = navItems.filter( - (item) => - !DISCOVER_EXCLUDED_ITEMS.has(item.name) && - (item.name !== "trophies" || canAccessTrophies(user)), + (item) => !DISCOVER_EXCLUDED_ITEMS.has(item.name), ); return ( diff --git a/app/features/top-search/XRankPlacementRepository.server.ts b/app/features/top-search/XRankPlacementRepository.server.ts index ec9d1d2a3..162023466 100644 --- a/app/features/top-search/XRankPlacementRepository.server.ts +++ b/app/features/top-search/XRankPlacementRepository.server.ts @@ -152,7 +152,11 @@ export async function findPlacementsByPlayerId( export async function findPlacementsByUserId( userId: Tables["User"]["id"], - options?: { limit?: number; weaponId?: MainWeaponId }, + options?: { + limit?: number; + weaponId?: MainWeaponId; + weaponIds?: readonly MainWeaponId[]; + }, ) { let query = xRankPlacementsQueryBase() .where("SplatoonPlayer.userId", "=", userId) @@ -162,6 +166,12 @@ export async function findPlacementsByUserId( query = query.where("XRankPlacement.weaponSplId", "=", options.weaponId); } + if (options?.weaponIds) { + query = query.where("XRankPlacement.weaponSplId", "in", [ + ...options.weaponIds, + ]); + } + if (options?.limit) { query = query.limit(options.limit); } diff --git a/app/features/tournament-organization/TournamentOrganizationRepository.server.ts b/app/features/tournament-organization/TournamentOrganizationRepository.server.ts index f078f6a78..efa3da073 100644 --- a/app/features/tournament-organization/TournamentOrganizationRepository.server.ts +++ b/app/features/tournament-organization/TournamentOrganizationRepository.server.ts @@ -15,6 +15,7 @@ import { dateToDatabaseTimestamp, } from "~/utils/dates"; import { + calendarEventNameMatchesSeries, commonUserSelect, concatUserSubmittedImagePrefix, jsonArrayFrom, @@ -437,15 +438,6 @@ export function findAllUnfinalizedEvents(organizationId: number) { .execute(); } -const nameMatchesSeries = - (substringMatches: string[]) => - (eb: ExpressionBuilder) => - eb.or( - substringMatches.map((match) => - eb("CalendarEvent.name", "like", `%${match}%`), - ), - ); - export async function findPaginatedEventsBySeries({ organizationId, substringMatches, @@ -467,7 +459,7 @@ export async function findPaginatedEventsBySeries({ .select("CalendarEvent.id") .where("CalendarEvent.organizationId", "=", organizationId) .where("CalendarEvent.hidden", "=", 0) - .where(nameMatchesSeries(substringMatches)) + .where(calendarEventNameMatchesSeries(substringMatches)) .groupBy("CalendarEvent.id") .orderBy(({ fn }) => fn.min("CalendarEventDate.startsAt"), "desc") .limit(TOURNAMENT_SERIES_EVENTS_PER_PAGE) @@ -507,7 +499,7 @@ export async function findAllEventsBySeries({ ]) .where("CalendarEvent.organizationId", "=", organizationId) .where("CalendarEvent.hidden", "=", 0) - .where(nameMatchesSeries(substringMatches)) + .where(calendarEventNameMatchesSeries(substringMatches)) .groupBy("CalendarEvent.id") .orderBy("CalendarEventDate.startsAt", "desc") .execute(); diff --git a/app/features/tournament-organization/loaders/org.$slug.server.ts b/app/features/tournament-organization/loaders/org.$slug.server.ts index 9c040df11..ad0fd1e77 100644 --- a/app/features/tournament-organization/loaders/org.$slug.server.ts +++ b/app/features/tournament-organization/loaders/org.$slug.server.ts @@ -2,7 +2,6 @@ import type { LoaderFunctionArgs } from "react-router"; import { getUser } from "~/features/auth/core/user.server"; import { calculateTentativeTier } from "~/features/tournament/core/tiering"; import * as TrophyRepository from "~/features/trophies/TrophyRepository.server"; -import { canAccessTrophies } from "~/features/trophies/trophies-utils"; import type { SerializeFrom } from "~/utils/remix"; import { eventLeaderboards } from "../core/leaderboards.server"; import * as TournamentOrganizationRepository from "../TournamentOrganizationRepository.server"; @@ -79,9 +78,7 @@ export async function loader({ params, request }: LoaderFunctionArgs) { series: await seriesInfo(), month, year, - trophies: canAccessTrophies(user) - ? await TrophyRepository.findByOrganizationId(organization.id) - : [], + trophies: await TrophyRepository.findByOrganizationId(organization.id), bannedUsers: user?.id && organization.permissions.BAN.includes(user.id) ? await TournamentOrganizationRepository.findAllBannedUsersByOrganizationId( diff --git a/app/features/tournament/TournamentRepository.server.ts b/app/features/tournament/TournamentRepository.server.ts index 84e24d405..46949d15e 100644 --- a/app/features/tournament/TournamentRepository.server.ts +++ b/app/features/tournament/TournamentRepository.server.ts @@ -3,7 +3,6 @@ import { type Insertable, type Kysely, type NotNull, - type SqlBool, sql, type Transaction, } from "kysely"; @@ -26,6 +25,7 @@ import type { TournamentTrophyReceiver, } from "~/features/tournament-bracket/tournament-bracket-schemas"; import type { TournamentOrganizationRole } from "~/features/tournament-organization/tournament-organization-constants"; +import * as TrophyRepository from "~/features/trophies/TrophyRepository.server"; import { modesShort } from "~/modules/in-game-lists/modes"; import { isSupporter } from "~/modules/permissions/utils"; import { nullFilledArray, nullifyingAvg } from "~/utils/arrays"; @@ -836,6 +836,20 @@ export function findAllForShowcase() { "CalendarEvent.organizationId", ), ).as("organization"), + jsonArrayFrom( + eb + .selectFrom("CalendarEventBadge") + .innerJoin("Badge", "CalendarEventBadge.badgeId", "Badge.id") + .select(["Badge.id", "Badge.code", "Badge.hue", "Badge.displayName"]) + .whereRef("CalendarEventBadge.eventId", "=", "CalendarEvent.id") + .orderBy("Badge.id", "asc"), + ).as("badges"), + jsonObjectFrom( + eb + .selectFrom("Trophy") + .select(["Trophy.model"]) + .whereRef("Trophy.id", "=", "CalendarEvent.trophyId"), + ).as("trophy"), jsonArrayFrom( eb .selectFrom("TournamentResult") @@ -1663,28 +1677,20 @@ export function finalize({ ); await trx.insertInto("TournamentBadgeOwner").values(badgeOwners).execute(); - if (trophyReceiver && trophyReceiver.userIds.length > 0) { - const tier = await trophyTier(trx, { - tournamentId, - tournamentTeamId: summary.tournamentResults.find((result) => - trophyReceiver.userIds.includes(result.userId), - )?.tournamentTeamId, - }); - - await trx - .insertInto("TrophyOwner") - .values( - trophyReceiver.userIds.map((userId) => ({ + if (trophyReceiver) { + await TrophyRepository.insertTournamentOwners( + [ + { tournamentId, + tournamentTeamId: summary.tournamentResults.find((result) => + trophyReceiver.userIds.includes(result.userId), + )?.tournamentTeamId, trophyId: trophyReceiver.trophyId, - userId, - tier, - })), - ) - .onConflict((oc) => - oc.columns(["tournamentId", "userId", "trophyId"]).doNothing(), - ) - .execute(); + userIds: trophyReceiver.userIds, + }, + ], + trx, + ); } const tournamentResults = summary.tournamentResults @@ -1945,41 +1951,6 @@ export async function findRunningTournamentIds() { return rows.map((row) => row.id); } -/** Tier of the winning team's division, falling back to the tournament's tier when unknown or never tiered. */ -async function trophyTier( - trx: Transaction, - { - tournamentId, - tournamentTeamId, - }: { tournamentId: number; tournamentTeamId?: number }, -) { - const divisionTier = tournamentTeamId - ? await trx - .selectFrom("TournamentDivisionTier") - .innerJoin( - "TournamentTeam", - "TournamentTeam.tournamentId", - "TournamentDivisionTier.tournamentId", - ) - .select("TournamentDivisionTier.tier") - .where("TournamentTeam.id", "=", tournamentTeamId) - .where( - sql`"TournamentDivisionTier"."bracketIdx" = coalesce("TournamentTeam"."startingBracketIdx", 0)`, - ) - .executeTakeFirst() - : undefined; - - if (divisionTier) return divisionTier.tier; - - const tournament = await trx - .selectFrom("Tournament") - .select("tier") - .where("id", "=", tournamentId) - .executeTakeFirst(); - - return tournament?.tier ?? null; -} - /** Which seeding skill the tournament ranks by, resolved once: inline in the join it parsed the settings JSON per member row. */ function seedingSkillType(tournamentId: number) { return sql< diff --git a/app/features/trophies/TrophyRepository.server.test.ts b/app/features/trophies/TrophyRepository.server.test.ts index 18ea9cdba..1a3ba659f 100644 --- a/app/features/trophies/TrophyRepository.server.test.ts +++ b/app/features/trophies/TrophyRepository.server.test.ts @@ -3,9 +3,13 @@ import * as TournamentFactory from "~/db/seed/factories/TournamentFactory"; import * as TournamentOrganizationFactory from "~/db/seed/factories/TournamentOrganizationFactory"; import * as TrophyFactory from "~/db/seed/factories/TrophyFactory"; import * as UserFactory from "~/db/seed/factories/UserFactory"; +import * as XRankPlacementFactory from "~/db/seed/factories/XRankPlacementFactory"; import { db } from "~/db/sql"; import type { TournamentTierNumber } from "~/features/tournament/core/tiering"; +import type { MainWeaponId } from "~/modules/in-game-lists/types"; import { dateToDatabaseTimestamp } from "~/utils/dates"; +import { ConcurrentModificationError } from "~/utils/errors"; +import * as XpTrophy from "./core/XpTrophy"; import * as TrophyRepository from "./TrophyRepository.server"; import { TROPHY_APPROVALS_REQUIRED } from "./trophies-constants"; @@ -424,3 +428,273 @@ async function trophyCount() { const daysFromNow = (days: number) => new Date(Date.now() + days * 24 * 60 * 60 * 1000); + +describe("backfill", () => { + const users = UserFactory.pool(); + const winnerIds = () => users.ids(4); + + beforeEach(async () => { + await users.create(8); + }); + + const createFinalized = ( + overrides: Partial[0]> = {}, + ) => + TournamentFactory.createPlayed( + { authorId: users.id(1), ...overrides }, + { + tier: 3, + teamRosters: [winnerIds(), users.ids(8).slice(4)], + playedOut: "all", + }, + ); + + const ownersOf = (trophyId: number) => + db + .selectFrom("TrophyOwner") + .select([ + "TrophyOwner.tournamentId", + "TrophyOwner.userId", + "TrophyOwner.tier", + ]) + .where("TrophyOwner.trophyId", "=", trophyId) + .orderBy("TrophyOwner.userId", "asc") + .execute(); + + test("links the trophy to the tournament and awards the chosen players at its tier", async () => { + const trophy = await TrophyFactory.create(); + const tournament = await createFinalized(); + + await TrophyRepository.backfill({ + trophyId: trophy.id, + awards: [ + { + tournamentId: tournament.id, + tournamentTeamId: tournament.teams[0].id, + userIds: winnerIds().slice(0, 2), + }, + ], + }); + + expect( + (await TrophyRepository.findTournamentsByTrophyId(trophy.id)).map( + (row) => row.tournamentId, + ), + ).toEqual([tournament.id]); + expect(await ownersOf(trophy.id)).toEqual( + winnerIds() + .slice(0, 2) + .map((userId) => ({ tournamentId: tournament.id, userId, tier: 3 })), + ); + }); + + test("awards nothing when one of the tournaments already has a trophy", async () => { + const trophy = await TrophyFactory.create(); + const otherTrophy = await TrophyFactory.create(); + const withoutTrophy = await createFinalized(); + const withTrophy = await createFinalized({ trophyId: otherTrophy.id }); + + await expect( + TrophyRepository.backfill({ + trophyId: trophy.id, + awards: [withoutTrophy, withTrophy].map((tournament) => ({ + tournamentId: tournament.id, + tournamentTeamId: tournament.teams[0].id, + userIds: winnerIds(), + })), + }), + ).rejects.toThrow(ConcurrentModificationError); + + expect(await TrophyRepository.findTournamentsByTrophyId(trophy.id)).toEqual( + [], + ); + expect(await ownersOf(trophy.id)).toEqual([]); + }); +}); + +describe("X Power trophies", () => { + const SPLATTERSHOT = 40; + const SPLASH_O_MATIC = 20; + const SPLAT_CHARGER = 2010; + + const users = UserFactory.pool(); + const playerId = () => users.id(1); + const otherPlayerId = () => users.id(2); + + let trophyIdByCode: Map; + + beforeEach(async () => { + await users.create(2); + trophyIdByCode = new Map( + (await TrophyFactory.createXpTrophies()).map((trophy) => [ + trophy.code, + trophy.id, + ]), + ); + }); + + const place = (args: { + userId?: number; + weaponSplId: MainWeaponId; + power: number; + region?: "WEST" | "JPN"; + }) => + XRankPlacementFactory.create({ + playerUserId: args.userId, + playerSplId: args.userId ? undefined : "unlinked-player", + weaponSplId: args.weaponSplId, + power: args.power, + ...(args.region ? { region: args.region } : {}), + }); + + const ownedCodes = async (userId: number) => + ( + await db + .selectFrom("SpecialTrophyOwner") + .innerJoin("Trophy", "Trophy.id", "SpecialTrophyOwner.trophyId") + .select("Trophy.code") + .where("SpecialTrophyOwner.userId", "=", userId) + .orderBy("Trophy.code", "asc") + .execute() + ).map((row) => row.code); + + describe("syncSpecialTrophies", () => { + test("awards the highest milestone reached per weapon category", async () => { + await place({ + userId: playerId(), + weaponSplId: SPLATTERSHOT, + power: 3100, + }); + await place({ + userId: playerId(), + weaponSplId: SPLASH_O_MATIC, + power: 3520, + }); + await place({ + userId: playerId(), + weaponSplId: SPLAT_CHARGER, + power: 3210, + }); + + await TrophyRepository.syncSpecialTrophies(); + + expect(await ownedCodes(playerId())).toEqual([ + "xp-chargers-3200", + "xp-shooters-3500", + ]); + }); + + test("awards nothing below the lowest milestone", async () => { + await place({ + userId: playerId(), + weaponSplId: SPLATTERSHOT, + power: 2999, + }); + + await TrophyRepository.syncSpecialTrophies(); + + expect(await ownedCodes(playerId())).toEqual([]); + }); + + test("awards nothing for placements of players no user linked", async () => { + await place({ weaponSplId: SPLATTERSHOT, power: 3600 }); + + await TrophyRepository.syncSpecialTrophies(); + + expect( + await db.selectFrom("SpecialTrophyOwner").select("userId").execute(), + ).toEqual([]); + }); + + test("moves an owner up when they reach a higher milestone", async () => { + await place({ + userId: playerId(), + weaponSplId: SPLATTERSHOT, + power: 3100, + }); + await TrophyRepository.syncSpecialTrophies(); + + await place({ + userId: playerId(), + weaponSplId: SPLATTERSHOT, + power: 3300, + }); + await TrophyRepository.syncSpecialTrophies(); + + expect(await ownedCodes(playerId())).toEqual(["xp-shooters-3200"]); + }); + }); + + describe("findByOwnerUserId", () => { + test("shows the division each X Power trophy was won in, Takoroka over Tentatek", async () => { + await place({ + userId: playerId(), + weaponSplId: SPLATTERSHOT, + power: 3620, + region: "WEST", + }); + await place({ + userId: playerId(), + weaponSplId: SPLASH_O_MATIC, + power: 3540, + region: "JPN", + }); + await place({ + userId: playerId(), + weaponSplId: SPLAT_CHARGER, + power: 3050, + region: "WEST", + }); + await TrophyRepository.syncSpecialTrophies(); + + const trophies = await TrophyRepository.findByOwnerUserId(playerId()); + + expect( + trophies + .map((trophy) => ({ code: trophy.code, division: trophy.division })) + .toSorted((a, b) => (a.code ?? "").localeCompare(b.code ?? "")), + ).toEqual([ + { code: "xp-chargers-3000", division: "WEST" }, + { code: "xp-shooters-3500", division: "JPN" }, + ]); + }); + }); + + describe("findXpWeaponCountsById", () => { + test("counts the owners who reached the milestone with each weapon", async () => { + await place({ + userId: playerId(), + weaponSplId: SPLATTERSHOT, + power: 3550, + }); + await place({ + userId: playerId(), + weaponSplId: SPLASH_O_MATIC, + power: 3510, + }); + await place({ + userId: otherPlayerId(), + weaponSplId: SPLATTERSHOT, + power: 3600, + }); + // below the milestone, so not what got them the trophy + await place({ + userId: otherPlayerId(), + weaponSplId: SPLASH_O_MATIC, + power: 3100, + }); + await TrophyRepository.syncSpecialTrophies(); + + const counts = await TrophyRepository.findXpWeaponCountsById({ + trophyId: trophyIdByCode.get("xp-shooters-3500")!, + weaponIds: XpTrophy.categoryWeaponIds("shooters"), + milestone: 3500, + }); + + expect(counts).toEqual([ + { weaponSplId: SPLATTERSHOT, ownerCount: 2 }, + { weaponSplId: SPLASH_O_MATIC, ownerCount: 1 }, + ]); + }); + }); +}); diff --git a/app/features/trophies/TrophyRepository.server.ts b/app/features/trophies/TrophyRepository.server.ts index 1f98a9045..64d10a0ae 100644 --- a/app/features/trophies/TrophyRepository.server.ts +++ b/app/features/trophies/TrophyRepository.server.ts @@ -1,33 +1,35 @@ import { sub } from "date-fns"; -import type { ExpressionBuilder, NotNull, Transaction } from "kysely"; +import { + type ExpressionBuilder, + type NotNull, + type SqlBool, + sql, + type Transaction, +} from "kysely"; import * as R from "remeda"; import { db } from "~/db/sql"; import type { DB } from "~/db/tables"; -import { isSupporter } from "~/modules/permissions/utils"; +import { DEV_IDS } from "~/features/admin/admin-constants"; +import type { MainWeaponId } from "~/modules/in-game-lists/types"; import { databaseTimestampToDate, dateToDatabaseTimestamp, } from "~/utils/dates"; +import { ConcurrentModificationError } from "~/utils/errors"; import { + calendarEventNameMatchesSeries, calendarEventStartTime, commonUserSelect, jsonArrayFrom, jsonObjectFrom, - peakXpOverallSql, tournamentLogoWithDefault, tournamentTeamCount, } from "~/utils/kysely.server"; import { getTentativeTier } from "../tournament-organization/core/tentativeTiers.server"; import { sortTrophiesByFavorites } from "../user-page/core/trophy-sorting.server"; -import { - SUPPORTER_TROPHY_CODE, - TROPHY_APPROVALS_REQUIRED, - XP_TROPHY_CODE_PREFIX, -} from "./trophies-constants"; -import { - hasUpcomingTournamentSoon, - parseSpecialTrophyCode, -} from "./trophies-utils"; +import * as XpTrophy from "./core/XpTrophy"; +import { TROPHY_APPROVALS_REQUIRED } from "./trophies-constants"; +import { hasUpcomingTournamentSoon } from "./trophies-utils"; type TrophyRecentTournament = { tier: number | null; @@ -36,10 +38,12 @@ type TrophyRecentTournament = { startTime: number | null; }; +/** Tournament trophies, special ones are listed by their own functions. */ export async function all() { const rows = await db .selectFrom("Trophy") .select((eb) => ["id", "name", "model", withRecentTournaments(eb)]) + .where("code", "is", null) .execute(); return sortByEffectiveTier(rows.map(addEffectiveTier)); @@ -233,9 +237,35 @@ async function findOwnedTrophies(userId: number) { .where("SpecialTrophyOwner.userId", "=", userId) .execute(); + const xpPlacements = specialRows.some((row) => XpTrophy.parseCode(row.code)) + ? await db + .selectFrom("XRankPlacement") + .innerJoin( + "SplatoonPlayer", + "SplatoonPlayer.id", + "XRankPlacement.playerId", + ) + .select([ + "XRankPlacement.weaponSplId", + "XRankPlacement.power", + "XRankPlacement.region", + ]) + .where("SplatoonPlayer.userId", "=", userId) + .execute() + : []; + return [ - ...tournamentRows, - ...specialRows.map((row) => ({ ...row, count: 1, tier: null })), + ...tournamentRows.map((row) => ({ ...row, division: null })), + ...specialRows.map((row) => { + const xpVariant = XpTrophy.parseCode(row.code); + + return { + ...row, + count: 1, + tier: null, + division: xpVariant ? XpTrophy.division(xpPlacements, xpVariant) : null, + }; + }), ]; } @@ -275,6 +305,7 @@ export async function findById(trophyId: number) { "Trophy.name", "Trophy.model", "Trophy.code", + "Trophy.organizationId", withCreator(eb), withManager(eb), withOrganization(eb), @@ -291,9 +322,7 @@ export async function findById(trophyId: number) { return { ...trophy, owners: [...trophy.owners, ...specialOwners], - permissions: { - EDIT: trophy.manager ? [trophy.manager.id] : [], - }, + permissions: trophyPermissions(trophy.manager?.id ?? null), }; } @@ -491,91 +520,218 @@ export async function existsByName(args: { return Boolean(pending); } -export async function findManagedBy(userId: number) { +export function findAllXp() { return db .selectFrom("Trophy") - .select(["id", "name", "model", "organizationId", "managerId", "creatorId"]) - .where("managerId", "=", userId) + .select(["Trophy.id", "Trophy.name", "Trophy.model", "Trophy.code"]) + .where("Trophy.code", "like", XpTrophy.CODE_LIKE_PATTERN) + .execute(); +} + +export async function findCodeById(trophyId: number) { + const row = await db + .selectFrom("Trophy") + .select("Trophy.code") + .where("Trophy.id", "=", trophyId) + .executeTakeFirst(); + + return row?.code ?? null; +} + +export function findXpWeaponCountsById({ + trophyId, + weaponIds, + milestone, +}: { + trophyId: number; + weaponIds: readonly MainWeaponId[]; + milestone: number; +}) { + return db + .selectFrom("XRankPlacement") + .innerJoin("SplatoonPlayer", "SplatoonPlayer.id", "XRankPlacement.playerId") + .innerJoin("SpecialTrophyOwner", (join) => + join + .onRef("SpecialTrophyOwner.userId", "=", "SplatoonPlayer.userId") + .on("SpecialTrophyOwner.trophyId", "=", trophyId), + ) + .select(({ fn }) => [ + "XRankPlacement.weaponSplId", + fn.count("SplatoonPlayer.userId").distinct().as("ownerCount"), + ]) + .where("XRankPlacement.weaponSplId", "in", [...weaponIds]) + .where("XRankPlacement.power", ">=", milestone) + .groupBy("XRankPlacement.weaponSplId") + .orderBy("ownerCount", "desc") + .orderBy("XRankPlacement.weaponSplId", "asc") .execute(); } export async function findAllForEditing() { - return db + const rows = await db .selectFrom("Trophy") .select(["id", "name", "model", "organizationId", "managerId", "creatorId"]) .where("code", "is", null) .execute(); + + return rows.map((row) => ({ + ...row, + permissions: trophyPermissions(row.managerId), + })); } -/** Recomputes special trophy (supporter, XP) ownership; still-eligible owners keep their `createdAt`. */ +export function findAllBackfillableTournaments({ + organizationId, + substringMatches, +}: { + organizationId: number; + substringMatches: string[]; +}) { + return db + .selectFrom("CalendarEvent") + .innerJoin("Tournament", "Tournament.id", "CalendarEvent.tournamentId") + .select((eb) => [ + "Tournament.id as tournamentId", + "Tournament.settings", + "CalendarEvent.name", + tournamentLogoWithDefault(eb).as("logoUrl"), + calendarEventStartTime(eb).as("startTime"), + jsonArrayFrom( + eb + .selectFrom("TournamentResult") + .innerJoin("User", "User.id", "TournamentResult.userId") + .innerJoin( + "TournamentTeam", + "TournamentTeam.id", + "TournamentResult.tournamentTeamId", + ) + .select((resultEb) => [ + ...commonUserSelect(resultEb), + "TournamentResult.tournamentTeamId", + "TournamentResult.div", + "TournamentResult.setResults", + "TournamentTeam.name as teamName", + ]) + .whereRef("TournamentResult.tournamentId", "=", "Tournament.id") + .where("TournamentResult.placement", "=", 1) + .orderBy("User.id", "asc"), + ).as("firstPlacers"), + ]) + .where("CalendarEvent.organizationId", "=", organizationId) + .where("CalendarEvent.hidden", "=", 0) + .where("CalendarEvent.trophyId", "is", null) + .where("Tournament.isFinalized", "=", 1) + .where(calendarEventNameMatchesSeries(substringMatches)) + .orderBy("startTime", "desc") + .execute(); +} + +type TournamentOwnersArgs = { + tournamentId: number; + tournamentTeamId?: number; + trophyId: number; + userIds: number[]; +}; + +export async function insertTournamentOwners( + awards: TournamentOwnersArgs[], + trx: Transaction, +) { + const tieredAwards: Array< + TournamentOwnersArgs & { tier: Awaited> } + > = []; + for (const award of awards) { + tieredAwards.push({ ...award, tier: await trophyTier(trx, award) }); + } + + const rows = tieredAwards.flatMap( + ({ tournamentId, trophyId, userIds, tier }) => + userIds.map((userId) => ({ tournamentId, trophyId, userId, tier })), + ); + if (rows.length === 0) return; + + await trx + .insertInto("TrophyOwner") + .values(rows) + .onConflict((oc) => + oc.columns(["tournamentId", "userId", "trophyId"]).doNothing(), + ) + .execute(); +} + +export function backfill({ + trophyId, + awards, +}: { + trophyId: number; + awards: Array>; +}) { + return db.transaction().execute(async (trx) => { + const tournamentIds = awards.map((award) => award.tournamentId); + + const { numUpdatedRows } = await trx + .updateTable("CalendarEvent") + .set({ trophyId }) + .where("CalendarEvent.tournamentId", "in", tournamentIds) + .where("CalendarEvent.trophyId", "is", null) + .executeTakeFirst(); + + if (Number(numUpdatedRows) !== tournamentIds.length) { + throw new ConcurrentModificationError( + "A tournament to backfill already has a trophy", + ); + } + + await insertTournamentOwners( + awards.map((award) => ({ ...award, trophyId })), + trx, + ); + }); +} + +/** + * Recomputes X Power trophy ownership from the Top 500 placements of linked players (see + * {@link XpTrophy.awards}). Still-eligible owners keep their `createdAt`. + */ export function syncSpecialTrophies() { return db.transaction().execute(async (trx) => { - await syncSupporterTrophyOwners(trx); - await syncXpTrophyOwners(trx); - }); -} - -async function syncSupporterTrophyOwners(trx: Transaction) { - const trophy = await trx - .selectFrom("Trophy") - .select("id") - .where("code", "=", SUPPORTER_TROPHY_CODE) - .executeTakeFirst(); - - if (!trophy) return; - - const patrons = await trx - .selectFrom("User") - .select(["id", "patronTier"]) - .where("patronTier", "is not", null) - .execute(); - - await replaceSpecialTrophyOwners({ - trx, - trophyId: trophy.id, - userIds: patrons.filter(isSupporter).map((patron) => patron.id), - }); -} - -async function syncXpTrophyOwners(trx: Transaction) { - const xpTrophies = ( - await trx + const trophies = await trx .selectFrom("Trophy") - .select(["id", "code"]) - .where("code", "like", `${XP_TROPHY_CODE_PREFIX}%`) - .execute() - ).flatMap((trophy) => { - const parsed = parseSpecialTrophyCode(trophy.code); - return parsed?.type === "xp" - ? [{ id: trophy.id, value: parsed.value }] - : []; + .select(["Trophy.id", "Trophy.code"]) + .where("Trophy.code", "like", XpTrophy.CODE_LIKE_PATTERN) + .execute(); + if (trophies.length === 0) return; + + const placements = await trx + .selectFrom("XRankPlacement") + .innerJoin( + "SplatoonPlayer", + "SplatoonPlayer.id", + "XRankPlacement.playerId", + ) + .select(({ fn }) => [ + "SplatoonPlayer.userId", + "XRankPlacement.weaponSplId", + fn.max("XRankPlacement.power").as("power"), + ]) + .where("SplatoonPlayer.userId", "is not", null) + .groupBy(["SplatoonPlayer.userId", "XRankPlacement.weaponSplId"]) + .$narrowType<{ userId: NotNull }>() + .execute(); + + const ownerIdsByCode = R.mapValues( + R.groupBy(XpTrophy.awards(placements), (award) => award.code), + (awards) => awards.map((award) => award.userId), + ); + + for (const trophy of trophies) { + await replaceSpecialTrophyOwners({ + trx, + trophyId: trophy.id, + userIds: (trophy.code ? ownerIdsByCode[trophy.code] : undefined) ?? [], + }); + } }); - - if (xpTrophies.length === 0) return; - - const byValueDesc = R.sortBy(xpTrophies, [(trophy) => trophy.value, "desc"]); - - const userPeakXps = await trx - .selectFrom("SplatoonPlayer") - .select(["userId", peakXpOverallSql().as("peakXp")]) - .where("userId", "is not", null) - .where("peakXp", "is not", null) - .$narrowType<{ userId: NotNull; peakXp: NotNull }>() - .execute(); - - const ownersByTrophyId = new Map( - xpTrophies.map((trophy) => [trophy.id, []]), - ); - for (const { userId, peakXp } of userPeakXps) { - const highestReached = byValueDesc.find((trophy) => peakXp >= trophy.value); - if (!highestReached) continue; - - ownersByTrophyId.get(highestReached.id)?.push(userId); - } - - for (const [trophyId, userIds] of ownersByTrophyId) { - await replaceSpecialTrophyOwners({ trx, trophyId, userIds }); - } } async function replaceSpecialTrophyOwners({ @@ -595,6 +751,8 @@ async function replaceSpecialTrophyOwners({ } await deleteStale.execute(); + if (userIds.length === 0) return; + await trx .insertInto("SpecialTrophyOwner") .values( @@ -903,3 +1061,43 @@ export async function addApproval(args: { .executeTakeFirstOrThrow(); }); } + +async function trophyTier( + trx: Transaction, + { + tournamentId, + tournamentTeamId, + }: { tournamentId: number; tournamentTeamId?: number }, +) { + const divisionTier = tournamentTeamId + ? await trx + .selectFrom("TournamentDivisionTier") + .innerJoin( + "TournamentTeam", + "TournamentTeam.tournamentId", + "TournamentDivisionTier.tournamentId", + ) + .select("TournamentDivisionTier.tier") + .where("TournamentTeam.id", "=", tournamentTeamId) + .where( + sql`"TournamentDivisionTier"."bracketIdx" = coalesce("TournamentTeam"."startingBracketIdx", 0)`, + ) + .executeTakeFirst() + : undefined; + + if (divisionTier) return divisionTier.tier; + + const tournament = await trx + .selectFrom("Tournament") + .select("tier") + .where("id", "=", tournamentId) + .executeTakeFirst(); + + return tournament?.tier ?? null; +} + +function trophyPermissions(managerId: number | null) { + return { + EDIT: R.unique([...(managerId ? [managerId] : []), ...DEV_IDS]), + }; +} diff --git a/app/features/trophies/actions/trophies.new.server.test.ts b/app/features/trophies/actions/trophies.new.server.test.ts new file mode 100644 index 000000000..826436ec5 --- /dev/null +++ b/app/features/trophies/actions/trophies.new.server.test.ts @@ -0,0 +1,213 @@ +import type * as v from "valibot"; +import { beforeEach, describe, expect, test } from "vitest"; +import { DEV_TEST_ID } from "~/db/seed/constants"; +import * as TournamentFactory from "~/db/seed/factories/TournamentFactory"; +import * as TournamentOrganizationFactory from "~/db/seed/factories/TournamentOrganizationFactory"; +import * as TrophyFactory from "~/db/seed/factories/TrophyFactory"; +import * as UserFactory from "~/db/seed/factories/UserFactory"; +import * as TournamentOrganizationRepository from "~/features/tournament-organization/TournamentOrganizationRepository.server"; +import { decompressFromBase64 } from "~/utils/compression"; +import { + assertResponseErrored, + type TestUser, + wrappedAction, + wrappedLoader, +} from "~/utils/Test"; +import { + loader as backfillLoader, + type TrophyBackfillLoaderData, +} from "../routes/trophies.$id.backfill.$seriesId"; +import * as TrophyRepository from "../TrophyRepository.server"; +import type { trophyFormSchema } from "../trophies-schemas"; +import { action } from "./trophies.new.server"; + +type BackfillFormFields = { + _action: "BACKFILL"; + trophyId: number; + seriesId: number; + awards: string; +}; + +const submitAction = wrappedAction({ + action, + isJsonSubmission: true, +}); +const backfillAction = wrappedAction>({ + action, +}); +const loadBackfillable = wrappedLoader({ + loader: backfillLoader, +}); + +const users = UserFactory.pool(); +const managerId = () => users.id(1); +const winnerIds = () => users.ids(5).slice(1, 5); +const loserIds = () => users.ids(9).slice(5, 9); + +describe("trophy submissions", () => { + const submitterId = () => users.id(1); + const artistId = () => users.id(2); + + let organizationId: number; + + beforeEach(async () => { + await users.create(2); + organizationId = ( + await TournamentOrganizationFactory.create({ ownerId: submitterId() }) + ).id; + }); + + const submit = (overrides: { name: string; creatorId?: number }) => + submitAction( + { + _action: "CREATE", + model: decompressFromBase64(TrophyFactory.MODELS[0]) ?? "", + organizationId, + description: null, + ...overrides, + }, + { user: submitterId() }, + ); + + test("a submission awaits review with the submitter as its creator", async () => { + expect(await submit({ name: "Regular Trophy" })).toBe(null); + + const pending = await TrophyRepository.pendingBySubmitter(submitterId()); + expect(pending.map((trophy) => trophy.name)).toEqual(["Regular Trophy"]); + expect(pending[0].creatorId).toBe(submitterId()); + }); + + test("a submission can name someone else as the creator", async () => { + expect( + await submit({ name: "Commissioned Trophy", creatorId: artistId() }), + ).toBe(null); + + const [pending] = await TrophyRepository.pendingBySubmitter(submitterId()); + expect(pending.creatorId).toBe(artistId()); + expect(pending.creator?.id).toBe(artistId()); + }); +}); + +describe("trophy backfill", () => { + let trophyId: number; + let seriesId: number; + let tournamentId: number; + + beforeEach(async () => { + await UserFactory.createAdmin(); + await users.create(9); + await UserFactory.createDev(); + + const organization = await TournamentOrganizationFactory.create( + { ownerId: managerId() }, + { + series: [ + { name: "Weekly Cup", description: null, showLeaderboard: false }, + ], + }, + ); + const [series] = + await TournamentOrganizationRepository.findAllSeriesByOrganizationIds([ + organization.id, + ]); + seriesId = series.id; + + trophyId = ( + await TrophyFactory.create({ + organizationId: organization.id, + managerId: managerId(), + }) + ).id; + + tournamentId = ( + await TournamentFactory.createPlayed( + { + authorId: managerId(), + name: "Weekly Cup #1", + organizationId: organization.id, + }, + { teamRosters: [winnerIds(), loserIds()], playedOut: "all" }, + ) + ).id; + }); + + const backfill = (userIds: number[], user: TestUser = "admin") => + backfillAction( + { + _action: "BACKFILL", + trophyId, + seriesId, + awards: JSON.stringify([{ tournamentId, userIds }]), + }, + { user }, + ); + + const awardedTournamentIds = async () => + (await TrophyRepository.findTournamentsByTrophyId(trophyId)).map( + (tournament) => tournament.tournamentId, + ); + + test("an admin lists the series' tournaments with their winners", async () => { + const data = await loadBackfillable({ + user: "admin", + params: { id: String(trophyId), seriesId: String(seriesId) }, + }); + + expect( + data.tournaments.map((tournament) => tournament.tournamentId), + ).toEqual([tournamentId]); + expect(data.tournaments[0].winners.map((winner) => winner.id)).toEqual( + winnerIds(), + ); + }); + + test("the trophy's manager can't list the tournaments", async () => { + await expect( + loadBackfillable({ + user: managerId(), + params: { id: String(trophyId), seriesId: String(seriesId) }, + }), + ).rejects.toThrow("403"); + }); + + test("an admin awards the trophy to the chosen winners", async () => { + await backfill(winnerIds().slice(0, 3)); + + expect(await awardedTournamentIds()).toEqual([tournamentId]); + + const ownerIds = (await TrophyRepository.findById(trophyId))?.owners.map( + (owner) => owner.id, + ); + expect(ownerIds?.toSorted((a, b) => a - b)).toEqual( + winnerIds().slice(0, 3), + ); + }); + + test("a dev awards the trophy", async () => { + await backfill(winnerIds(), DEV_TEST_ID); + + expect(await awardedTournamentIds()).toEqual([tournamentId]); + }); + + test("the trophy's manager can't award it", async () => { + const response = await backfill(winnerIds(), managerId()); + + assertResponseErrored(response, "Not allowed"); + expect(await awardedTournamentIds()).toEqual([]); + }); + + test("a player who didn't win the tournament can't receive the trophy", async () => { + const response = await backfill([winnerIds()[0], loserIds()[0]]); + + assertResponseErrored(response, "Only the winners"); + expect(await awardedTournamentIds()).toEqual([]); + }); + + test("a tournament can't be awarded twice", async () => { + await backfill(winnerIds()); + + const response = await backfill(winnerIds()); + + assertResponseErrored(response, "can't be backfilled"); + }); +}); diff --git a/app/features/trophies/actions/trophies.new.server.ts b/app/features/trophies/actions/trophies.new.server.ts index 3970b7cb2..8721f60bb 100644 --- a/app/features/trophies/actions/trophies.new.server.ts +++ b/app/features/trophies/actions/trophies.new.server.ts @@ -4,22 +4,32 @@ import { type AuthenticatedUser, requireUser, } from "~/features/auth/core/user.server"; +import * as ShowcaseTournaments from "~/features/front-page/core/ShowcaseTournaments.server"; import { notify } from "~/features/notifications/core/notify.server"; import { resolveNotifications } from "~/features/notifications/core/resolve.server"; import { clearTrophiesCache } from "~/features/trophies/loaders/trophies.server"; import * as UserRepository from "~/features/user-page/UserRepository.server"; import { parseFormData } from "~/form/parse.server"; import { requirePermission } from "~/modules/permissions/guards.server"; -import { errorToastIfFalsy, parseRequestPayload } from "~/utils/remix.server"; +import { ConcurrentModificationError } from "~/utils/errors"; +import { logger } from "~/utils/logger"; +import { + errorToast, + errorToastIfFalsy, + parseRequestPayload, + successToast, +} from "~/utils/remix.server"; import { assertUnreachable } from "~/utils/types"; import { stripDisabledEffects } from "../core/model-analysis"; +import * as TrophyBackfill from "../core/TrophyBackfill.server"; import * as TrophyRepository from "../TrophyRepository.server"; import { TROPHY_PENDING_PER_USER_LIMIT } from "../trophies-constants"; +import { trophyActionSchema, trophyFormSchema } from "../trophies-schemas"; import { - pendingTrophyActionSchema, - trophyFormSchema, -} from "../trophies-schemas"; -import { canReviewTrophies, compressTrophyModel } from "../trophies-utils"; + canBackfillTrophies, + canReviewTrophies, + compressTrophyModel, +} from "../trophies-utils"; export const action: ActionFunction = async ({ request }) => { const user = requireUser(); @@ -104,7 +114,7 @@ export const action: ActionFunction = async ({ request }) => { const data = await parseRequestPayload({ request, - schema: pendingTrophyActionSchema, + schema: trophyActionSchema, }); switch (data._action) { @@ -205,6 +215,58 @@ export const action: ActionFunction = async ({ request }) => { return null; } + case "BACKFILL": { + errorToastIfFalsy(canBackfillTrophies(user), "Not allowed"); + + const trophy = await TrophyRepository.findById(data.trophyId); + errorToastIfFalsy(trophy, "Trophy not found"); + errorToastIfFalsy(trophy.organizationId, "Trophy has no organization"); + + const tournaments = await TrophyBackfill.backfillableTournaments({ + organizationId: trophy.organizationId, + seriesId: data.seriesId, + }); + errorToastIfFalsy(tournaments, "Series not found"); + + const awards = data.awards.map((award) => { + const tournament = tournaments.find( + (candidate) => candidate.tournamentId === award.tournamentId, + ); + errorToastIfFalsy(tournament, "Tournament can't be backfilled"); + errorToastIfFalsy( + award.userIds.every((userId) => + tournament.winners.some((winner) => winner.id === userId), + ), + "Only the winners of a tournament can receive its trophy", + ); + + return { + tournamentId: award.tournamentId, + tournamentTeamId: tournament.tournamentTeamId, + userIds: award.userIds, + }; + }); + + try { + await TrophyRepository.backfill({ trophyId: trophy.id, awards }); + } catch (error) { + if (error instanceof ConcurrentModificationError) { + errorToast("A tournament got a trophy in the meantime, try again"); + } + throw error; + } + + logger.info( + `Trophy ${trophy.id} backfilled by user ${user.id}: ${JSON.stringify(awards)}`, + ); + + clearTrophiesCache(); + ShowcaseTournaments.clearCachedTournaments(); + + return successToast( + `${trophy.name} awarded for ${awards.length} tournament(s)`, + ); + } default: { assertUnreachable(data); } diff --git a/app/features/trophies/components/TrophiesSelector.tsx b/app/features/trophies/components/TrophiesSelector.tsx index 20de89ade..963f686f5 100644 --- a/app/features/trophies/components/TrophiesSelector.tsx +++ b/app/features/trophies/components/TrophiesSelector.tsx @@ -162,7 +162,7 @@ function SortableTrophyItem({ ☰
- +
{trophy.name} (false); const [drawn, setDrawn] = useState(false); const [everDrawn, setEverDrawn] = useState(false); - const [activeModel, setActiveModel] = useState(model); + const [active, setActive] = useState({ model, code }); + const [hasAnimation, setHasAnimation] = useState(false); + const animationProgressRef = useRef(null); const reducedMotion = usePrefersReducedMotion(); const onRenderStatsRef = useRef(onRenderStats); onRenderStatsRef.current = onRenderStats; - const prevModelRef = useRef(model); - if (prevModelRef.current !== model) { - prevModelRef.current = model; + const prevSourceRef = useRef({ model, code }); + if ( + prevSourceRef.current.model !== model || + prevSourceRef.current.code !== code + ) { + prevSourceRef.current = { model, code }; setError(false); - if (!drawn || reducedMotion) setActiveModel(model); + if (!drawn || reducedMotion) setActive({ model, code }); setDrawn(false); } - const swapping = activeModel !== model; - const modelState = decompressTrophyModel(activeModel); + const swapping = active.model !== model || active.code !== code; + const xpVariant = XpTrophy.parseCode(active.code); + const xpState = useXpTrophyState(xpVariant); + const isLoadingXpState = xpVariant !== null && xpState === null; + const modelState = xpVariant ? xpState : decompressTrophyModel(active.model); const siteColorScheme = useTrophyColorScheme(); const colorScheme = forcedColorScheme ?? siteColorScheme; @@ -199,15 +212,25 @@ export function Trophy({ return; } - if (context && onRenderStats) { + const animationDuration = viewer.modelInfo?.animationDuration ?? 0; + const tracksAnimationProgress = Boolean( + showAnimationProgress && animationDuration > 0, + ); + setHasAnimation(tracksAnimationProgress); + + if ((context && onRenderStats) || tracksAnimationProgress) { viewer.onFrame = () => { - onRenderStatsRef.current?.({ ...context.stats }); + if (context) onRenderStatsRef.current?.({ ...context.stats }); + animationProgressRef.current?.style.setProperty( + "--animation-progress", + String(viewer.animation.time / animationDuration), + ); }; } - viewer.startRenderLoop(false); viewer.whenReady().then(() => { if (viewerRef.current !== viewer) return; + viewer.startRenderLoop(false); setDrawn(true); setEverDrawn(true); }); @@ -234,6 +257,7 @@ export function Trophy({ disableCameraControls, colorScheme, fps, + showAnimationProgress, ], ); @@ -261,7 +285,7 @@ export function Trophy({
) : null; - if (error || modelState === null) { + if (error || (modelState === null && !isLoadingXpState)) { return (
@@ -275,7 +299,10 @@ export function Trophy({ return (
- {deferred || isLoadingSharedContext || !RENDERS_MODELS ? ( + {deferred || + isLoadingSharedContext || + isLoadingXpState || + !RENDERS_MODELS ? (
) : ( { - if (swapping) setActiveModel(model); + if (swapping) setActive({ model, code }); }} /> )} + {hasAnimation ? ( +
+ ) : null} {everDrawn || swapping ? null : (
diff --git a/app/features/trophies/components/TrophyBackfill.module.css b/app/features/trophies/components/TrophyBackfill.module.css new file mode 100644 index 000000000..313960125 --- /dev/null +++ b/app/features/trophies/components/TrophyBackfill.module.css @@ -0,0 +1,63 @@ +.tournamentList { + display: flex; + flex-direction: column; + gap: var(--s-2); + padding: 0; + list-style: none; +} + +.tournament { + display: flex; + flex-direction: column; + gap: var(--s-2); + padding: var(--s-2-5); + border: var(--border-style); + border-radius: var(--radius-box); + background-color: var(--color-bg-high); +} + +.tournamentHeader { + display: flex; + align-items: center; + gap: var(--s-2); +} + +.logo { + border-radius: var(--radius-full); +} + +.tournamentName { + font-size: var(--font-sm); + font-weight: var(--weight-semi); +} + +.winners { + display: flex; + flex-direction: column; + gap: var(--s-1-5); + padding: 0 0 0 var(--s-4); + list-style: none; +} + +.winner { + display: grid; + grid-template-columns: max-content max-content 1fr max-content; + align-items: center; + gap: var(--s-2); + font-size: var(--font-xs); +} + +.winnerName { + min-width: 0; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.footer { + display: flex; + flex-wrap: wrap; + align-items: center; + justify-content: space-between; + gap: var(--s-2); +} diff --git a/app/features/trophies/components/TrophyBackfill.tsx b/app/features/trophies/components/TrophyBackfill.tsx new file mode 100644 index 000000000..6c18ba252 --- /dev/null +++ b/app/features/trophies/components/TrophyBackfill.tsx @@ -0,0 +1,311 @@ +import * as React from "react"; +import { useTranslation } from "react-i18next"; +import { useFetcher } from "react-router"; +import { ActionButton } from "~/components/ActionButton"; +import { Alert } from "~/components/Alert"; +import { Avatar } from "~/components/Avatar"; +import { SendouButton } from "~/components/elements/Button"; +import { SendouSelect, SendouSelectItem } from "~/components/elements/Select"; +import { SendouSwitch } from "~/components/elements/Switch"; +import { FormMessage } from "~/components/FormMessage"; +import { LocaleTime } from "~/components/LocaleTime"; +import { ParticipationPill } from "~/features/user-page/components/ParticipationPill"; +import { trophyBackfillPage } from "~/utils/urls"; +import type { NewTrophyLoaderData } from "../loaders/trophies.new.server"; +import type { TrophyBackfillLoaderData } from "../routes/trophies.$id.backfill.$seriesId"; +import { trophyActionSchema } from "../trophies-schemas"; +import styles from "./TrophyBackfill.module.css"; + +type BackfillTrophy = NewTrophyLoaderData["backfillTrophies"][number]; +type BackfillTournament = TrophyBackfillLoaderData["tournaments"][number]; + +type Awards = Record; + +export function TrophyBackfill({ + trophies, + series, +}: { + trophies: NewTrophyLoaderData["backfillTrophies"]; + series: NewTrophyLoaderData["backfillSeries"]; +}) { + const { t } = useTranslation(["trophies", "common"]); + const fetcher = useFetcher(); + const [trophyId, setTrophyId] = React.useState(null); + const [seriesId, setSeriesId] = React.useState(null); + + const backfillableTrophies = trophies.filter((trophy) => + series.some( + (oneSeries) => oneSeries.organizationId === trophy.organizationId, + ), + ); + const selectedTrophy = backfillableTrophies.find( + (trophy) => trophy.id === trophyId, + ); + const trophySeries = selectedTrophy + ? series.filter( + (oneSeries) => + oneSeries.organizationId === selectedTrophy.organizationId, + ) + : []; + + const tournaments = + fetcher.data?.trophyId === trophyId && fetcher.data?.seriesId === seriesId + ? fetcher.data.tournaments + : null; + + if (backfillableTrophies.length === 0) { + return {t("trophies:new.backfill.noTrophies")}; + } + + const handleTrophyChange = (newTrophyId: number) => { + setTrophyId(newTrophyId); + setSeriesId(null); + }; + + const handleSeriesChange = (newSeriesId: number) => { + setSeriesId(newSeriesId); + if (trophyId) { + fetcher.load(trophyBackfillPage({ trophyId, seriesId: newSeriesId })); + } + }; + + return ( +
+

{t("trophies:new.backfill.explanation")}

+ {t("trophies:new.backfill.warning")} + handleTrophyChange(key as number)} + data-testid="backfill-trophy-select" + > + {(trophy) => ( + + {trophy.name} + + )} + + {selectedTrophy ? ( + handleSeriesChange(key as number)} + data-testid="backfill-series-select" + > + {(oneSeries) => ( + + {oneSeries.name} + + )} + + ) : null} + {selectedTrophy && seriesId ? ( + tournaments ? ( + tournaments.length > 0 ? ( + tournament.tournamentId) + .join()} + trophy={selectedTrophy} + seriesId={seriesId} + tournaments={tournaments} + /> + ) : ( + {t("trophies:new.backfill.noTournaments")} + ) + ) : ( +
+ {t("common:actions.loading")} +
+ ) + ) : null} +
+ ); +} + +function BackfillTournamentList({ + trophy, + seriesId, + tournaments, +}: { + trophy: BackfillTrophy; + seriesId: number; + tournaments: BackfillTournament[]; +}) { + const { t } = useTranslation(["trophies", "common"]); + const [awards, setAwards] = React.useState({}); + + const selectedAwards = Object.entries(awards).map( + ([tournamentId, userIds]) => ({ + tournamentId: Number(tournamentId), + userIds, + }), + ); + const playerCount = selectedAwards.reduce( + (sum, award) => sum + award.userIds.length, + 0, + ); + const hasTournamentWithoutPlayers = selectedAwards.some( + (award) => award.userIds.length === 0, + ); + + const allWinners = (tournament: BackfillTournament) => + tournament.winners.map((winner) => winner.id); + + const toggleTournament = (tournament: BackfillTournament) => { + const { [tournament.tournamentId]: existing, ...rest } = awards; + setAwards( + existing + ? rest + : { ...awards, [tournament.tournamentId]: allWinners(tournament) }, + ); + }; + + const toggleWinner = (tournamentId: number, userId: number) => { + const userIds = awards[tournamentId] ?? []; + setAwards({ + ...awards, + [tournamentId]: userIds.includes(userId) + ? userIds.filter((id) => id !== userId) + : [...userIds, userId], + }); + }; + + const selectAll = () => { + setAwards( + Object.fromEntries( + tournaments.map((tournament) => [ + tournament.tournamentId, + allWinners(tournament), + ]), + ), + ); + }; + + return ( +
+ + {t("common:actions.selectAll")} + +
    + {tournaments.map((tournament) => { + const receiverIds = awards[tournament.tournamentId]; + + return ( +
  • +
    + toggleTournament(tournament)} + aria-label={tournament.name} + /> + +
    + + {tournament.name} + + + {tournament.startTime ? ( + <> + + {" • "} + + ) : null} + {tournament.teamName} + +
    +
    +
      + {tournament.winners.map((winner) => ( +
    • + + toggleWinner(tournament.tournamentId, winner.id) + } + aria-label={winner.username} + /> + + {winner.username} + +
    • + ))} +
    +
  • + ); + })} +
+
+ + {t("trophies:new.backfill.selected", { + count: selectedAwards.length, + playerCount, + })} + + + {t("trophies:new.backfill.submit")} + +
+ {hasTournamentWithoutPlayers ? ( + + {t("trophies:new.backfill.noPlayersSelected")} + + ) : null} +
+ ); +} diff --git a/app/features/trophies/components/TrophyDisplay.module.css b/app/features/trophies/components/TrophyDisplay.module.css index d6b0ba487..0c454361e 100644 --- a/app/features/trophies/components/TrophyDisplay.module.css +++ b/app/features/trophies/components/TrophyDisplay.module.css @@ -31,6 +31,8 @@ .winMembers { display: flex; flex-direction: column; + padding-left: var(--s-2); + border-left: var(--border-style); } .winMember { @@ -46,10 +48,6 @@ min-width: 0; max-width: 100%; } - - &:nth-child(odd) { - background-color: var(--color-bg-high); - } } @container (width >= 560px) and (width <= 750px) { @@ -91,3 +89,8 @@ color: var(--color-text-high); padding-top: var(--s-2); } + +.placements { + display: flex; + flex-direction: column; +} diff --git a/app/features/trophies/components/TrophyDisplay.tsx b/app/features/trophies/components/TrophyDisplay.tsx index e837cba49..f665095f6 100644 --- a/app/features/trophies/components/TrophyDisplay.tsx +++ b/app/features/trophies/components/TrophyDisplay.tsx @@ -6,20 +6,22 @@ import { Avatar } from "~/components/Avatar"; import { Divider } from "~/components/Divider"; import { DotPagination } from "~/components/DotPagination"; import { WeaponImage } from "~/components/Image"; +import { DivisionImage } from "~/features/top-search/components/DivisionImage"; +import type { XRankPlacementRegion } from "~/features/top-search/top-search-types"; import { UserCard } from "~/features/user-card/components/UserCard"; import { ParticipationPill } from "~/features/user-page/components/ParticipationPill"; import { usePagination } from "~/hooks/usePagination"; -import { trophyWinsPage } from "~/utils/urls"; +import { trophyPlacementsPage, trophyWinsPage } from "~/utils/urls"; +import * as XpTrophy from "../core/XpTrophy"; +import type { TrophyPlacementsLoaderData } from "../routes/trophies.$id.placements.$userId"; import type { TrophyWinsLoaderData } from "../routes/trophies.$id.wins.$userId"; import { SMALL_TROPHIES_PER_DISPLAY_PAGE } from "../trophies-constants"; -import { - parseSpecialTrophyCode, - useProgressiveRender, -} from "../trophies-utils"; +import { useProgressiveRender } from "../trophies-utils"; import { TournamentSummaryRow } from "./TournamentSummaryRow"; import { Trophy, TrophyContextProvider, TrophyGrid } from "./Trophy"; import styles from "./TrophyDisplay.module.css"; import { TrophyShowcaseModal } from "./TrophyShowcase"; +import { XPlacementSummaryRow } from "./XPlacementSummaryRow"; type TrophyItem = { id: number; @@ -28,6 +30,8 @@ type TrophyItem = { tier?: number | null; code?: string | null; count?: number | null; + /** Division an X Power trophy was won in. */ + division?: XRankPlacementRegion | null; }; export interface TrophyDisplayProps { @@ -41,6 +45,7 @@ export function TrophyDisplay({ userId, className, }: TrophyDisplayProps) { + const { t } = useTranslation(["common"]); const [openTrophy, setOpenTrophy] = React.useState(null); const { @@ -78,6 +83,7 @@ export function TrophyDisplay({ > = visibleCount} pill={ - trophy.count && trophy.count > 1 - ? `×${trophy.count}` - : undefined + trophy.division ? ( + + ) : trophy.count && trophy.count > 1 ? ( + `×${trophy.count}` + ) : undefined } /> @@ -123,33 +135,53 @@ function TrophyModal({ userId: number; onClose: () => void; }) { - const { t } = useTranslation(["trophies"]); + const { t } = useTranslation(["trophies", "common"]); const fetcher = useFetcher(); + const placementsFetcher = useFetcher(); const data = fetcher.data; + const placements = placementsFetcher.data?.placements; - const special = parseSpecialTrophyCode(trophy.code); + const xpVariant = XpTrophy.parseCode(trophy.code); const loadedRef = React.useRef(false); React.useEffect(() => { - if (parseSpecialTrophyCode(trophy.code) || loadedRef.current) return; + if (loadedRef.current) return; loadedRef.current = true; - fetcher.load(trophyWinsPage({ trophyId: trophy.id, userId })); - }, [fetcher.load, trophy.id, trophy.code, userId]); + + if (XpTrophy.parseCode(trophy.code)) { + placementsFetcher.load( + trophyPlacementsPage({ trophyId: trophy.id, userId }), + ); + } else { + fetcher.load(trophyWinsPage({ trophyId: trophy.id, userId })); + } + }, [fetcher.load, placementsFetcher.load, trophy.id, trophy.code, userId]); return ( - {special ? ( + {xpVariant ? (

- {special.type === "supporter" - ? t("trophies:special.supporter.description") - : t("trophies:special.xp.description", { - value: special.value, - })} + {t("trophies:special.xp.categoryDescription", { + value: xpVariant.milestone, + category: t( + `common:weapon.category.${XpTrophy.categoryKey(xpVariant.category)}`, + ), + })}

) : null} + {placements && placements.length > 0 ? ( +
+ +
+ {placements.map((placement) => ( + + ))} +
+
+ ) : null} {data ? data.wins.map((win) => (
diff --git a/app/features/trophies/components/TrophyShowcase.tsx b/app/features/trophies/components/TrophyShowcase.tsx index 8674af517..75b31216b 100644 --- a/app/features/trophies/components/TrophyShowcase.tsx +++ b/app/features/trophies/components/TrophyShowcase.tsx @@ -9,11 +9,13 @@ import styles from "./TrophyShowcase.module.css"; export function TrophyShowcase({ model, + code, children, className, detailsClassName, }: { model: string; + code?: string | null; children: React.ReactNode; className?: string; detailsClassName?: string; @@ -21,7 +23,7 @@ export function TrophyShowcase({ return (
- +
{children}
@@ -35,7 +37,7 @@ export function TrophyShowcaseModal({ onClose, children, }: { - trophy: { id: number; name: string; model: string }; + trophy: { id: number; name: string; model: string; code?: string | null }; onClose: () => void; children?: React.ReactNode; }) { @@ -49,7 +51,7 @@ export function TrophyShowcaseModal({ isDismissable className={styles.modal} > - +

{trophy.name}

diff --git a/app/features/trophies/components/XPlacementSummaryRow.module.css b/app/features/trophies/components/XPlacementSummaryRow.module.css new file mode 100644 index 000000000..ae50a3f9c --- /dev/null +++ b/app/features/trophies/components/XPlacementSummaryRow.module.css @@ -0,0 +1,39 @@ +.row { + display: flex; + align-items: center; + gap: var(--s-2); + padding: var(--s-1-5); + border-radius: var(--radius-field); + + &:hover { + background-color: var(--color-bg-high); + } +} + +.power { + display: flex; + align-items: baseline; + gap: var(--s-1-5); + font-size: var(--font-sm); + font-weight: var(--weight-semi); +} + +.rank { + color: var(--color-text-high); + font-size: var(--font-2xs); +} + +.meta { + display: flex; + flex-wrap: wrap; + align-items: center; + gap: var(--s-1) var(--s-2); + color: var(--color-text-high); + font-size: var(--font-2xs); +} + +.metaItem { + display: flex; + align-items: center; + gap: var(--s-1); +} diff --git a/app/features/trophies/components/XPlacementSummaryRow.tsx b/app/features/trophies/components/XPlacementSummaryRow.tsx new file mode 100644 index 000000000..d66ccdbcb --- /dev/null +++ b/app/features/trophies/components/XPlacementSummaryRow.tsx @@ -0,0 +1,71 @@ +import { clsx } from "clsx"; +import { useTranslation } from "react-i18next"; +import { Link } from "react-router"; +import { ModeImage, WeaponImage } from "~/components/Image"; +import { DivisionImage } from "~/features/top-search/components/DivisionImage"; +import type { XRankPlacementRegion } from "~/features/top-search/top-search-types"; +import { topSearchPage } from "~/features/top-search/top-search-urls"; +import { monthYearToSpan } from "~/features/top-search/top-search-utils"; +import { useDateTimeFormat } from "~/hooks/intl/useDateTimeFormat"; +import type { MainWeaponId, ModeShort } from "~/modules/in-game-lists/types"; +import styles from "./XPlacementSummaryRow.module.css"; + +export function XPlacementSummaryRow({ + placement, + className, +}: { + placement: { + weaponSplId: MainWeaponId; + power: number; + rank: number; + region: XRankPlacementRegion; + mode: ModeShort; + month: number; + year: number; + }; + className?: string; +}) { + const { t } = useTranslation(["common"]); + const { formatter } = useDateTimeFormat({ month: "short", year: "numeric" }); + + const season = monthYearToSpan(placement); + const divisionName = t(`common:divisions.${placement.region}`); + + return ( + + +
+ + {placement.power.toFixed(1)} + #{placement.rank} + +
+ + + {divisionName} + + + + {formatter.formatRange( + new Date(season.from.year, season.from.month - 1), + new Date(season.to.year, season.to.month - 1), + )} + +
+
+ + ); +} diff --git a/app/features/trophies/core/TrophyBackfill.server.test.ts b/app/features/trophies/core/TrophyBackfill.server.test.ts new file mode 100644 index 000000000..122af8b1e --- /dev/null +++ b/app/features/trophies/core/TrophyBackfill.server.test.ts @@ -0,0 +1,251 @@ +import { sub } from "date-fns"; +import { beforeEach, describe, expect, test } from "vitest"; +import * as BadgeFactory from "~/db/seed/factories/BadgeFactory"; +import * as TournamentFactory from "~/db/seed/factories/TournamentFactory"; +import * as TournamentOrganizationFactory from "~/db/seed/factories/TournamentOrganizationFactory"; +import * as TrophyFactory from "~/db/seed/factories/TrophyFactory"; +import * as UserFactory from "~/db/seed/factories/UserFactory"; +import type * as Progression from "~/features/tournament-bracket/core/Progression"; +import * as TournamentOrganizationRepository from "~/features/tournament-organization/TournamentOrganizationRepository.server"; +import { dateToDatabaseTimestamp } from "~/utils/dates"; +import * as TrophyBackfill from "./TrophyBackfill.server"; + +const SINGLE_BRACKET: Progression.ParsedBracket[] = [ + { + name: "Main Bracket", + type: "single_elimination", + settings: {}, + requiresCheckIn: false, + }, +]; + +const TWO_STARTING_BRACKETS: Progression.ParsedBracket[] = [ + { + name: "Division 1", + type: "single_elimination", + settings: {}, + requiresCheckIn: false, + }, + { + name: "Division 2", + type: "single_elimination", + settings: {}, + requiresCheckIn: false, + }, +]; + +const AB_DIVISIONS_FINALS: Progression.ParsedBracket[] = [ + { + name: "Finals", + type: "round_robin", + settings: { hasAbDivisions: true }, + requiresCheckIn: false, + }, +]; + +const placer = ( + userId: number, + div: string | null, + setResults: Array<"W" | "L" | null> = ["W"], +) => ({ userId, div, setResults }); + +describe("TrophyBackfill.eligibleWinners", () => { + test.each([ + { + why: "every first placer without divisions", + bracketProgression: SINGLE_BRACKET, + firstPlacers: [placer(1, null), placer(2, null)], + expected: [1, 2], + }, + { + why: "the first starting bracket's division", + bracketProgression: TWO_STARTING_BRACKETS, + firstPlacers: [placer(1, "Division 1"), placer(2, "Division 2")], + expected: [1], + }, + { + why: "the A division of A/B division finals", + bracketProgression: AB_DIVISIONS_FINALS, + firstPlacers: [placer(1, "B"), placer(2, "A")], + expected: [2], + }, + { + why: "no one when the top division has no winners", + bracketProgression: TWO_STARTING_BRACKETS, + firstPlacers: [placer(1, "Division 2")], + expected: [], + }, + { + why: "no one who didn't play a single set", + bracketProgression: SINGLE_BRACKET, + firstPlacers: [ + placer(1, null, ["W", null]), + placer(2, null, [null, null]), + placer(3, null, []), + ], + expected: [1], + }, + ])("picks $why", ({ bracketProgression, firstPlacers, expected }) => { + expect( + TrophyBackfill.eligibleWinners({ firstPlacers, bracketProgression }).map( + (winner) => winner.userId, + ), + ).toEqual(expected); + }); +}); + +describe("TrophyBackfill.backfillableTournaments", () => { + const users = UserFactory.pool(); + const organizerId = () => users.id(1); + const winnerIds = () => users.ids(9).slice(1, 5); + const benchedWinnerId = () => users.id(6); + const loserRoster = () => users.ids(9).slice(6, 9); + + let organizationId: number; + let seriesId: number; + + beforeEach(async () => { + await users.create(9); + + const organization = await TournamentOrganizationFactory.create( + { ownerId: organizerId() }, + { + series: [ + { name: "Weekly Cup", description: null, showLeaderboard: false }, + ], + }, + ); + organizationId = organization.id; + + const [series] = + await TournamentOrganizationRepository.findAllSeriesByOrganizationIds([ + organizationId, + ]); + seriesId = series.id; + }); + + const createFinalized = ( + overrides: Partial[0]> = {}, + ) => + TournamentFactory.createPlayed( + { + authorId: organizerId(), + name: "Weekly Cup #1", + organizationId, + ...overrides, + }, + { + teamRosters: [ + [...winnerIds(), benchedWinnerId()], + [organizerId(), ...loserRoster()], + ], + playedOut: "all", + }, + ); + + const backfillable = () => + TrophyBackfill.backfillableTournaments({ organizationId, seriesId }); + + test("lists a finalized tournament of the series with its winners who played", async () => { + const tournament = await createFinalized(); + + const tournaments = await backfillable(); + + expect(tournaments).toHaveLength(1); + expect(tournaments?.[0]).toMatchObject({ + tournamentId: tournament.id, + name: "Weekly Cup #1", + tournamentTeamId: tournament.teams[0].id, + }); + expect(tournaments?.[0].winners.map((winner) => winner.id)).toEqual( + winnerIds(), + ); + }); + + test("lists a tournament whose winners already got a badge", async () => { + const badge = await BadgeFactory.create(); + await createFinalized({ badges: [badge.id] }); + + expect(await backfillable()).toHaveLength(1); + }); + + test("skips a tournament that already has a trophy", async () => { + const trophy = await TrophyFactory.create({ organizationId }); + await createFinalized({ trophyId: trophy.id }); + + expect(await backfillable()).toEqual([]); + }); + + test("skips a tournament outside of the series", async () => { + await createFinalized({ name: "Monthly Showdown" }); + + expect(await backfillable()).toEqual([]); + }); + + test("skips a tournament of another organization", async () => { + const otherOrganization = await TournamentOrganizationFactory.create({ + ownerId: organizerId(), + }); + await createFinalized({ organizationId: otherOrganization.id }); + + expect(await backfillable()).toEqual([]); + }); + + test("skips a test tournament", async () => { + await createFinalized({ isTest: true }); + + expect(await backfillable()).toEqual([]); + }); + + test("skips a tournament that is not finalized", async () => { + await TournamentFactory.createPlayed( + { authorId: organizerId(), name: "Weekly Cup #2", organizationId }, + { + teamRosters: [winnerIds(), [organizerId(), ...loserRoster()]], + }, + ); + + expect(await backfillable()).toEqual([]); + }); + + test("lists newest tournaments first", async () => { + const older = await createFinalized({ + name: "Weekly Cup #1", + startTimes: [daysAgoTimestamp(14)], + }); + const newer = await createFinalized({ + name: "Weekly Cup #2", + startTimes: [daysAgoTimestamp(7)], + }); + + expect( + (await backfillable())?.map((tournament) => tournament.tournamentId), + ).toEqual([newer.id, older.id]); + }); + + test("is null for a series of another organization", async () => { + const otherOrganization = await TournamentOrganizationFactory.create( + { ownerId: organizerId() }, + { + series: [ + { name: "Other Cup", description: null, showLeaderboard: false }, + ], + }, + ); + const [otherSeries] = + await TournamentOrganizationRepository.findAllSeriesByOrganizationIds([ + otherOrganization.id, + ]); + + expect( + await TrophyBackfill.backfillableTournaments({ + organizationId, + seriesId: otherSeries.id, + }), + ).toBe(null); + }); +}); + +function daysAgoTimestamp(days: number) { + return dateToDatabaseTimestamp(sub(new Date(), { days })); +} diff --git a/app/features/trophies/core/TrophyBackfill.server.ts b/app/features/trophies/core/TrophyBackfill.server.ts new file mode 100644 index 000000000..c95bbee1f --- /dev/null +++ b/app/features/trophies/core/TrophyBackfill.server.ts @@ -0,0 +1,76 @@ +import { getBracketProgressionLabel } from "~/features/tournament/tournament-utils"; +import * as Progression from "~/features/tournament-bracket/core/Progression"; +import * as TournamentOrganizationRepository from "~/features/tournament-organization/TournamentOrganizationRepository.server"; +import * as TrophyRepository from "../TrophyRepository.server"; + +export async function backfillableTournaments({ + organizationId, + seriesId, +}: { + organizationId: number; + seriesId: number; +}) { + const series = ( + await TournamentOrganizationRepository.findAllSeriesByOrganizationIds([ + organizationId, + ]) + ).find((candidate) => candidate.id === seriesId); + if (!series) return null; + + const tournaments = await TrophyRepository.findAllBackfillableTournaments({ + organizationId, + substringMatches: series.substringMatches, + }); + + return tournaments.flatMap(({ settings, firstPlacers, ...tournament }) => { + const winners = eligibleWinners({ + firstPlacers, + bracketProgression: settings.bracketProgression, + }); + if (winners.length === 0) return []; + + return [ + { + ...tournament, + tournamentTeamId: winners[0].tournamentTeamId, + teamName: winners[0].teamName, + winners: winners.map( + ({ + div: _div, + tournamentTeamId: _teamId, + teamName: _name, + ...winner + }) => winner, + ), + }, + ]; + }); +} + +export function eligibleWinners< + T extends { div: string | null; setResults: ReadonlyArray }, +>({ + firstPlacers, + bracketProgression, +}: { + firstPlacers: T[]; + bracketProgression: Progression.ParsedBracket[]; +}) { + const hasDivisions = firstPlacers.some((placer) => placer.div !== null); + const topDivision = hasDivisions + ? topDivisionLabel(bracketProgression) + : null; + + return firstPlacers.filter( + (placer) => placer.div === topDivision && placer.setResults.some(Boolean), + ); +} + +function topDivisionLabel(bracketProgression: Progression.ParsedBracket[]) { + if (Progression.hasAbDivisionsFinals(bracketProgression)) return "A"; + + return getBracketProgressionLabel( + Progression.startingBrackets(bracketProgression)[0], + bracketProgression, + ); +} diff --git a/app/features/trophies/core/XpTrophy.test.ts b/app/features/trophies/core/XpTrophy.test.ts new file mode 100644 index 000000000..5685eea0e --- /dev/null +++ b/app/features/trophies/core/XpTrophy.test.ts @@ -0,0 +1,205 @@ +import { readFileSync } from "node:fs"; +import type { RawPicoCAD2File } from "picocad2-web"; +import { describe, expect, test } from "vitest"; +import { analyzeTrophyModel } from "./model-analysis"; +import * as XpTrophy from "./XpTrophy"; + +type VisibleNode = { + readonly name: string; + readonly visible: boolean; + readonly children: readonly VisibleNode[]; +}; + +const masterJson = readFileSync( + new URL("../data/xp-trophies-master.txt", import.meta.url), + "utf8", +); +const master: RawPicoCAD2File = JSON.parse(masterJson); + +describe("XpTrophy.VARIANTS", () => { + test("has one trophy per weapon category and milestone", () => { + const codes = XpTrophy.VARIANTS.map((variant) => variant.code); + + expect(codes).toHaveLength(11 * 4); + expect(new Set(codes).size).toBe(codes.length); + }); + + test("has a model for every weapon category", () => { + const modelled = new Set(master.graph.children.map((node) => node.name)); + const missing = XpTrophy.VARIANTS.filter( + (variant) => !modelled.has(variant.category), + ); + + expect(missing).toEqual([]); + }); +}); + +describe("XpTrophy.parseCode", () => { + test.each([ + { + why: "an X Power trophy", + code: "xp-shooters-3500", + expected: { category: "shooters", milestone: 3500 }, + }, + { why: "a tournament trophy", code: null, expected: null }, + { why: "an unknown milestone", code: "xp-shooters-3100", expected: null }, + { why: "an unknown category", code: "xp-bows-3000", expected: null }, + ])("parses $why", ({ code, expected }) => { + const parsed = XpTrophy.parseCode(code); + + expect( + parsed + ? { category: parsed.category, milestone: parsed.milestone } + : null, + ).toEqual(expected); + }); + + test("round trips every variant's code", () => { + for (const variant of XpTrophy.VARIANTS) { + expect(XpTrophy.parseCode(XpTrophy.code(variant))?.code).toBe( + variant.code, + ); + } + }); +}); + +describe("XpTrophy.milestoneFor", () => { + test.each([ + { power: 2999.9, expected: null }, + { power: 3000, expected: 3000 }, + { power: 3199.9, expected: 3000 }, + { power: 3200, expected: 3200 }, + { power: 3650.4, expected: 3500 }, + { power: 4100, expected: 4000 }, + ])("$power X Power reaches $expected", ({ power, expected }) => { + expect(XpTrophy.milestoneFor(power)).toBe(expected); + }); +}); + +describe("XpTrophy.awards", () => { + const SPLATTERSHOT = 40; + const SPLAT_ROLLER = 1010; + const SPLAT_CHARGER = 2010; + const E_LITER = 2030; + + test("awards the highest milestone reached with each category's weapons", () => { + expect( + XpTrophy.awards([ + { userId: 1, weaponSplId: SPLATTERSHOT, power: 3550 }, + { userId: 1, weaponSplId: SPLAT_CHARGER, power: 3050 }, + { userId: 1, weaponSplId: E_LITER, power: 3250 }, + { userId: 1, weaponSplId: SPLAT_ROLLER, power: 2900 }, + ]).toSorted((a, b) => a.code.localeCompare(b.code)), + ).toEqual([ + { userId: 1, code: "xp-chargers-3200" }, + { userId: 1, code: "xp-shooters-3500" }, + ]); + }); + + test("awards every user separately", () => { + expect( + XpTrophy.awards([ + { userId: 1, weaponSplId: SPLATTERSHOT, power: 3000 }, + { userId: 2, weaponSplId: SPLATTERSHOT, power: 4000 }, + ]), + ).toEqual([ + { userId: 1, code: "xp-shooters-3000" }, + { userId: 2, code: "xp-shooters-4000" }, + ]); + }); +}); + +describe("XpTrophy.division", () => { + const SPLATTERSHOT = 40; + const SPLAT_CHARGER = 2010; + const shooters3500 = { category: "shooters", milestone: 3500 } as const; + + test.each([ + { + why: "Tentatek when only reached there", + placements: [{ weaponSplId: SPLATTERSHOT, power: 3510, region: "WEST" }], + expected: "WEST", + }, + { + why: "Takoroka when only reached there", + placements: [{ weaponSplId: SPLATTERSHOT, power: 3510, region: "JPN" }], + expected: "JPN", + }, + { + why: "Takoroka when reached in both", + placements: [ + { weaponSplId: SPLATTERSHOT, power: 3700, region: "WEST" }, + { weaponSplId: SPLATTERSHOT, power: 3510, region: "JPN" }, + ], + expected: "JPN", + }, + { + why: "the division the milestone was reached in, not any it was played in", + placements: [ + { weaponSplId: SPLATTERSHOT, power: 3510, region: "WEST" }, + { weaponSplId: SPLATTERSHOT, power: 3400, region: "JPN" }, + ], + expected: "WEST", + }, + { + why: "none when only reached with another category", + placements: [{ weaponSplId: SPLAT_CHARGER, power: 3600, region: "JPN" }], + expected: null, + }, + ] as const)("is $why", ({ placements, expected }) => { + expect(XpTrophy.division(placements, shooters3500)).toBe(expected); + }); +}); + +describe("XpTrophy.variantState", () => { + const variant = { category: "chargers", milestone: 3500 } as const; + const state = XpTrophy.variantState(master, variant); + const children = state.source?.graph.children ?? []; + + test("keeps only the variant's category and the pedestal", () => { + expect(children.map((node) => node.name).toSorted()).toEqual([ + "chargers", + "pedestal", + ]); + }); + + test("keeps only the variant's milestone digits on the pedestal", () => { + const pedestal = children.find((node) => node.name === "pedestal"); + const digitFolders = pedestal?.children + .map((node) => node.name) + .filter((name) => /^\d+$/.test(name)); + + expect(digitFolders).toEqual(["35"]); + }); + + test("shows every part of the variant without forcing anything visible", () => { + const hidden = (node: VisibleNode): string[] => [ + ...(node.visible ? [] : [node.name]), + ...node.children.flatMap(hidden), + ]; + + expect(children.flatMap(hidden)).toEqual([]); + }); + + test("meets the requirements of an uploaded trophy", () => { + const analysis = analyzeTrophyModel(JSON.stringify(state)); + + expect(analysis?.cameraTargetCentered).toBe(true); + expect(analysis?.backgroundIsAlpha).toBe(true); + }); + + test.each([...new Set(XpTrophy.VARIANTS.map(({ category }) => category))])( + "spins %s around its center", + (category) => { + const [x, , z] = + XpTrophy.variantState(master, { category, milestone: 3000 }).model + ?.camera?.target ?? []; + + expect([x, z]).toEqual([0, 0]); + }, + ); + + test("leaves the master untouched", () => { + expect(master).toEqual(JSON.parse(masterJson)); + }); +}); diff --git a/app/features/trophies/core/XpTrophy.ts b/app/features/trophies/core/XpTrophy.ts new file mode 100644 index 000000000..a7c5c95d0 --- /dev/null +++ b/app/features/trophies/core/XpTrophy.ts @@ -0,0 +1,335 @@ +import type { + CameraSettings, + ExtrasOptions, + PicoCAD2ViewerState, + RawPicoCAD2File, +} from "picocad2-web"; +import type { XRankPlacementRegion } from "~/features/top-search/top-search-types"; +import type { MainWeaponId } from "~/modules/in-game-lists/types"; +import { weaponCategories } from "~/modules/in-game-lists/weapon-ids"; +import { toColor3 } from "./model-analysis"; + +const CODE_PREFIX = "xp-"; +const PEDESTAL_FOLDER = "pedestal"; + +const SHARED_EFFECTS: ExtrasOptions = { + specular: { + enabled: true, + environment: { + strength: 0.2, + skyColor: [1, 1, 1], + groundColor: [0, 0, 0], + horizon: 0.6, + fresnel: 0.73, + }, + style: "smooth", + nodes: ["pedestal", "rod.1", "rod.2", "rod.3", "rod.4"], + }, + gradientOutline: { + enabled: true, + colorFrom: [0.04, 0.04, 0.04], + gradient: 0, + mode: "dropShadow", + }, +}; + +const THREE_POINT_TWO_THOUSAND_EFFECTS: ExtrasOptions = { + meshDeform: { + enabled: true, + nodes: ["hundreds", "tens", "30", "32", "35", "40"], + cycle: { + enabled: true, + mode: "loop", + hold: 0, + }, + sweep: { + mode: "directional", + direction: [0, 0, 1], + softness: 0.2, + wave: 0.4, + }, + spherify: { + amount: 0.15, + }, + }, +}; + +const THREE_POINT_FIVE_THOUSAND_EFFECTS: ExtrasOptions = { + ...THREE_POINT_TWO_THOUSAND_EFFECTS, + triangleShatter: { + enabled: true, + cycle: { + enabled: true, + mode: "loop", + duration: 8, + hold: 1, + }, + sweep: { + mode: "directional", + softness: 0.2, + wave: 0.3, + }, + distance: 2.5, + spread: 0.75, + rotation: 0.5, + shrink: 1, + nodes: [ + "HEAVY", + "Charger.1", + "RollerModel", + "Shooter.1", + "DualiesUNO", + "DualiesDOS", + "sword", + "Bow", + "deflect the rain", + "EXPLOSION", + "BUCKET", + "ihatethisweapon", + ], + }, +}; + +const FOUR_THOUSAND_EFFECTS: ExtrasOptions = { + ...THREE_POINT_FIVE_THOUSAND_EFFECTS, + interior: { + enabled: true, + pattern: "constellations", + depth: 6, + scale: 0.9, + speed: 0.75, + backgroundColor: [ + 0.1411764705882353, 0.1411764705882353, 0.1411764705882353, + ], + style: "smooth", + maskedColors: [3, 1, 5], + nodes: [ + "basebot", + "chargers", + "rollers", + "shooters", + "dualies", + "splatlings", + "splatanas", + "stringers", + "brellas", + "blasters", + "sloshers", + "brushes", + ], + }, + bloom: { + enabled: true, + threshold: 0.65, + intensity: 1.71, + blur: 1.77, + maskedColors: [3, 5, 1], + }, +}; + +const TARGET_PER_CATEGORY = { + blasters: { distance: 16.1, position: [0, 2.1, 0] }, + brellas: { distance: 17.1, position: [0, 2.3, 0] }, + brushes: { distance: 19.1, position: [0, 3, 0] }, + chargers: { distance: 16.1, position: [0, 2.1, 0] }, + dualies: { distance: 16.1, position: [0, 2.1, 0] }, + rollers: { distance: 17.8, position: [0, 2.6, 0] }, + shooters: { distance: 16.1, position: [0, 2.1, 0] }, + sloshers: { distance: 16.1, position: [0, 2.1, 0] }, + splatanas: { distance: 18.1, position: [0, 2.5, 0] }, + splatlings: { distance: 16.1, position: [0, 2.1, 0] }, + stringers: { distance: 17.1, position: [0, 2.2, 0] }, +} satisfies Record< + Category, + { distance: number; position: CameraSettings["target"] } +>; + +const MILESTONES = [ + { value: 3000, folder: "30", effects: { ...SHARED_EFFECTS } }, + { + value: 3200, + folder: "32", + effects: { ...SHARED_EFFECTS, ...THREE_POINT_TWO_THOUSAND_EFFECTS }, + }, + { + value: 3500, + folder: "35", + effects: { ...SHARED_EFFECTS, ...THREE_POINT_FIVE_THOUSAND_EFFECTS }, + }, + { + value: 4000, + folder: "40", + effects: { ...SHARED_EFFECTS, ...FOUR_THOUSAND_EFFECTS }, + }, +] as const satisfies ReadonlyArray<{ + value: number; + folder: string; + effects: ExtrasOptions; +}>; + +const CAMERA: Pick = { + omega: 0.02, + theta: 0.03, +}; + +type Milestone = (typeof MILESTONES)[number]["value"]; +type Category = Lowercase<(typeof weaponCategories)[number]["name"]>; + +export interface Variant { + category: Category; + milestone: Milestone; +} + +// Every possible variant +export const VARIANTS: ReadonlyArray = + weaponCategories.flatMap(({ name }) => + MILESTONES.map(({ value }) => { + const variant = { category: toCategory(name), milestone: value }; + return { ...variant, code: code(variant), name: variantName(variant) }; + }), + ); + +export function code({ category, milestone }: Variant) { + return `${CODE_PREFIX}${category}-${milestone}`; +} + +// This is just for SQL "like" queries +export const CODE_LIKE_PATTERN = `${CODE_PREFIX}%`; + +export function parseCode(trophyCode: string | null | undefined) { + if (!trophyCode) return null; + + return VARIANTS.find((variant) => variant.code === trophyCode) ?? null; +} + +export function categoryKey(category: Category) { + return category.toUpperCase() as Uppercase; +} + +export function milestoneFor(power: number) { + return ( + MILESTONES.findLast((milestone) => power >= milestone.value)?.value ?? null + ); +} + +export function categoryWeaponIds(category: Category): readonly MainWeaponId[] { + return ( + weaponCategories.find(({ name }) => toCategory(name) === category) + ?.weaponIds ?? [] + ); +} + +export function awards( + placements: ReadonlyArray<{ + userId: number; + weaponSplId: MainWeaponId; + power: number; + }>, +) { + const peaks = new Map< + string, + { userId: number; category: Category; power: number } + >(); + + for (const { userId, weaponSplId, power } of placements) { + const category = weaponCategory(weaponSplId); + if (!category) continue; + + const key = `${userId}-${category}`; + const peak = peaks.get(key); + if (!peak || power > peak.power) { + peaks.set(key, { userId, category, power }); + } + } + + return [...peaks.values()].flatMap(({ userId, category, power }) => { + const milestone = milestoneFor(power); + return milestone ? [{ userId, code: code({ category, milestone }) }] : []; + }); +} + +export function division( + placements: ReadonlyArray<{ + weaponSplId: MainWeaponId; + power: number; + region: XRankPlacementRegion; + }>, + { category, milestone }: Variant, +): XRankPlacementRegion | null { + const weaponIds: readonly number[] = categoryWeaponIds(category); + const regions = new Set( + placements + .filter( + (placement) => + weaponIds.includes(placement.weaponSplId) && + placement.power >= milestone, + ) + .map((placement) => placement.region), + ); + + if (regions.has("JPN")) return "JPN"; + if (regions.has("WEST")) return "WEST"; + return null; +} + +export function variantState( + master: RawPicoCAD2File, + { category, milestone }: Variant, +): PicoCAD2ViewerState { + const milestoneFolder = MILESTONES.find( + (candidate) => candidate.value === milestone, + ); + const otherMilestoneFolders = new Set( + MILESTONES.filter((candidate) => candidate !== milestoneFolder).map( + (candidate) => candidate.folder, + ), + ); + + const children = master.graph.children.flatMap((node) => { + if (node.name === category) return [node]; + if (node.name !== PEDESTAL_FOLDER) return []; + + return [ + { + ...node, + children: node.children.filter( + (child) => !otherMilestoneFolders.has(child.name), + ), + }, + ]; + }); + + const { texture } = master; + + return { + source: { ...master, graph: { ...master.graph, children } }, + model: { + camera: { + ...CAMERA, + distanceToTarget: TARGET_PER_CATEGORY[category].distance, + target: TARGET_PER_CATEGORY[category].position, + }, + }, + viewer: { + backgroundColor: toColor3(texture.colors[texture.transparent_color]), + transparency: "smooth", + }, + extras: milestoneFolder?.effects ?? {}, + }; +} + +function weaponCategory(weaponSplId: MainWeaponId) { + const category = weaponCategories.find(({ weaponIds }) => + (weaponIds as readonly number[]).includes(weaponSplId), + ); + + return category ? toCategory(category.name) : null; +} + +function toCategory(name: (typeof weaponCategories)[number]["name"]) { + return name.toLowerCase() as Category; +} + +function variantName({ category, milestone }: Variant) { + return `${milestone} X Power ${category.charAt(0).toUpperCase()}${category.slice(1)}`; +} diff --git a/app/features/trophies/core/model-analysis.ts b/app/features/trophies/core/model-analysis.ts index e21ab2fa2..935a15e13 100644 --- a/app/features/trophies/core/model-analysis.ts +++ b/app/features/trophies/core/model-analysis.ts @@ -115,7 +115,7 @@ function isBackgroundAlpha(state: ModelState) { ); } -function toColor3(color: RawColor): Color3 { +export function toColor3(color: RawColor): Color3 { return Array.isArray(color) ? [color[0], color[1], color[2]] : [color.r, color.g, color.b]; diff --git a/app/features/trophies/data/xp-trophies-master.txt b/app/features/trophies/data/xp-trophies-master.txt new file mode 100644 index 000000000..fd66f4a51 --- /dev/null +++ b/app/features/trophies/data/xp-trophies-master.txt @@ -0,0 +1,10371 @@ +{ + "metadata":{ + "version":"2.0", + "shading_mode":1, + "face_mode":2, + "motion_duration":6.4, + "spritesheet_settings":{ + "cam_dist":40, + "cam_ortho":true, + "cam_theta":0.3, + "cam_target_y":0, + "num_frames":8, + "frame_width":48 + }, + "export_settings":{ + "watermark_color":15, + "dir":-1, + "watermark2_color":15, + "animate":"off", + "outline_color":0, + "anim":"spin", + "scanlines":false, + "watermark2":"", + "scale":3, + "fov_type":"perspective", + "scanline_color":0, + "speed":5, + "outline_size":0, + "size":128, + "watermark":"#picoCAD2" + }, + "camera":{ + "distance_to_target":14.140849729455, + "target":{ + "x":-0.34314750194545, + "y":1.0424570687741, + "z":-0.29154741152398 + }, + "theta":0.1957963267949, + "pos":{ + "x":13.523179462176, + "y":3.7935269726562, + "z":0.055183001091675 + }, + "_Ii0i01iOloOo11ll1Ii1loIii1100iOO35":{ + "distance_to_target":11.970653682206, + "target":{ + "x":-0.34314750194545, + "y":1.0424570687741, + "z":-0.29154741152398 + }, + "theta":1.1707963267949, + "pos":{ + "x":-0.013399520536092, + "y":12.068159248171, + "z":4.3583673510613 + }, + "omega":1.5 + }, + "omega":0.024999999999999 + } + }, + "texture":{ + "transparent_color":9, + "pixels":"11111111111111111111111111111111111111111111171111111111111111111171111111111111111111711111111111111111111111111111111111111111111111111111111111111111111111111111111111111711111111111111111111711111111111111111117111111111111111111111111111111111111111111111111111111111111111111111111111111111111117111111111111111111117111111111111111111171111111111111111111111111111111111111111111111111111111111111111111111111111111111111171111111111111111111171111111111111111111711111111111111111111111111111111111111111111111111111111111111111111111111111111111111711111111111111111111711111111111111111117111111111111111111111111111111111111111111111111111111111111111111111111111111111111117111111111111111111117111111111111111111171111111111111111111111111111111111111111111111111111111111111111111111111111111111111171111111111111111111171111111111111111111711111111111111111111111111111111111111111111111111111111111111111111111111111111111111711111111111111111111711111111111111111117111111111111111111111111111111111111111111111111111111111111111111111111111111111111117111111111111111111117111111111111111111171111111111111111111111111111111111111111111111111111111111111111111111111111111111111171111111111111111111171111111111111111111711111111111111111111111111111111111111111111111111111111111111111111111111111111111111711111111111111111111711111111111111111117111111111111111111111111111111111111111111111111111111111111111111111111111111111111117111111111111111111117111111111111111111171111111111111111111111111111111111111111111111111111111111111111111111111111111111111171111111111111111111171111111111111111111711111111111111111111111111111111111111111111111111111111111111111111111111111111111111711111111111111111111711111111111111111117111111111111111111111111111111111111111111111111111111111111111111111111111111111111117111111111111111111117111111111111111111171111111111111111111111111111111111111111111111111111111111111111111111111111111111111171111111111111111111171111111111111111111711111111111111111111111111111111111111111111111111111111111111111111111111111111111111711111111111111111111711111111111111111117111111111111111111111111111111111111111111111111111111111111111111111111111111111111117111111111111111111117111111111111111111171111111111111111111111111111111111111111111111111111111111111111111111111111111111111177777777777777777777771111111111111111111711111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111117111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111171111111111111111111111111111111111111111117777777777777777777777777777777777111111111111111111111111111111111111111111111111111711111111111111111111111111111111111111111171111111111111111111111111111111171111111111111111111111111111111111111111111111111117111111111111111111111111111111111111111111711111111111111111111111111111111711111111111111111111111111111111111111111111111111177777777777777777777777777777777777777777717111111111111111111111111111111117111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111171111111111111111111111111111111171111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111711111111111111111111111111111111711111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111117111111111111111111111111111111117111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111171111111111111111111111111111111171111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111711111113331111111111113331111111711111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111117111111133331111111111333311111117777777777777777777777777777777777777777777777777777777777777777777777777777777777777777711111171111111333331111111133333111111171111111111111111111111111111111111111111111111111177111111111111111111111111111111111117111111711111111333331111113333311111111711111111111111111111111111111111111111111111111111771111111111111111111111111111111eeee7111111711111111133333111133333111111111711111111111111111111111111111111111111111111111111771111111111111111111111111111eeeeeee7111111711111111113333311333331111111111711111111111111111111111111111111111111111111111111771111111111111111111111111eeeeeeeeee711111171111111111133333333331111111111171111111111111111111111111111111111111111111111111177111111111111111111111eeeeeeeeeeeeee711111171111111111113333333311111111111171111111111111111111111111111111111111111111111111177111111111111111111eeeeeeeeeeeeeeeee711111171111111111111333333111111111111171111111111fffffff11fffff111fffff111fffff1111111111771111111111111111eeeeeeeeeeeeeeeeeee711111171111111111111333333111111111111171111111111fffffff1fffffff1fffffff1fffffff111111111771111111111111111eeeeeeeeeeeeeeeeeee71111117111111111111333333331111111111117111111111111111ff1ff111ff1ff111ff1ff111ff11111111177111111111111111111eeeeeeeeeeeeeeeee71111117111111111113333333333111111111117111111111111fffff1ff1f1ff1ff1f1ff1ff1f1ff11111111177111111111111111111111eeeeeeeeeeeeee71111117111111111133333113333311111111117111111111111111ff1ff111ff1ff111ff1ff111ff111111111771111111111111111111111111eeeeeeeeee711111171111111113333311113333311111111171111111111fffffff1fffffff1fffffff1fffffff111111111771111111111111111111111111111eeeeeee711111171111111133333111111333331111111171111111111fffffff11fffff111fffff111fffff1111111111771111111111111111111111111111111eeee7111111711111113333311111111333331111111711111111111111111111111111111111111111111111111111771111111111111111111111111111111111171111117111111133331111111111333311111117111111111111111111111111111111111111111111111111117711111111111111111111111111111111111711111171111111333111111111111333111111171111111111111111111111111111111111111111111111111177777777777777777777777777777777777777111111711111111111111111111111111111111711111111111111111111111111111111111111111111111111711111111111111111111111111111111111111111117111111111111111111111111111111117111111111111111111111111111111111111111111111111117111111111111111111111111111111111111111111171111111111111111111111111111111171111111111111111111111111111111111111111111111111171111111111111111111111111111111111111111111711111111111111111111111111111111777777777777777777777777777777777777777777777777777711111111111111111111111111111111111111111117111111111111111111111111111111117117eeeeeeeeeeeeeeeeeeee711111111111111111111111111111111111111111111111111111111111111111111117111111111111111111111111111111117117eeeeeeeeeeeeeeeeeeee711111111111111111111111111111111111111111111111111111111111111111111117111111111111111111111111111111117117eeeeeeeeeeeeeeeeeeee711111111111111111111111111111111111111111111111111111111111111111111117111111111111111111111111111111117117eeeeeee111111eeeeeee711111111111111111111111111111111111111111111111111111111111111111111117111111111111111111111111111111117117eeeeee11111111eeeeee711111111111111111111111111111111111111111111111111111111111111111111117111111111111111111111111111111117117eeeee1111111111eeeee711111111111111111111111111111111111111111111111111111111111111111111117777777777777777777777777777777777777eeee111111111111eeee71111111111111111111113333333333333333333333333eeeeeeeeeeeeeeeeeeeeeee777777777777777777fffffffffffffffffff7eeee111111111111eeee71111111111111111111113333333333333333333333333eeeeeeeeeeeeeeeeeeeeeee333333333333333337fffffffffffffffffff7eeee111111111111eeee71111111111111111111113333333333333333333333333eeeeeeeeeeeeeeeeeeeeeee333333333333333337fffffffffffffffffff7eeee111111111111eeee71111111111111111111113333333333333333333333333eeeeeeeeeeeeeeeeeeeeeee333333333333333337fffffffffffffffffff7eeee111111111111eeee71111111111111111111113333333333333333333333333eeeeeeeeeeeeeeeeeeeeeee333333333333333337fffffffffffffffffff7eeee111111111111eeee71111111111111111111113333333333333333333333333eeeeeeeeeeeeeeeeeeeeeee333333333333333337fffffffffffffffffff7eeeee1111111111eeeee71111111111111111111113333333333333333333333333eeeeeeeeeeeeeeeeeeeeeee333333333333333337fffffffffffffffffff7eeeeee11111111eeeeee71111111111111111111113333333333333333333333333eeeeeeeeeeeeeeeeeeeeeee333333333333333337fffffffffffffffffff7eeeeeee111111eeeeeee71111111111111111111113333333333333333333333333eeeeeeeeeeeeeeeeeeeeeee333333333333333337fffffffffffffffffff7eeeeeeeeeeeeeeeeeeee71111111111111111111113333333333333333333333333eeeeeeeeeeeeeeeeeeeeeee333333333333333337fffffffffffffffffff7eeeeeeeeeeeeeeeeeeee71111111111111111111113333333333333333333333333eeeeeeeeeeeeeeeeeeeeeee333333333333333337fffffffffffffffffff7eeeeeeeeeeeeeeeeeeee71111111111111111111113333333333333333333333333eeeeeeeeeeeeeeeeeeeeeee333333333333333337fffffffffffffffffff7eeeeeeeeeeeeeeeeeeee71111111111111111111113333333333333333333333333eeeeeeeeeeeeeeeeeeeeeee333333333333333337fffffffffffffffffff77777777777777777777771111111111111111111113333333333333333333333333eeeeeeeeeeeeeeeeeeeeeee333333333333333337fffffffffffffffffff71111111111111111111111111111111111111111113333333333333333333333333eeeeeeeeeeeeeeeeeeeeeee333333333333333337fffffffffffffffffff71111111111111111111111111111111111111111113333333333333333333333333eeeeeeeeeeeeeeeeeeeeeee333333333333333337fffffffffffffffffff71111111111111111111111111111111111111111113333333333333333333333333eeeeeeeeeeeeeeeeeeeeeee333333333333333337fffffffffffffffffff71111111111111111111111111111111111111111113333333333333333333333333eeeeeeeeeeeeeeeeeeeeeee333333333333333337fffffffffffffffffff71111111111111111111111111111111111111111113333333333333333333333333eeeeeeeeeeeeeeeeeeeeeee333333333333333337fffffffffffffffffff71111111111111111111111111111111111111111113333333333333333333333333eeeeeeeeeeeeeeeeeeeeeee777777777777777777777777777777777777771111116666666666666666666666666666666666663333333333333333333333333eeeeeeeeeeeeeeeeeeeeeee111111111111111111111111111111711111111111116666666666666666666666666666666666663333333333333333333333333eeeeeeeeeeeeeeeeeeeeeee111111111111111111111111111111711111111111116666666666666666666666666666666666663333333333333333333333333eeeeeeeeeeeeeeeeeeeeeee111111111111111111111111111111711111111111116666666666666666666666666666666666663333333333333333333333333eeeeeeeeeeeeeeeeeeeeeee11111111111111111111111111111171111111111111666666666666666666666666666666666666fffffffffffffffffffffffffbbbbbbbbbbbbbbbbbbbbbbb11111111111111111111111111111171111111111111666666666666666666666666666666666666fffffffffffffffffffffffffbbbbbbbbbbbbbbbbbbbbbbb11111111111111111111111111111171111111111111666666666666666666666666666666666666fffffffffffffffffffffffffbbbbbbbbbbbbbbbbbbbbbbb11111111111111111111111111111171111111111111666666666666666666666666666666666666fffffffffffffffffffffffffbbbbbbbbbbbbbbbbbbbbbbb11111111111111111111111111111171111111111111666666666666666666666666666666666666fffffffffffffffffffffffffbbbbbbbbbbbbbbbbbbbbbbb11111111111111111111111111111171111111111111666666666666666666666666666666666666fffffffffffffffffffffffffbbbbbbbbbbbbbbbbbbbbbbb11111111111111111111111111111171111111111111666666666666666666666666666666666666fffffffffffffffffffffffffbbbbbbbbbbbbbbbbbbbbbbb11111111111111111111111111111171111111111111666666666666666666666666666666666666fffffffffffffffffffffffffbbbbbbbbbbbbbbbbbbbbbbb11111111111111111111111111111171111111111111666666666666666666666666666666666666fffffffffffffffffffffffffbbbbbbbbbbbbbbbbbbbbbbb11111111111111111111111111111171111111111111666666666666666666666666666666666666fffffffffffffffffffffffffbbbbbbbbbbbbbbbbbbbbbbb11111111111111111111111111111171111111111111666666666666666666666666666666666666fffffffffffffffffffffffffbbbbbbbbbbbbbbbbbbbbbbb11111111111111111111111111111171111111111111666666666666666666666666666666666666fffffffffffffffffffffffffbbbbbbbbbbbbbbbbbbbbbbb11111111111111111111111111111171111111111111666666666666666666666666666666666666fffffffffffffffffffffffffbbbbbbbbbbbbbbbbbbbbbbb11111111111111111111111111111171111111111111666666666666666666666666666666666666fffffffffffffffffffffffffbbbbbbbbbbbbbbbbbbbbbbb11111111111111111111111111111171111111111111666666666666666666666666666666666666fffffffffffffffffffffffffbbbbbbbbbbbbbbbbbbbbbbb11111111111111111111111111111171111111111111666666666666666666666666666666666666fffffffffffffffffffffffffbbbbbbbbbbbbbbbbbbbbbbb11111111111111111111111111111171111111111111666666666666666666666666666666666666fffffffffffffffffffffffffbbbbbbbbbbbbbbbbbbbbbbb11111111111111111111111111111171111111111111666666666666666666666666666666666666fffffffffffffffffffffffffbbbbbbbbbbbbbbbbbbbbbbb11111111111111111111111111111171111111111111666666666666666666666666666666666666fffffffffffffffffffffffffbbbbbbbbbbbbbbbbbbbbbbb11111111111111111111111111111171111111111111666666666666666666666666666666666666fffffffffffffffffffffffffbbbbbbbbbbbbbbbbbbbbbbb11111111111111111111111111111171111111111111666666666666666666666666666666666666fffffffffffffffffffffffffbbbbbbbbbbbbbbbbbbbbbbb11111111111111111111111111111171111111111111666666666666666666666666666666666666fffffffffffffffffffffffffbbbbbbbbbbbbbbbbbbbbbbb11111111111111111111111111111171111111111111666666666666666666666666666666666666fffffffffffffffffffffffff1111111111111111111111111111111111111111111111111111171111111111111666666666666666666666666666666666666fffffffffffffffffffffffff1111111111111111111111111111111111111111111111111111171111111111111666666666666666666666666666666666666fffffffffffffffffffffffff1111111111111111111111111111111111111111111111111111171111111111111666666666666666666666666666666666666fffffffffffffffffffffffff1111111111111111111111111111111111111111111111111111171111111111111666666666666666666666666666666666666fffffffffffffffffffffffff1111111111111111111111111111111111111111111111111111171111111111111666666666666666666666666666666666666fffffffffffffffffffffffff1111111111111111111111111111111111111111111111111111171111111111111666666666666666666666666666666666666fffffffffffffffffffffffff1111111111111111111111111111111111111111111111111111171111111111111666666666666666666666666666666666666fffffffffffffffffffffffff1111111111111111111111177777777777777777777777777777771111111111111111111111111111111111111111111111111fffffffffffffffffffffffff1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111fffffffffffffffffffffffff1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111fffffffffffffffffffffffff1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111fffffffffffffffffffffffff1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111", + "colors":[[0.14285714285714,0.14285714285714,0.14285714285714],[0.2,0.2,0.2],[0.75338345864662,0.77004048582996,0.78947368421053],[0.36862745098039,0.36862745098039,0.36862745098039],[0.67058823529412,0.32156862745098,0.21176470588235],[0.2078431372549,0.12941176470588,0.54117647058824],[0.66917293233083,0.70225563909774,0.67862513426423],[1,0,0.30196078431373],[0.49803921568627,0.26274509803922,0.98823529411765],[0.59607843137255,0.63137254901961,1],[0.64962406015038,0.41364950838635,0.03609022556391],[0.52156862745098,0.25490196078431,0.99607843137255],[0.92941176470588,0.96078431372549,0.69019607843137],[1,0.8,0.66666666666667],[0.89019607843137,0.73182503770739,0.20392156862745],[1,0.94509803921569,0.90980392156863]], + "background_color":13, + "shade_pal_1":[0,0,6,1,2,3,3,2,6,11,4,5,6,10,10,12], + "shade_pal_2":[0,0,3,0,1,1,1,1,3,5,2,1,3,4,4,6] + }, + "graph":{ + "ghost":false, + "open":false, + "children":[{ + "ghost":false, + "open":true, + "children":[{ + "ghost":false, + "open":false, + "children":[], + "visible":true, + "name":"x", + "motions":{ + "tracks":[[],[],[],[]] + }, + "mesh":{ + "vertices":[0.5,0.61731568167418,-0.5,2.25,0.61731568167418,-0.5,2.25,0.25,-0.5,0.5,0.25,-0.5,0.5,0.61731568167418,0.5,2.25,0.61731568167418,0.5,2.25,0.25,0.5,0.5,0.25,0.5,-0.5,0.61731568167418,0.5,-0.5,0.61731568167418,-0.5,-0.5,0.25,-0.5,-0.5,0.25,0.5,-0.5,0.61731568167418,-2.25,0.5,0.61731568167418,-2.25,0.5,0.25,-2.25,-0.5,0.25,-2.25,-2.25,0.61731568167418,0.5,-2.25,0.61731568167418,-0.5,-2.25,0.25,-0.5,-2.25,0.25,0.5,-0.5,0.25,2.25,0.5,0.25,2.25,0.5,0.61731568167418,2.25,-0.5,0.61731568167418,2.25], + "name":"XXXXXXXXXXXX", + "faces":[{ + "color":11, + "uvs":[0,0.46875,0.125,0.46875,0.125,0.59375,0,0.59375], + "vertex_ids":[1,2,3,4] + },{ + "color":11, + "uvs":[0,0.46875,0.125,0.46875,0.125,0.59375,0,0.59375], + "vertex_ids":[6,5,8,7] + },{ + "color":11, + "uvs":[0.125,0.46875,0.125,0.59375,0,0.59375,0,0.46875], + "vertex_ids":[5,6,2,1] + },{ + "color":11, + "uvs":[0,0.46875,0.125,0.46875,0.125,0.59375,0,0.59375], + "vertex_ids":[17,18,19,20] + },{ + "color":11, + "uvs":[0,0.46875,0.125,0.46875,0.125,0.59375,0,0.59375], + "vertex_ids":[2,6,7,3] + },{ + "color":11, + "uvs":[0.125,0.46875,0.125,0.59375,0,0.59375,0,0.46875], + "vertex_ids":[4,3,7,8] + },{ + "color":11, + "uvs":[0,0.46875,0.125,0.46875,0.125,0.59375,0,0.59375], + "vertex_ids":[9,5,1,10] + },{ + "color":11, + "uvs":[0,0.46875,0.125,0.46875,0.125,0.59375,0,0.59375], + "vertex_ids":[13,14,15,16] + },{ + "color":11, + "uvs":[0,0.46875,0.125,0.46875,0.125,0.59375,0,0.59375], + "vertex_ids":[11,4,8,12] + },{ + "color":11, + "uvs":[0,0.46875,0.125,0.46875,0.125,0.59375,0,0.59375], + "vertex_ids":[21,22,23,24] + },{ + "color":11, + "uvs":[0,0.46875,0.125,0.46875,0.125,0.59375,0,0.59375], + "vertex_ids":[13,10,1,14] + },{ + "color":11, + "uvs":[0,0.46875,0.125,0.46875,0.125,0.59375,0,0.59375], + "vertex_ids":[14,1,4,15] + },{ + "color":11, + "uvs":[0,0.46875,0.125,0.46875,0.125,0.59375,0,0.59375], + "vertex_ids":[15,4,11,16] + },{ + "color":11, + "uvs":[0,0.46875,0.125,0.46875,0.125,0.59375,0,0.59375], + "vertex_ids":[16,11,10,13] + },{ + "color":11, + "uvs":[0,0.46875,0.125,0.46875,0.125,0.59375,0,0.59375], + "vertex_ids":[17,9,10,18] + },{ + "color":11, + "uvs":[0,0.46875,0.125,0.46875,0.125,0.59375,0,0.59375], + "vertex_ids":[18,10,11,19] + },{ + "color":11, + "uvs":[0,0.46875,0.125,0.46875,0.125,0.59375,0,0.59375], + "vertex_ids":[19,11,12,20] + },{ + "color":11, + "uvs":[0,0.46875,0.125,0.46875,0.125,0.59375,0,0.59375], + "vertex_ids":[20,12,9,17] + },{ + "color":11, + "uvs":[0,0.46875,0.125,0.46875,0.125,0.59375,0,0.59375], + "vertex_ids":[21,12,8,22] + },{ + "color":11, + "uvs":[0,0.46875,0.125,0.46875,0.125,0.59375,0,0.59375], + "vertex_ids":[22,8,5,23] + },{ + "color":11, + "uvs":[0,0.46875,0.125,0.46875,0.125,0.59375,0,0.59375], + "vertex_ids":[23,5,9,24] + },{ + "color":11, + "uvs":[0,0.46875,0.125,0.46875,0.125,0.59375,0,0.59375], + "vertex_ids":[24,9,12,21] + }] + }, + "locked":true, + "transform":{ + "scale":{ + "x":1, + "y":1, + "z":1 + }, + "pos":{ + "x":0, + "y":1, + "z":0 + }, + "rot":{ + "x":-3.1415926535898, + "y":0.78539816339745, + "z":-3.1415926535898 + } + } + },{ + "ghost":false, + "open":false, + "children":[], + "visible":true, + "name":"basetop", + "motions":{ + "tracks":[[],[],[],[]] + }, + "mesh":{ + "vertices":[2.75,0.5,-1.25,1.25,0.5,-2.75,-1.25,0.5,-2.75,-2.75,0.5,-1.25,-2.75,0.5,1.25,-1.25,0.5,2.75,1.25,0.5,2.75,2.75,0.5,1.25,2.75,-1.5,-1.25,1.25,-1.5,-2.75,-1.25,-1.5,-2.75,-2.75,-1.5,-1.25,-2.75,-1.5,1.25,-1.25,-1.5,2.75,1.25,-1.5,2.75,2.75,-1.5,1.25], + "name":"basetop", + "faces":[{ + "color":10, + "uvs":[0.0625,0.84375,0,0.78125,0,0.6875,0.0625,0.625,0.15625,0.625,0.21875,0.6875,0.21875,0.78125,0.15625,0.84375], + "vertex_ids":[1,2,3,4,5,6,7,8] + },{ + "color":10, + "uvs":[0.78125,0.125,0.75,0.09375,0.75,0.03125,0.78125,0,0.84375,0,0.875,0.03125,0.875,0.09375,0.84375,0.125], + "vertex_ids":[16,15,14,13,12,11,10,9] + },{ + "color":10, + "uvs":[0.15625,0.65625,0.15625,0.78125,0.03125,0.78125,0.03125,0.65625], + "vertex_ids":[1,9,10,2] + },{ + "color":10, + "uvs":[0.15625,0.625,0.15625,0.75,0.03125,0.75,0.03125,0.625], + "vertex_ids":[2,10,11,3] + },{ + "color":10, + "uvs":[0.15625,0.625,0.15625,0.75,0.03125,0.75,0.03125,0.625], + "vertex_ids":[3,11,12,4] + },{ + "color":10, + "uvs":[0.1875,0.65625,0.1875,0.78125,0.0625,0.78125,0.0625,0.65625], + "vertex_ids":[4,12,13,5] + },{ + "color":10, + "uvs":[0.1875,0.6875,0.1875,0.8125,0.0625,0.8125,0.0625,0.6875], + "vertex_ids":[5,13,14,6] + },{ + "color":10, + "uvs":[0.15625,0.6875,0.15625,0.8125,0.03125,0.8125,0.03125,0.6875], + "vertex_ids":[6,14,15,7] + },{ + "color":10, + "uvs":[0.1875,0.625,0.1875,0.75,0.0625,0.75,0.0625,0.625], + "vertex_ids":[7,15,16,8] + },{ + "color":10, + "uvs":[0.15625,0.625,0.15625,0.75,0.03125,0.75,0.03125,0.625], + "vertex_ids":[8,16,9,1] + }] + }, + "locked":true, + "transform":{ + "scale":{ + "x":1, + "y":1, + "z":1 + }, + "pos":{ + "x":0, + "y":1, + "z":0 + }, + "rot":{ + "x":0, + "y":-0, + "z":0 + } + } + },{ + "ghost":false, + "open":false, + "children":[], + "visible":true, + "name":"basebot", + "motions":{ + "tracks":[[],[],[],[]] + }, + "mesh":{ + "vertices":[3,-0.5,-1.5,1.5,-0.5,-3,-1.5,-0.5,-3,-3,-0.5,-1.5,-3,-0.5,1.5,-1.5,-0.5,3,1.5,-0.5,3,3,-0.5,1.5,3,-1.75,-1.5,1.5,-1.75,-3,-1.5,-1.75,-3,-3,-1.75,-1.5,-3,-1.75,1.5,-1.5,-1.75,3,1.5,-1.75,3,3,-1.75,1.5], + "name":"basebot", + "faces":[{ + "color":10, + "uvs":[0.09375,0.78125,0.0625,0.75,0.0625,0.6875,0.09375,0.65625,0.15625,0.65625,0.1875,0.6875,0.1875,0.75,0.15625,0.78125], + "vertex_ids":[1,2,3,4,5,6,7,8] + },{ + "color":10, + "uvs":[0.09375,0.75,0.0625,0.71875,0.0625,0.65625,0.09375,0.625,0.15625,0.625,0.1875,0.65625,0.1875,0.71875,0.15625,0.75], + "vertex_ids":[16,15,14,13,12,11,10,9] + },{ + "color":10, + "uvs":[0.15625,0.625,0.15625,0.75,0.03125,0.75,0.03125,0.625], + "vertex_ids":[1,9,10,2] + },{ + "color":10, + "uvs":[0.15625,0.625,0.15625,0.75,0.03125,0.75,0.03125,0.625], + "vertex_ids":[2,10,11,3] + },{ + "color":10, + "uvs":[0.1875,0.625,0.1875,0.75,0.0625,0.75,0.0625,0.625], + "vertex_ids":[3,11,12,4] + },{ + "color":10, + "uvs":[0.15625,0.65625,0.15625,0.78125,0.03125,0.78125,0.03125,0.65625], + "vertex_ids":[4,12,13,5] + },{ + "color":10, + "uvs":[0.1875,0.625,0.1875,0.75,0.0625,0.75,0.0625,0.625], + "vertex_ids":[5,13,14,6] + },{ + "color":10, + "uvs":[0.15625,0.625,0.15625,0.75,0.03125,0.75,0.03125,0.625], + "vertex_ids":[6,14,15,7] + },{ + "color":10, + "uvs":[0.15625,0.65625,0.15625,0.78125,0.03125,0.78125,0.03125,0.65625], + "vertex_ids":[7,15,16,8] + },{ + "color":10, + "uvs":[0.1875,0.65625,0.1875,0.78125,0.0625,0.78125,0.0625,0.65625], + "vertex_ids":[8,16,9,1] + }] + }, + "locked":true, + "transform":{ + "scale":{ + "x":1, + "y":1, + "z":1 + }, + "pos":{ + "x":0, + "y":0, + "z":0 + }, + "rot":{ + "x":0, + "y":-0, + "z":0 + } + } + },{ + "ghost":false, + "open":true, + "children":[], + "visible":true, + "name":"hundreds", + "motions":{ + "tracks":[[],[],[],[]] + }, + "mesh":{ + "vertices":[0.13418622324524,0.1171875,-0.1171875,0.13418622324524,-0.1328125,-0.1171875,-0.36581377675476,-0.1328125,-0.1171875,-0.36581377675476,0.1171875,-0.1171875,0.13418622324524,0.1171875,0.1328125,0.13418622324524,-0.1328125,0.1328125,-0.36581377675476,-0.1328125,0.1328125,-0.36581377675476,0.1171875,0.1328125,0.13418622324524,-0.6328125,-0.6171875,0.13418622324524,-0.8828125,-0.6171875,-0.36581377675476,-0.8828125,-0.6171875,-0.36581377675476,-0.6328125,-0.6171875,0.13418622324524,-0.6328125,0.6328125,0.13418622324524,-0.8828125,0.6328125,-0.36581377675476,-0.8828125,0.6328125,-0.36581377675476,-0.6328125,0.6328125,0.13418622324524,-0.3828125,0.3828125,0.13418622324524,-0.3828125,-0.3671875,-0.36581377675476,-0.3828125,-0.3671875,-0.36581377675476,-0.3828125,0.3828125,-0.36581377675476,-0.3828125,0.8828125,-0.36581377675476,-0.6328125,0.8828125,0.13418622324524,-0.6328125,0.8828125,0.13418622324524,-0.3828125,0.8828125,0.13418622324524,-0.3828125,-0.8671875,0.13418622324524,-0.6328125,-0.8671875,-0.36581377675476,-0.6328125,-0.8671875,-0.36581377675476,-0.3828125,-0.8671875,0.13418622324524,0.3671875,0.8828125,0.13418622324524,0.3671875,0.3828125,-0.36581377675476,0.3671875,0.3828125,-0.36581377675476,0.3671875,0.8828125,-0.36581377675476,0.3671875,-0.8671875,-0.36581377675476,0.3671875,-0.3671875,0.13418622324524,0.3671875,-0.3671875,0.13418622324524,0.3671875,-0.8671875,0.13418622324524,0.6171875,0.8828125,0.13418622324524,0.6171875,0.6328125,-0.36581377675476,0.6171875,0.6328125,-0.36581377675476,0.6171875,0.8828125,-0.36581377675476,0.6171875,-0.8671875,-0.36581377675476,0.6171875,-0.6171875,0.13418622324524,0.6171875,-0.6171875,0.13418622324524,0.6171875,-0.8671875,-0.36581377675476,0.8671875,-0.6171875,-0.36581377675476,0.8671875,0.6328125,0.13418622324524,0.8671875,0.6328125,0.13418622324524,0.8671875,-0.6171875], + "name":"ZeroXX", + "faces":[{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[1,2,3,4] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[6,5,8,7] + },{ + "color":11, + "uvs":[0.28125,0.46875,0.28125,0.59375,0.15625,0.59375,0.15625,0.46875], + "vertex_ids":[5,6,2,1] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[5,1,4,8] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[2,6,7,3] + },{ + "color":11, + "uvs":[0.28125,0.46875,0.28125,0.59375,0.15625,0.59375,0.15625,0.46875], + "vertex_ids":[4,3,7,8] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[9,10,11,12] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[14,13,16,15] + },{ + "color":11, + "uvs":[0.28125,0.46875,0.28125,0.59375,0.15625,0.59375,0.15625,0.46875], + "vertex_ids":[13,14,10,9] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[17,18,19,20] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[10,14,15,11] + },{ + "color":11, + "uvs":[0.28125,0.46875,0.28125,0.59375,0.15625,0.59375,0.15625,0.46875], + "vertex_ids":[12,11,15,16] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[17,13,9,18] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[25,26,27,28] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[19,12,16,20] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[21,22,23,24] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[21,20,16,22] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[22,16,13,23] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[23,13,17,24] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[37,38,39,40] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[25,18,9,26] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[26,9,12,27] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[27,12,19,28] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[41,42,43,44] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[29,24,17,30] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[30,17,20,31] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[31,20,21,32] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[32,21,24,29] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[33,28,19,34] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[34,19,18,35] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[35,18,25,36] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[36,25,28,33] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[37,29,30,38] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[39,31,32,40] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[40,32,29,37] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[41,33,34,42] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[42,34,35,43] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[43,35,36,44] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[44,36,33,41] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[43,38,30,35] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[35,30,31,34] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[34,31,39,42] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[45,46,47,48] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[45,42,39,46] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[46,39,38,47] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[47,38,43,48] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[48,43,42,45] + }] + }, + "locked":true, + "transform":{ + "scale":{ + "x":0.5, + "y":0.5, + "z":0.5 + }, + "pos":{ + "x":2.75, + "y":0.5, + "z":0.53125 + }, + "rot":{ + "x":0, + "y":-0, + "z":0 + } + } + },{ + "ghost":false, + "open":false, + "children":[], + "visible":true, + "name":"tens", + "motions":{ + "tracks":[[],[],[],[]] + }, + "mesh":{ + "vertices":[0.088838515580164,0.1171875,-0.076090945928238,0.088838515580164,-0.1328125,-0.076090945928238,-0.41116148441984,-0.1328125,-0.076090945928238,-0.41116148441984,0.1171875,-0.076090945928238,0.088838515580164,0.1171875,0.17390905407176,0.088838515580164,-0.1328125,0.17390905407176,-0.41116148441984,-0.1328125,0.17390905407176,-0.41116148441984,0.1171875,0.17390905407176,0.088838515580164,-0.6328125,-0.57609094592824,0.088838515580164,-0.8828125,-0.57609094592824,-0.41116148441984,-0.8828125,-0.57609094592824,-0.41116148441984,-0.6328125,-0.57609094592824,0.088838515580164,-0.6328125,0.67390905407176,0.088838515580164,-0.8828125,0.67390905407176,-0.41116148441984,-0.8828125,0.67390905407176,-0.41116148441984,-0.6328125,0.67390905407176,0.088838515580164,-0.3828125,0.42390905407176,0.088838515580164,-0.3828125,-0.32609094592824,-0.41116148441984,-0.3828125,-0.32609094592824,-0.41116148441984,-0.3828125,0.42390905407176,-0.41116148441984,-0.3828125,0.92390905407176,-0.41116148441984,-0.6328125,0.92390905407176,0.088838515580164,-0.6328125,0.92390905407176,0.088838515580164,-0.3828125,0.92390905407176,0.088838515580164,-0.3828125,-0.82609094592824,0.088838515580164,-0.6328125,-0.82609094592824,-0.41116148441984,-0.6328125,-0.82609094592824,-0.41116148441984,-0.3828125,-0.82609094592824,0.088838515580164,0.3671875,0.92390905407176,0.088838515580164,0.3671875,0.42390905407176,-0.41116148441984,0.3671875,0.42390905407176,-0.41116148441984,0.3671875,0.92390905407176,-0.41116148441984,0.3671875,-0.82609094592824,-0.41116148441984,0.3671875,-0.32609094592824,0.088838515580164,0.3671875,-0.32609094592824,0.088838515580164,0.3671875,-0.82609094592824,0.088838515580164,0.6171875,0.92390905407176,0.088838515580164,0.6171875,0.67390905407176,-0.41116148441984,0.6171875,0.67390905407176,-0.41116148441984,0.6171875,0.92390905407176,-0.41116148441984,0.6171875,-0.82609094592824,-0.41116148441984,0.6171875,-0.57609094592824,0.088838515580164,0.6171875,-0.57609094592824,0.088838515580164,0.6171875,-0.82609094592824,-0.41116148441984,0.8671875,-0.57609094592824,-0.41116148441984,0.8671875,0.67390905407176,0.088838515580164,0.8671875,0.67390905407176,0.088838515580164,0.8671875,-0.57609094592824], + "name":"ZeroX", + "faces":[{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[1,2,3,4] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[6,5,8,7] + },{ + "color":11, + "uvs":[0.28125,0.46875,0.28125,0.59375,0.15625,0.59375,0.15625,0.46875], + "vertex_ids":[5,6,2,1] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[5,1,4,8] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[2,6,7,3] + },{ + "color":11, + "uvs":[0.28125,0.46875,0.28125,0.59375,0.15625,0.59375,0.15625,0.46875], + "vertex_ids":[4,3,7,8] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[9,10,11,12] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[14,13,16,15] + },{ + "color":11, + "uvs":[0.28125,0.46875,0.28125,0.59375,0.15625,0.59375,0.15625,0.46875], + "vertex_ids":[13,14,10,9] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[17,18,19,20] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[10,14,15,11] + },{ + "color":11, + "uvs":[0.28125,0.46875,0.28125,0.59375,0.15625,0.59375,0.15625,0.46875], + "vertex_ids":[12,11,15,16] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[17,13,9,18] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[25,26,27,28] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[19,12,16,20] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[21,22,23,24] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[21,20,16,22] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[22,16,13,23] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[23,13,17,24] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[37,38,39,40] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[25,18,9,26] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[26,9,12,27] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[27,12,19,28] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[41,42,43,44] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[29,24,17,30] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[30,17,20,31] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[31,20,21,32] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[32,21,24,29] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[33,28,19,34] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[34,19,18,35] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[35,18,25,36] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[36,25,28,33] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[37,29,30,38] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[39,31,32,40] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[40,32,29,37] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[41,33,34,42] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[42,34,35,43] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[43,35,36,44] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[44,36,33,41] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[43,38,30,35] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[35,30,31,34] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[34,31,39,42] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[45,46,47,48] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[45,42,39,46] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[46,39,38,47] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[47,38,43,48] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[48,43,42,45] + }] + }, + "locked":true, + "transform":{ + "scale":{ + "x":0.5, + "y":0.5, + "z":0.5 + }, + "pos":{ + "x":2.5, + "y":0.5, + "z":1.5 + }, + "rot":{ + "x":0, + "y":-0.78539816339745, + "z":0 + } + } + },{ + "ghost":false, + "open":false, + "children":[{ + "ghost":false, + "open":false, + "children":[], + "visible":true, + "name":"30.3", + "motions":{ + "tracks":[[],[],[],[]] + }, + "mesh":{ + "vertices":[0.084626143963453,0.8671875,-0.90407168245505,0.084626143963453,0.3671875,-0.90407168245505,-0.41537385603655,0.3671875,-0.90407168245505,-0.41537385603655,0.8671875,-0.90407168245505,0.084626143963453,0.8671875,0.34592831754495,0.084626143963453,0.3671875,0.34592831754495,-0.41537385603655,0.3671875,0.34592831754495,-0.41537385603655,0.8671875,0.34592831754495,0.084626143963453,0.3671875,0.84592831754495,0.084626143963453,0.8671875,0.84592831754495,-0.41537385603655,0.8671875,0.84592831754495,-0.41537385603655,0.3671875,0.84592831754495,-0.41537385603655,0.1171875,0.84592831754495,-0.41537385603655,0.1171875,0.34592831754495,0.084626143963453,0.1171875,0.34592831754495,0.084626143963453,0.1171875,0.84592831754495,-0.41537385603655,-0.1328125,0.84592831754495,-0.41537385603655,-0.1328125,0.34592831754495,0.084626143963453,-0.1328125,0.34592831754495,0.084626143963453,-0.1328125,0.84592831754495,-0.41537385603655,-0.3828125,0.84592831754495,-0.41537385603655,-0.3828125,0.34592831754495,0.084626143963453,-0.3828125,0.34592831754495,0.084626143963453,-0.3828125,0.84592831754495,-0.41537385603655,-0.8828125,0.84592831754495,-0.41537385603655,-0.8828125,0.34592831754495,0.084626143963453,-0.8828125,0.34592831754495,0.084626143963453,-0.8828125,0.84592831754495,-0.41537385603655,-0.8828125,-0.90407168245505,-0.41537385603655,-0.3828125,-0.90407168245505,0.084626143963453,-0.3828125,-0.90407168245505,0.084626143963453,-0.8828125,-0.90407168245505,-0.41537385603655,-0.1328125,-0.40407168245505,-0.41537385603655,0.1171875,-0.40407168245505,0.084626143963453,0.1171875,-0.40407168245505,0.084626143963453,-0.1328125,-0.40407168245505], + "name":"Three.2", + "faces":[{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[1,2,3,4] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[9,10,11,12] + },{ + "color":11, + "uvs":[0.28125,0.46875,0.28125,0.59375,0.15625,0.59375,0.15625,0.46875], + "vertex_ids":[5,6,2,1] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[5,1,4,8] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[2,6,7,3] + },{ + "color":11, + "uvs":[0.28125,0.46875,0.28125,0.59375,0.15625,0.59375,0.15625,0.46875], + "vertex_ids":[4,3,7,8] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[9,6,5,10] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[10,5,8,11] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[11,8,7,12] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[25,26,27,28] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[13,12,7,14] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[14,7,6,15] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[15,6,9,16] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[16,9,12,13] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[17,13,14,18] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[33,34,35,36] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[19,15,16,20] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[20,16,13,17] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[21,17,18,22] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[22,18,19,23] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[23,19,20,24] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[24,20,17,21] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[25,21,22,26] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[29,30,31,32] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[27,23,24,28] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[28,24,21,25] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[29,26,22,30] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[30,22,23,31] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[31,23,27,32] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[32,27,26,29] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[33,18,14,34] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[34,14,15,35] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[35,15,19,36] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[36,19,18,33] + }] + }, + "locked":true, + "transform":{ + "scale":{ + "x":0.5, + "y":0.5, + "z":0.5 + }, + "pos":{ + "x":2.5, + "y":0.5, + "z":-1.5 + }, + "rot":{ + "x":0, + "y":0.78539816339745, + "z":0 + } + } + },{ + "ghost":false, + "open":false, + "children":[], + "visible":true, + "name":"30.0", + "motions":{ + "tracks":[[],[],[],[]] + }, + "mesh":{ + "vertices":[0.13418622324524,0.1171875,-0.1171875,0.13418622324524,-0.1328125,-0.1171875,-0.36581377675476,-0.1328125,-0.1171875,-0.36581377675476,0.1171875,-0.1171875,0.13418622324524,0.1171875,0.1328125,0.13418622324524,-0.1328125,0.1328125,-0.36581377675476,-0.1328125,0.1328125,-0.36581377675476,0.1171875,0.1328125,0.13418622324524,-0.6328125,-0.6171875,0.13418622324524,-0.8828125,-0.6171875,-0.36581377675476,-0.8828125,-0.6171875,-0.36581377675476,-0.6328125,-0.6171875,0.13418622324524,-0.6328125,0.6328125,0.13418622324524,-0.8828125,0.6328125,-0.36581377675476,-0.8828125,0.6328125,-0.36581377675476,-0.6328125,0.6328125,0.13418622324524,-0.3828125,0.3828125,0.13418622324524,-0.3828125,-0.3671875,-0.36581377675476,-0.3828125,-0.3671875,-0.36581377675476,-0.3828125,0.3828125,-0.36581377675476,-0.3828125,0.8828125,-0.36581377675476,-0.6328125,0.8828125,0.13418622324524,-0.6328125,0.8828125,0.13418622324524,-0.3828125,0.8828125,0.13418622324524,-0.3828125,-0.8671875,0.13418622324524,-0.6328125,-0.8671875,-0.36581377675476,-0.6328125,-0.8671875,-0.36581377675476,-0.3828125,-0.8671875,0.13418622324524,0.3671875,0.8828125,0.13418622324524,0.3671875,0.3828125,-0.36581377675476,0.3671875,0.3828125,-0.36581377675476,0.3671875,0.8828125,-0.36581377675476,0.3671875,-0.8671875,-0.36581377675476,0.3671875,-0.3671875,0.13418622324524,0.3671875,-0.3671875,0.13418622324524,0.3671875,-0.8671875,0.13418622324524,0.6171875,0.8828125,0.13418622324524,0.6171875,0.6328125,-0.36581377675476,0.6171875,0.6328125,-0.36581377675476,0.6171875,0.8828125,-0.36581377675476,0.6171875,-0.8671875,-0.36581377675476,0.6171875,-0.6171875,0.13418622324524,0.6171875,-0.6171875,0.13418622324524,0.6171875,-0.8671875,-0.36581377675476,0.8671875,-0.6171875,-0.36581377675476,0.8671875,0.6328125,0.13418622324524,0.8671875,0.6328125,0.13418622324524,0.8671875,-0.6171875], + "name":"Zero.4", + "faces":[{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[1,2,3,4] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[6,5,8,7] + },{ + "color":11, + "uvs":[0.28125,0.46875,0.28125,0.59375,0.15625,0.59375,0.15625,0.46875], + "vertex_ids":[5,6,2,1] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[5,1,4,8] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[2,6,7,3] + },{ + "color":11, + "uvs":[0.28125,0.46875,0.28125,0.59375,0.15625,0.59375,0.15625,0.46875], + "vertex_ids":[4,3,7,8] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[9,10,11,12] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[14,13,16,15] + },{ + "color":11, + "uvs":[0.28125,0.46875,0.28125,0.59375,0.15625,0.59375,0.15625,0.46875], + "vertex_ids":[13,14,10,9] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[17,18,19,20] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[10,14,15,11] + },{ + "color":11, + "uvs":[0.28125,0.46875,0.28125,0.59375,0.15625,0.59375,0.15625,0.46875], + "vertex_ids":[12,11,15,16] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[17,13,9,18] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[25,26,27,28] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[19,12,16,20] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[21,22,23,24] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[21,20,16,22] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[22,16,13,23] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[23,13,17,24] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[37,38,39,40] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[25,18,9,26] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[26,9,12,27] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[27,12,19,28] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[41,42,43,44] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[29,24,17,30] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[30,17,20,31] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[31,20,21,32] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[32,21,24,29] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[33,28,19,34] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[34,19,18,35] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[35,18,25,36] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[36,25,28,33] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[37,29,30,38] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[39,31,32,40] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[40,32,29,37] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[41,33,34,42] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[42,34,35,43] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[43,35,36,44] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[44,36,33,41] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[43,38,30,35] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[35,30,31,34] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[34,31,39,42] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[45,46,47,48] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[45,42,39,46] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[46,39,38,47] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[47,38,43,48] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[48,43,42,45] + }] + }, + "locked":true, + "transform":{ + "scale":{ + "x":0.5, + "y":0.5, + "z":0.5 + }, + "pos":{ + "x":2.75, + "y":0.5, + "z":-0.5390625 + }, + "rot":{ + "x":0, + "y":-0, + "z":0 + } + } + }], + "visible":true, + "name":"30", + "motions":{ + "tracks":[[],[],[],[]] + }, + "folder":true, + "locked":true, + "transform":{ + "scale":{ + "x":1, + "y":1, + "z":1 + }, + "pos":{ + "x":0, + "y":0, + "z":0 + }, + "rot":{ + "x":0, + "y":-0, + "z":0 + } + } + },{ + "ghost":false, + "open":false, + "children":[{ + "ghost":false, + "open":false, + "children":[], + "visible":true, + "name":"32.3", + "motions":{ + "tracks":[[],[],[],[]] + }, + "mesh":{ + "vertices":[0.084626143963453,0.8671875,-0.90407168245505,0.084626143963453,0.3671875,-0.90407168245505,-0.41537385603655,0.3671875,-0.90407168245505,-0.41537385603655,0.8671875,-0.90407168245505,0.084626143963453,0.8671875,0.34592831754495,0.084626143963453,0.3671875,0.34592831754495,-0.41537385603655,0.3671875,0.34592831754495,-0.41537385603655,0.8671875,0.34592831754495,0.084626143963453,0.3671875,0.84592831754495,0.084626143963453,0.8671875,0.84592831754495,-0.41537385603655,0.8671875,0.84592831754495,-0.41537385603655,0.3671875,0.84592831754495,-0.41537385603655,0.1171875,0.84592831754495,-0.41537385603655,0.1171875,0.34592831754495,0.084626143963453,0.1171875,0.34592831754495,0.084626143963453,0.1171875,0.84592831754495,-0.41537385603655,-0.1328125,0.84592831754495,-0.41537385603655,-0.1328125,0.34592831754495,0.084626143963453,-0.1328125,0.34592831754495,0.084626143963453,-0.1328125,0.84592831754495,-0.41537385603655,-0.3828125,0.84592831754495,-0.41537385603655,-0.3828125,0.34592831754495,0.084626143963453,-0.3828125,0.34592831754495,0.084626143963453,-0.3828125,0.84592831754495,-0.41537385603655,-0.8828125,0.84592831754495,-0.41537385603655,-0.8828125,0.34592831754495,0.084626143963453,-0.8828125,0.34592831754495,0.084626143963453,-0.8828125,0.84592831754495,-0.41537385603655,-0.8828125,-0.90407168245505,-0.41537385603655,-0.3828125,-0.90407168245505,0.084626143963453,-0.3828125,-0.90407168245505,0.084626143963453,-0.8828125,-0.90407168245505,-0.41537385603655,-0.1328125,-0.40407168245505,-0.41537385603655,0.1171875,-0.40407168245505,0.084626143963453,0.1171875,-0.40407168245505,0.084626143963453,-0.1328125,-0.40407168245505], + "name":"Three.3", + "faces":[{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[1,2,3,4] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[9,10,11,12] + },{ + "color":11, + "uvs":[0.28125,0.46875,0.28125,0.59375,0.15625,0.59375,0.15625,0.46875], + "vertex_ids":[5,6,2,1] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[5,1,4,8] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[2,6,7,3] + },{ + "color":11, + "uvs":[0.28125,0.46875,0.28125,0.59375,0.15625,0.59375,0.15625,0.46875], + "vertex_ids":[4,3,7,8] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[9,6,5,10] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[10,5,8,11] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[11,8,7,12] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[25,26,27,28] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[13,12,7,14] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[14,7,6,15] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[15,6,9,16] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[16,9,12,13] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[17,13,14,18] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[33,34,35,36] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[19,15,16,20] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[20,16,13,17] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[21,17,18,22] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[22,18,19,23] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[23,19,20,24] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[24,20,17,21] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[25,21,22,26] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[29,30,31,32] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[27,23,24,28] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[28,24,21,25] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[29,26,22,30] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[30,22,23,31] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[31,23,27,32] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[32,27,26,29] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[33,18,14,34] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[34,14,15,35] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[35,15,19,36] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[36,19,18,33] + }] + }, + "locked":true, + "transform":{ + "scale":{ + "x":0.5, + "y":0.5, + "z":0.5 + }, + "pos":{ + "x":2.5, + "y":0.5, + "z":-1.5 + }, + "rot":{ + "x":0, + "y":0.78539816339745, + "z":0 + } + } + },{ + "ghost":false, + "open":false, + "children":[], + "visible":true, + "name":"32.2", + "motions":{ + "tracks":[[],[],[],[]] + }, + "mesh":{ + "vertices":[0.13573584518601,-0.609375,-0.15981140170704,0.13573584518601,-0.859375,-0.15981140170704,-0.36426415481399,-0.859375,-0.15981140170704,-0.36426415481399,-0.609375,-0.15981140170704,0.13573584518601,-0.609375,0.84018859829296,0.13573584518601,-0.859375,0.84018859829296,-0.36426415481399,-0.859375,0.84018859829296,-0.36426415481399,-0.609375,0.84018859829296,0.13573584518601,-0.109375,-0.65981140170704,0.13573584518601,-0.359375,-0.65981140170704,-0.36426415481399,-0.359375,-0.65981140170704,-0.36426415481399,-0.109375,-0.65981140170704,0.13573584518601,-0.109375,0.59018859829296,0.13573584518601,-0.359375,0.59018859829296,-0.36426415481399,-0.359375,0.59018859829296,-0.36426415481399,-0.109375,0.59018859829296,0.13573584518601,-0.609375,-0.90981140170704,-0.36426415481399,-0.609375,-0.90981140170704,-0.36426415481399,-0.359375,-0.90981140170704,0.13573584518601,-0.359375,-0.90981140170704,0.13573584518601,-0.359375,0.84018859829296,-0.36426415481399,-0.359375,0.84018859829296,0.13573584518601,-0.859375,-0.40981140170704,0.13573584518601,-1.109375,-0.40981140170704,-0.36426415481399,-1.109375,-0.40981140170704,-0.36426415481399,-0.859375,-0.40981140170704,0.13573584518601,-0.859375,0.59018859829296,0.13573584518601,-1.109375,0.59018859829296,-0.36426415481399,-1.109375,0.59018859829296,-0.36426415481399,-0.859375,0.59018859829296,0.13573584518601,-1.609375,0.090188598292963,0.13573584518601,-1.859375,0.090188598292963,-0.36426415481399,-1.859375,0.090188598292963,-0.36426415481399,-1.609375,0.090188598292963,0.13573584518601,-1.609375,0.84018859829296,0.13573584518601,-1.859375,0.84018859829296,-0.36426415481399,-1.859375,0.84018859829296,-0.36426415481399,-1.609375,0.84018859829296,0.13573584518601,-1.359375,-0.65981140170704,0.13573584518601,-1.859375,-0.65981140170704,-0.36426415481399,-1.859375,-0.65981140170704,-0.36426415481399,-1.359375,-0.65981140170704,0.13573584518601,-1.359375,-0.90981140170704,0.13573584518601,-1.859375,-0.90981140170704,-0.36426415481399,-1.859375,-0.90981140170704,-0.36426415481399,-1.359375,-0.90981140170704,-0.36426415481399,-1.109375,-0.65981140170704,-0.36426415481399,-1.359375,0.090188598292963,0.13573584518601,-1.359375,0.090188598292963,0.13573584518601,-1.109375,-0.65981140170704,-0.36426415481399,-1.109375,0.34018859829296,-0.36426415481399,-1.359375,0.34018859829296,0.13573584518601,-1.359375,0.34018859829296,0.13573584518601,-1.109375,0.34018859829296], + "name":"TWO", + "faces":[{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[1,2,3,4] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[6,5,8,7] + },{ + "color":11, + "uvs":[0.28125,0.46875,0.28125,0.59375,0.15625,0.59375,0.15625,0.46875], + "vertex_ids":[5,6,2,1] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[5,1,4,8] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[2,6,7,3] + },{ + "color":11, + "uvs":[0.28125,0.46875,0.28125,0.59375,0.15625,0.59375,0.15625,0.46875], + "vertex_ids":[4,3,7,8] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[9,10,11,12] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[14,13,16,15] + },{ + "color":11, + "uvs":[0.28125,0.46875,0.28125,0.59375,0.15625,0.59375,0.15625,0.46875], + "vertex_ids":[13,14,10,9] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[13,9,12,16] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[17,5,8,18] + },{ + "color":11, + "uvs":[0.28125,0.46875,0.28125,0.59375,0.15625,0.59375,0.15625,0.46875], + "vertex_ids":[12,11,15,16] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[17,10,14,5] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[21,21,22,22] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[8,15,11,18] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[18,19,20,17] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[18,18,11,19] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[19,11,10,20] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[20,10,17,17] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[17,17,18,18] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[21,5,14,21] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[21,14,15,22] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[22,15,8,22] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[22,8,5,21] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[23,24,25,26] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[28,27,30,29] + },{ + "color":11, + "uvs":[0.28125,0.46875,0.28125,0.59375,0.15625,0.59375,0.15625,0.46875], + "vertex_ids":[27,28,24,23] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[27,23,26,30] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[24,28,29,25] + },{ + "color":11, + "uvs":[0.28125,0.46875,0.28125,0.59375,0.15625,0.59375,0.15625,0.46875], + "vertex_ids":[26,25,29,30] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[43,44,45,46] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[36,35,38,37] + },{ + "color":11, + "uvs":[0.28125,0.46875,0.28125,0.59375,0.15625,0.59375,0.15625,0.46875], + "vertex_ids":[35,36,32,31] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[35,31,34,38] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[32,36,37,33] + },{ + "color":11, + "uvs":[0.28125,0.46875,0.28125,0.59375,0.15625,0.59375,0.15625,0.46875], + "vertex_ids":[34,33,37,38] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[39,31,32,40] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[40,32,33,41] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[41,33,34,42] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[51,52,53,54] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[43,39,40,44] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[44,40,41,45] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[45,41,42,46] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[46,42,39,43] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[47,42,34,48] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[48,34,31,49] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[49,31,39,50] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[50,39,42,47] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[51,47,48,52] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[52,48,49,53] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[53,49,50,54] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[54,50,47,51] + }] + }, + "locked":true, + "transform":{ + "scale":{ + "x":0.5, + "y":0.5, + "z":0.5 + }, + "pos":{ + "x":2.75, + "y":1, + "z":-0.5 + }, + "rot":{ + "x":0, + "y":-0, + "z":0 + } + } + }], + "visible":true, + "name":"32", + "motions":{ + "tracks":[[],[],[],[]] + }, + "folder":true, + "locked":true, + "transform":{ + "scale":{ + "x":1, + "y":1, + "z":1 + }, + "pos":{ + "x":0, + "y":0, + "z":0 + }, + "rot":{ + "x":0, + "y":-0, + "z":0 + } + } + },{ + "ghost":false, + "open":false, + "children":[{ + "ghost":false, + "open":false, + "children":[], + "visible":true, + "name":"35.3", + "motions":{ + "tracks":[[],[],[],[]] + }, + "mesh":{ + "vertices":[0.084626143963453,0.8671875,-0.90407168245505,0.084626143963453,0.3671875,-0.90407168245505,-0.41537385603655,0.3671875,-0.90407168245505,-0.41537385603655,0.8671875,-0.90407168245505,0.084626143963453,0.8671875,0.34592831754495,0.084626143963453,0.3671875,0.34592831754495,-0.41537385603655,0.3671875,0.34592831754495,-0.41537385603655,0.8671875,0.34592831754495,0.084626143963453,0.3671875,0.84592831754495,0.084626143963453,0.8671875,0.84592831754495,-0.41537385603655,0.8671875,0.84592831754495,-0.41537385603655,0.3671875,0.84592831754495,-0.41537385603655,0.1171875,0.84592831754495,-0.41537385603655,0.1171875,0.34592831754495,0.084626143963453,0.1171875,0.34592831754495,0.084626143963453,0.1171875,0.84592831754495,-0.41537385603655,-0.1328125,0.84592831754495,-0.41537385603655,-0.1328125,0.34592831754495,0.084626143963453,-0.1328125,0.34592831754495,0.084626143963453,-0.1328125,0.84592831754495,-0.41537385603655,-0.3828125,0.84592831754495,-0.41537385603655,-0.3828125,0.34592831754495,0.084626143963453,-0.3828125,0.34592831754495,0.084626143963453,-0.3828125,0.84592831754495,-0.41537385603655,-0.8828125,0.84592831754495,-0.41537385603655,-0.8828125,0.34592831754495,0.084626143963453,-0.8828125,0.34592831754495,0.084626143963453,-0.8828125,0.84592831754495,-0.41537385603655,-0.8828125,-0.90407168245505,-0.41537385603655,-0.3828125,-0.90407168245505,0.084626143963453,-0.3828125,-0.90407168245505,0.084626143963453,-0.8828125,-0.90407168245505,-0.41537385603655,-0.1328125,-0.40407168245505,-0.41537385603655,0.1171875,-0.40407168245505,0.084626143963453,0.1171875,-0.40407168245505,0.084626143963453,-0.1328125,-0.40407168245505], + "name":"Three.4", + "faces":[{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[1,2,3,4] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[9,10,11,12] + },{ + "color":11, + "uvs":[0.28125,0.46875,0.28125,0.59375,0.15625,0.59375,0.15625,0.46875], + "vertex_ids":[5,6,2,1] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[5,1,4,8] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[2,6,7,3] + },{ + "color":11, + "uvs":[0.28125,0.46875,0.28125,0.59375,0.15625,0.59375,0.15625,0.46875], + "vertex_ids":[4,3,7,8] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[9,6,5,10] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[10,5,8,11] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[11,8,7,12] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[25,26,27,28] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[13,12,7,14] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[14,7,6,15] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[15,6,9,16] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[16,9,12,13] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[17,13,14,18] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[33,34,35,36] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[19,15,16,20] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[20,16,13,17] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[21,17,18,22] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[22,18,19,23] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[23,19,20,24] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[24,20,17,21] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[25,21,22,26] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[29,30,31,32] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[27,23,24,28] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[28,24,21,25] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[29,26,22,30] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[30,22,23,31] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[31,23,27,32] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[32,27,26,29] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[33,18,14,34] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[34,14,15,35] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[35,15,19,36] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[36,19,18,33] + }] + }, + "locked":true, + "transform":{ + "scale":{ + "x":0.5, + "y":0.5, + "z":0.5 + }, + "pos":{ + "x":2.5, + "y":0.5, + "z":-1.5 + }, + "rot":{ + "x":0, + "y":0.78539816339745, + "z":0 + } + } + },{ + "ghost":false, + "open":false, + "children":[], + "visible":true, + "name":"35.5", + "motions":{ + "tracks":[[],[],[],[]] + }, + "mesh":{ + "vertices":[0.13533972145086,0.8671875,-0.43648911141966,0.13533972145086,0.3671875,-0.43648911141966,-0.36466027854914,0.3671875,-0.43648911141966,-0.36466027854914,0.8671875,-0.43648911141966,0.13533972145086,0.8671875,0.81351088858034,0.13533972145086,0.3671875,0.81351088858034,-0.36466027854914,0.3671875,0.81351088858034,-0.36466027854914,0.8671875,0.81351088858034,0.13533972145086,0.8671875,-0.93648911141966,0.13533972145086,0.3671875,-0.93648911141966,-0.36466027854914,0.3671875,-0.93648911141966,-0.36466027854914,0.8671875,-0.93648911141966,0.13533972145086,0.1171875,-0.93648911141966,0.13533972145086,0.1171875,-0.43648911141966,-0.36466027854914,0.1171875,-0.43648911141966,-0.36466027854914,0.1171875,-0.93648911141966,0.13533972145086,-0.1328125,-0.93648911141966,0.13533972145086,-0.1328125,-0.43648911141966,-0.36466027854914,-0.1328125,-0.43648911141966,-0.36466027854914,-0.1328125,-0.93648911141966,0.13533972145086,-0.1328125,0.063510888580344,0.13533972145086,0.1171875,0.063510888580344,-0.36466027854914,0.1171875,0.063510888580344,-0.36466027854914,-0.1328125,0.063510888580344,0.13533972145086,-0.1328125,0.81351088858034,0.13533972145086,0.1171875,0.81351088858034,-0.36466027854914,0.1171875,0.81351088858034,-0.36466027854914,-0.1328125,0.81351088858034,-0.36466027854914,-0.3828125,0.81351088858034,-0.36466027854914,-0.3828125,0.063510888580344,0.13533972145086,-0.3828125,0.063510888580344,0.13533972145086,-0.3828125,0.81351088858034,-0.36466027854914,-0.6328125,0.81351088858034,-0.36466027854914,-0.6328125,0.063510888580344,0.13533972145086,-0.6328125,0.063510888580344,0.13533972145086,-0.6328125,0.81351088858034,-0.36466027854914,-0.6328125,-0.93648911141966,-0.36466027854914,-0.3828125,-0.93648911141966,0.13533972145086,-0.3828125,-0.93648911141966,0.13533972145086,-0.6328125,-0.93648911141966,0.13533972145086,-0.8828125,-0.93648911141966,0.13533972145086,-0.8828125,0.063510888580344,-0.36466027854914,-0.8828125,0.063510888580344,-0.36466027854914,-0.8828125,-0.93648911141966,0.13533972145086,-0.8828125,0.56351088858034,0.13533972145086,-0.6328125,0.56351088858034,-0.36466027854914,-0.6328125,0.56351088858034,-0.36466027854914,-0.8828125,0.56351088858034], + "name":"FIVE.1", + "faces":[{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[9,10,11,12] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[6,5,8,7] + },{ + "color":11, + "uvs":[0.28125,0.46875,0.28125,0.59375,0.15625,0.59375,0.15625,0.46875], + "vertex_ids":[5,6,2,1] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[5,1,4,8] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[2,6,7,3] + },{ + "color":11, + "uvs":[0.28125,0.46875,0.28125,0.59375,0.15625,0.59375,0.15625,0.46875], + "vertex_ids":[4,3,7,8] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[9,1,2,10] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[17,18,19,20] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[11,3,4,12] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[12,4,1,9] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[13,10,2,14] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[14,2,3,15] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[15,3,11,16] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[16,11,10,13] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[17,13,14,18] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[25,26,27,28] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[19,15,16,20] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[20,16,13,17] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[21,18,14,22] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[22,14,15,23] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[23,15,19,24] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[24,19,18,21] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[25,21,22,26] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[26,22,23,27] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[27,23,24,28] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[33,34,35,36] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[29,28,24,30] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[30,24,21,31] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[31,21,25,32] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[32,25,28,29] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[33,29,30,34] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[37,38,39,40] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[35,31,32,36] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[36,32,29,33] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[37,34,30,38] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[38,30,31,39] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[39,31,35,40] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[41,42,43,44] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[41,40,35,42] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[45,46,47,48] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[43,34,37,44] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[44,37,40,41] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[45,42,35,46] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[46,35,34,47] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[47,34,43,48] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[48,43,42,45] + }] + }, + "locked":true, + "transform":{ + "scale":{ + "x":0.5, + "y":0.5, + "z":0.5 + }, + "pos":{ + "x":2.75, + "y":0.5, + "z":-0.5 + }, + "rot":{ + "x":0, + "y":-0, + "z":0 + } + } + }], + "visible":true, + "name":"35", + "motions":{ + "tracks":[[],[],[],[]] + }, + "folder":true, + "locked":true, + "transform":{ + "scale":{ + "x":1, + "y":1, + "z":1 + }, + "pos":{ + "x":0, + "y":0, + "z":0 + }, + "rot":{ + "x":0, + "y":-0, + "z":0 + } + } + },{ + "ghost":false, + "open":false, + "children":[{ + "ghost":false, + "open":false, + "children":[], + "visible":true, + "name":"40.4", + "motions":{ + "tracks":[[],[],[],[]] + }, + "mesh":{ + "vertices":[0.079052665550982,-0.6328125,0.090075666387746,0.079052665550982,-0.8828125,0.090075666387746,-0.42094733444902,-0.8828125,0.090075666387746,-0.42094733444902,-0.6328125,0.090075666387746,0.079052665550982,-0.6328125,0.59007566638775,0.079052665550982,-0.8828125,0.59007566638775,-0.42094733444902,-0.8828125,0.59007566638775,-0.42094733444902,-0.6328125,0.59007566638775,0.079052665550982,-0.1328125,0.59007566638775,0.079052665550982,-0.1328125,0.090075666387746,-0.42094733444902,-0.1328125,0.090075666387746,-0.42094733444902,-0.1328125,0.59007566638775,-0.42094733444902,-0.1328125,0.84007566638775,-0.42094733444902,-0.6328125,0.84007566638775,0.079052665550982,-0.6328125,0.84007566638775,0.079052665550982,-0.1328125,0.84007566638775,0.079052665550982,-0.1328125,-0.40992433361225,0.079052665550982,-0.6328125,-0.40992433361225,-0.42094733444902,-0.6328125,-0.40992433361225,-0.42094733444902,-0.1328125,-0.40992433361225,0.079052665550982,0.3671875,0.59007566638775,0.079052665550982,0.3671875,0.090075666387746,-0.42094733444902,0.3671875,0.090075666387746,-0.42094733444902,0.3671875,0.59007566638775,0.079052665550982,0.8671875,0.59007566638775,0.079052665550982,0.8671875,0.090075666387746,-0.42094733444902,0.8671875,0.090075666387746,-0.42094733444902,0.8671875,0.59007566638775,0.079052665550982,-0.1328125,-0.90992433361225,0.079052665550982,-0.6328125,-0.90992433361225,-0.42094733444902,-0.6328125,-0.90992433361225,-0.42094733444902,-0.1328125,-0.90992433361225,0.079052665550982,0.8671875,-0.40992433361225,0.079052665550982,0.3671875,-0.15992433361225,-0.42094733444902,0.3671875,-0.15992433361225,-0.42094733444902,0.8671875,-0.40992433361225,0.079052665550982,0.6171875,-0.40992433361225,0.079052665550982,0.1171875,-0.15992433361225,-0.42094733444902,0.1171875,-0.15992433361225,-0.42094733444902,0.6171875,-0.40992433361225,0.079052665550982,0.6171875,-0.65992433361225,0.079052665550982,0.1171875,-0.65992433361225,-0.42094733444902,0.1171875,-0.65992433361225,-0.42094733444902,0.6171875,-0.65992433361225,-0.42094733444902,0.3671875,-0.90992433361225,-0.42094733444902,0.3671875,-0.40992433361225,0.079052665550982,0.3671875,-0.40992433361225,0.079052665550982,0.3671875,-0.90992433361225], + "name":"FOUR.1", + "faces":[{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[1,2,3,4] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[6,5,8,7] + },{ + "color":11, + "uvs":[0.28125,0.46875,0.28125,0.59375,0.15625,0.59375,0.15625,0.46875], + "vertex_ids":[5,6,2,1] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[25,26,27,28] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[2,6,7,3] + },{ + "color":11, + "uvs":[0.28125,0.46875,0.28125,0.59375,0.15625,0.59375,0.15625,0.46875], + "vertex_ids":[4,3,7,8] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[9,5,1,10] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[29,30,31,32] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[11,4,8,12] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[13,14,15,16] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[13,12,8,14] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[14,8,5,15] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[15,5,9,16] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[16,9,12,13] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[17,10,1,18] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[18,1,4,19] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[19,4,11,20] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[20,11,10,17] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[21,9,10,22] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[22,10,11,23] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[23,11,12,24] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[24,12,9,21] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[25,21,22,26] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[41,42,43,44] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[27,23,24,28] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[28,24,21,25] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[29,17,18,30] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[30,18,19,31] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[31,19,20,32] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[45,46,47,48] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[33,26,22,34] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[34,22,23,35] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[35,23,27,36] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[36,27,26,33] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[37,33,34,38] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[38,34,35,39] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[39,35,36,40] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[40,36,33,37] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[41,37,38,42] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[42,38,39,43] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[43,39,40,44] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[44,40,37,41] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[45,32,20,46] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[46,20,17,47] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[47,17,29,48] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[48,29,32,45] + }] + }, + "locked":true, + "transform":{ + "scale":{ + "x":0.5, + "y":0.5, + "z":0.5 + }, + "pos":{ + "x":2.5, + "y":0.5, + "z":-1.5 + }, + "rot":{ + "x":0, + "y":0.78539816339745, + "z":0 + } + } + },{ + "ghost":false, + "open":false, + "children":[], + "visible":true, + "name":"40.0", + "motions":{ + "tracks":[[],[],[],[]] + }, + "mesh":{ + "vertices":[0.13418622324524,0.1171875,-0.16934178504025,0.13418622324524,-0.1328125,-0.16934178504025,-0.36581377675476,-0.1328125,-0.16934178504025,-0.36581377675476,0.1171875,-0.16934178504025,0.13418622324524,0.1171875,0.080658214959755,0.13418622324524,-0.1328125,0.080658214959755,-0.36581377675476,-0.1328125,0.080658214959755,-0.36581377675476,0.1171875,0.080658214959755,0.13418622324524,-0.6328125,-0.66934178504025,0.13418622324524,-0.8828125,-0.66934178504025,-0.36581377675476,-0.8828125,-0.66934178504025,-0.36581377675476,-0.6328125,-0.66934178504025,0.13418622324524,-0.6328125,0.58065821495975,0.13418622324524,-0.8828125,0.58065821495975,-0.36581377675476,-0.8828125,0.58065821495975,-0.36581377675476,-0.6328125,0.58065821495975,0.13418622324524,-0.3828125,0.33065821495975,0.13418622324524,-0.3828125,-0.41934178504025,-0.36581377675476,-0.3828125,-0.41934178504025,-0.36581377675476,-0.3828125,0.33065821495975,-0.36581377675476,-0.3828125,0.83065821495975,-0.36581377675476,-0.6328125,0.83065821495975,0.13418622324524,-0.6328125,0.83065821495975,0.13418622324524,-0.3828125,0.83065821495975,0.13418622324524,-0.3828125,-0.91934178504025,0.13418622324524,-0.6328125,-0.91934178504025,-0.36581377675476,-0.6328125,-0.91934178504025,-0.36581377675476,-0.3828125,-0.91934178504025,0.13418622324524,0.3671875,0.83065821495975,0.13418622324524,0.3671875,0.33065821495975,-0.36581377675476,0.3671875,0.33065821495975,-0.36581377675476,0.3671875,0.83065821495975,-0.36581377675476,0.3671875,-0.91934178504025,-0.36581377675476,0.3671875,-0.41934178504025,0.13418622324524,0.3671875,-0.41934178504025,0.13418622324524,0.3671875,-0.91934178504025,0.13418622324524,0.6171875,0.83065821495975,0.13418622324524,0.6171875,0.58065821495975,-0.36581377675476,0.6171875,0.58065821495975,-0.36581377675476,0.6171875,0.83065821495975,-0.36581377675476,0.6171875,-0.91934178504025,-0.36581377675476,0.6171875,-0.66934178504025,0.13418622324524,0.6171875,-0.66934178504025,0.13418622324524,0.6171875,-0.91934178504025,-0.36581377675476,0.8671875,-0.66934178504025,-0.36581377675476,0.8671875,0.58065821495975,0.13418622324524,0.8671875,0.58065821495975,0.13418622324524,0.8671875,-0.66934178504025], + "name":"Zero.5", + "faces":[{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[1,2,3,4] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[6,5,8,7] + },{ + "color":11, + "uvs":[0.28125,0.46875,0.28125,0.59375,0.15625,0.59375,0.15625,0.46875], + "vertex_ids":[5,6,2,1] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[5,1,4,8] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[2,6,7,3] + },{ + "color":11, + "uvs":[0.28125,0.46875,0.28125,0.59375,0.15625,0.59375,0.15625,0.46875], + "vertex_ids":[4,3,7,8] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[9,10,11,12] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[14,13,16,15] + },{ + "color":11, + "uvs":[0.28125,0.46875,0.28125,0.59375,0.15625,0.59375,0.15625,0.46875], + "vertex_ids":[13,14,10,9] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[17,18,19,20] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[10,14,15,11] + },{ + "color":11, + "uvs":[0.28125,0.46875,0.28125,0.59375,0.15625,0.59375,0.15625,0.46875], + "vertex_ids":[12,11,15,16] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[17,13,9,18] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[25,26,27,28] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[19,12,16,20] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[21,22,23,24] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[21,20,16,22] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[22,16,13,23] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[23,13,17,24] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[37,38,39,40] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[25,18,9,26] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[26,9,12,27] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[27,12,19,28] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[41,42,43,44] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[29,24,17,30] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[30,17,20,31] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[31,20,21,32] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[32,21,24,29] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[33,28,19,34] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[34,19,18,35] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[35,18,25,36] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[36,25,28,33] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[37,29,30,38] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[39,31,32,40] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[40,32,29,37] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[41,33,34,42] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[42,34,35,43] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[43,35,36,44] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[44,36,33,41] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[43,38,30,35] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[35,30,31,34] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[34,31,39,42] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[45,46,47,48] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[45,42,39,46] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[46,39,38,47] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[47,38,43,48] + },{ + "color":11, + "uvs":[0.15625,0.46875,0.28125,0.46875,0.28125,0.59375,0.15625,0.59375], + "vertex_ids":[48,43,42,45] + }] + }, + "locked":true, + "transform":{ + "scale":{ + "x":0.5, + "y":0.5, + "z":0.5 + }, + "pos":{ + "x":2.75, + "y":0.5, + "z":-0.5 + }, + "rot":{ + "x":0, + "y":-0, + "z":0 + } + } + }], + "visible":true, + "name":"40", + "motions":{ + "tracks":[[],[],[],[]] + }, + "folder":true, + "locked":true, + "transform":{ + "scale":{ + "x":1, + "y":1, + "z":1 + }, + "pos":{ + "x":0, + "y":0, + "z":0 + }, + "rot":{ + "x":0, + "y":-0, + "z":0 + } + } + }], + "visible":true, + "name":"pedestal", + "motions":{ + "tracks":[[],[],[],[]] + }, + "folder":true, + "locked":true, + "transform":{ + "scale":{ + "x":1, + "y":1, + "z":1 + }, + "pos":{ + "x":0, + "y":0, + "z":0 + }, + "rot":{ + "x":0, + "y":-0, + "z":0 + } + } + },{ + "ghost":false, + "open":false, + "children":[{ + "ghost":false, + "open":false, + "children":[], + "visible":true, + "name":"Charger.1", + "motions":{ + "tracks":[[],[],[],[]] + }, + "mesh":{ + "vertices":[-0.25,3.1938137821521,-1.8232233047034,0.25,3.1938137821521,-1.8232233047034,0.25,2.5375637821521,-2.0732233047034,-0.25,2.5375637821521,-2.0732233047034,-0.25,3.1938137821521,-1.3232233047034,0.25,3.1938137821521,-1.3232233047034,0.25,2.3422512821521,-1.1825983047034,-0.25,2.3422512821521,-1.1825983047034,0.25,3.4438137821521,-2.3232233047034,0.75,3.9438137821521,-2.3232233047034,0.75,4.4438137821521,-2.3232233047034,0.25,4.9438137821521,-2.3232233047034,-0.25,4.9438137821521,-2.3232233047034,-0.75,4.4438137821521,-2.3232233047034,-0.75,3.9438137821521,-2.3232233047034,-0.25,3.4438137821521,-2.3232233047034,0.25,3.4438137821521,-4.0732233047034,0.75,3.9438137821521,-4.0732233047034,0.75,4.4438137821521,-4.0732233047034,0.25,4.9438137821521,-4.0732233047034,-0.25,4.9438137821521,-4.0732233047034,-0.75,4.4438137821521,-4.0732233047034,-0.75,3.9438137821521,-4.0732233047034,-0.25,3.4438137821521,-4.0732233047034,0.25,3.6938137821521,-2.0732233047034,0.5,3.9438137821521,-2.0732233047034,0.5,4.4438137821521,-2.0732233047034,0.25,4.6938137821521,-2.0732233047034,-0.25,4.6938137821521,-2.0732233047034,-0.5,4.4438137821521,-2.0732233047034,-0.5,3.9438137821521,-2.0732233047034,-0.25,3.6938137821521,-2.0732233047034,-0.25,3.6938137821521,-4.5732233047034,-0.5,3.9438137821521,-4.5732233047034,-0.5,4.4438137821521,-4.5732233047034,-0.25,4.6938137821521,-4.5732233047034,0.25,4.6938137821521,-4.5732233047034,0.5,4.4438137821521,-4.5732233047034,0.5,3.9438137821521,-4.5732233047034,0.25,3.6938137821521,-4.5732233047034,-0.25,3.4438137821521,-2.0732233047034,0.25,3.4438137821521,-2.0732233047034,-0.25,3.4438137821521,-1.0732233047034,0.25,3.4438137821521,-1.0732233047034,-0.25,3.4438137821521,1.6767766952966,-0.5,3.9438137821521,1.4267766952966,0.5,3.9438137821521,1.4267766952966,0.25,3.4438137821521,1.6767766952966,-0.5,3.9438137821521,-1.8232233047034,0.5,3.9438137821521,-1.8232233047034,-0.25,4.9438137821521,3.4267766952966,-0.5,3.9438137821521,3.4267766952966,0.5,3.9438137821521,3.4267766952966,0.25,4.9438137821521,3.4267766952966,-0.25,4.4438137821521,2.9267766952966,-0.25,3.9438137821521,2.9267766952966,0.25,3.9438137821521,2.9267766952966,0.25,4.4438137821521,2.9267766952966,-0.25,4.6938137821521,0.92677669529664,-0.5,3.9438137821521,1.1767766952966,0.5,3.9438137821521,1.1767766952966,0.25,4.6938137821521,0.92677669529664,-0.25,4.6938137821521,-1.8232233047034,0.25,4.6938137821521,-1.8232233047034,0.25,3.9438137821521,-2.0732233047034,0.25,4.4438137821521,-2.0732233047034,-0.25,3.9438137821521,-2.0732233047034,-0.25,4.4438137821521,-2.0732233047034], + "name":"Charger.1", + "faces":[{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[1,2,3,4] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[6,5,8,7] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[5,6,2,1] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[5,1,4,8] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[2,6,7,3] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[4,3,7,8] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.65625,0.75,0.65625,0.6875,0.6875,0.65625,0.75,0.65625,0.78125,0.6875,0.78125,0.75,0.75,0.78125], + "vertex_ids":[25,26,27,28,29,30,31,32] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.65625,0.75,0.65625,0.6875,0.6875,0.65625,0.75,0.65625,0.78125,0.6875,0.78125,0.75,0.75,0.78125], + "vertex_ids":[33,34,35,36,37,38,39,40] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[9,17,18,10] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[10,18,19,11] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[11,19,20,12] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[12,20,21,13] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[13,21,22,14] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[14,22,23,15] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[15,23,24,16] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[16,24,17,9] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[25,9,10,26] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[26,10,11,27] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[27,11,12,28] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[28,12,13,29] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[29,13,14,30] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[30,14,15,31] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[31,15,16,32] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[32,16,9,25] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[33,24,23,34] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[34,23,22,35] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[35,22,21,36] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[36,21,20,37] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[37,20,19,38] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[38,19,18,39] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[39,18,17,40] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[40,17,24,33] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[41,42,2,1] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[44,43,5,6] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[43,44,42,41] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[43,41,1,5] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[42,44,6,2] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[1,2,6,5] + },{ + "color":11, + "uvs":[0.84375,0.78125,0.96875,0.78125,0.96875,0.65625,0.84375,0.65625], + "vertex_ids":[48,47,46,45] + },{ + "color":11, + "uvs":[0.84375,0.78125,0.96875,0.78125,0.96875,0.65625,0.84375,0.65625], + "vertex_ids":[50,42,41,49] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.84375,0.78125,0.96875,0.78125,0.96875,0.65625], + "vertex_ids":[45,46,49,41] + },{ + "color":11, + "uvs":[0.84375,0.78125,0.96875,0.78125,0.96875,0.65625,0.84375,0.65625], + "vertex_ids":[42,48,45,41] + },{ + "color":11, + "uvs":[0.84375,0.78125,0.96875,0.78125,0.96875,0.65625,0.84375,0.65625], + "vertex_ids":[47,50,49,46] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.84375,0.78125,0.96875,0.78125,0.96875,0.65625], + "vertex_ids":[42,50,47,48] + },{ + "color":11, + "uvs":[0.84375,0.46875,0.96875,0.46875,0.96875,0.59375,0.84375,0.59375], + "vertex_ids":[51,52,53,54] + },{ + "color":11, + "uvs":[0.84375,0.46875,0.96875,0.46875,0.96875,0.59375,0.84375,0.59375], + "vertex_ids":[56,55,58,57] + },{ + "color":11, + "uvs":[0.96875,0.46875,0.96875,0.59375,0.84375,0.59375,0.84375,0.46875], + "vertex_ids":[55,56,52,51] + },{ + "color":11, + "uvs":[0.84375,0.46875,0.96875,0.46875,0.96875,0.59375,0.84375,0.59375], + "vertex_ids":[55,51,54,58] + },{ + "color":11, + "uvs":[0.84375,0.46875,0.96875,0.46875,0.96875,0.59375,0.84375,0.59375], + "vertex_ids":[52,56,57,53] + },{ + "color":11, + "uvs":[0.96875,0.46875,0.96875,0.59375,0.84375,0.59375,0.84375,0.46875], + "vertex_ids":[54,53,57,58] + },{ + "color":11, + "uvs":[0.84375,0.46875,0.96875,0.46875,0.96875,0.59375,0.84375,0.59375], + "vertex_ids":[59,60,61,62] + },{ + "color":11, + "uvs":[0.84375,0.46875,0.96875,0.46875,0.96875,0.59375,0.84375,0.59375], + "vertex_ids":[49,63,64,50] + },{ + "color":11, + "uvs":[0.96875,0.46875,0.96875,0.59375,0.84375,0.59375,0.84375,0.46875], + "vertex_ids":[63,49,60,59] + },{ + "color":11, + "uvs":[0.84375,0.46875,0.96875,0.46875,0.96875,0.59375,0.84375,0.59375], + "vertex_ids":[63,59,62,64] + },{ + "color":11, + "uvs":[0.84375,0.46875,0.96875,0.46875,0.96875,0.59375,0.84375,0.59375], + "vertex_ids":[60,49,50,61] + },{ + "color":11, + "uvs":[0.96875,0.46875,0.96875,0.59375,0.84375,0.59375,0.84375,0.46875], + "vertex_ids":[62,61,50,64] + },{ + "color":11, + "uvs":[0.65625,0.46875,0.78125,0.46875,0.78125,0.59375,0.65625,0.59375], + "vertex_ids":[58,57,65,66] + },{ + "color":11, + "uvs":[0.65625,0.46875,0.78125,0.46875,0.78125,0.59375,0.65625,0.59375], + "vertex_ids":[56,55,68,67] + },{ + "color":11, + "uvs":[0.78125,0.46875,0.78125,0.59375,0.65625,0.59375,0.65625,0.46875], + "vertex_ids":[55,56,57,58] + },{ + "color":11, + "uvs":[0.65625,0.46875,0.78125,0.46875,0.78125,0.59375,0.65625,0.59375], + "vertex_ids":[55,58,66,68] + },{ + "color":11, + "uvs":[0.65625,0.46875,0.78125,0.46875,0.78125,0.59375,0.65625,0.59375], + "vertex_ids":[57,56,67,65] + },{ + "color":11, + "uvs":[0.78125,0.46875,0.78125,0.59375,0.65625,0.59375,0.65625,0.46875], + "vertex_ids":[66,65,67,68] + }] + }, + "locked":true, + "transform":{ + "scale":{ + "x":1, + "y":1, + "z":1 + }, + "pos":{ + "x":0, + "y":0.2421875, + "z":1.4296875 + }, + "rot":{ + "x":-0.26179938779915, + "y":-0, + "z":0 + } + } + },{ + "ghost":false, + "open":false, + "children":[], + "visible":true, + "name":"rod.1", + "motions":{ + "tracks":[[],[],[],[]] + }, + "mesh":{ + "vertices":[0.125,0.25,0.125,0.125,-3.25,0.125,-0.125,-3.25,0.125,-0.125,0.25,0.125,0.125,0.25,0.375,0.125,-3.25,0.375,-0.125,-3.25,0.375,-0.125,0.25,0.375], + "name":"cube", + "faces":[{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[1,2,3,4] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[6,5,8,7] + },{ + "color":11, + "uvs":[0.53125,0.65625,0.53125,0.78125,0.40625,0.78125,0.40625,0.65625], + "vertex_ids":[5,6,2,1] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[5,1,4,8] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[2,6,7,3] + },{ + "color":11, + "uvs":[0.5,0.65625,0.5,0.78125,0.375,0.78125,0.375,0.65625], + "vertex_ids":[4,3,7,8] + }] + }, + "locked":true, + "transform":{ + "scale":{ + "x":1, + "y":1, + "z":1 + }, + "pos":{ + "x":0, + "y":3.75, + "z":1 + }, + "rot":{ + "x":0, + "y":-0, + "z":0 + } + } + },{ + "ghost":false, + "open":false, + "children":[], + "visible":true, + "name":"rod.2", + "motions":{ + "tracks":[[],[],[],[]] + }, + "mesh":{ + "vertices":[0.125,0.25,0.125,0.125,-3.25,0.125,-0.125,-3.25,0.125,-0.125,0.25,0.125,0.125,0.25,0.375,0.125,-3.25,0.375,-0.125,-3.25,0.375,-0.125,0.25,0.375], + "name":"cube.5", + "faces":[{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[1,2,3,4] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[6,5,8,7] + },{ + "color":11, + "uvs":[0.53125,0.65625,0.53125,0.78125,0.40625,0.78125,0.40625,0.65625], + "vertex_ids":[5,6,2,1] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[5,1,4,8] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[2,6,7,3] + },{ + "color":11, + "uvs":[0.5,0.65625,0.5,0.78125,0.375,0.78125,0.375,0.65625], + "vertex_ids":[4,3,7,8] + }] + }, + "locked":true, + "transform":{ + "scale":{ + "x":1, + "y":1, + "z":1 + }, + "pos":{ + "x":0, + "y":2.25, + "z":-1 + }, + "rot":{ + "x":0, + "y":-0, + "z":0 + } + } + }], + "visible":true, + "name":"chargers", + "motions":{ + "tracks":[[],[],[],[]] + }, + "folder":true, + "locked":true, + "transform":{ + "scale":{ + "x":1, + "y":1, + "z":1 + }, + "pos":{ + "x":0, + "y":0, + "z":0 + }, + "rot":{ + "x":0, + "y":0, + "z":0 + } + } + },{ + "ghost":false, + "open":false, + "children":[{ + "ghost":false, + "open":false, + "children":[], + "visible":true, + "name":"RollerModel", + "motions":{ + "tracks":[[],[],[],[]] + }, + "mesh":{ + "vertices":[5.5511151231258e-17,-2,0.64644660940673,5.5511151231258e-17,-2.5,0.64644660940673,-0.35355339059327,-2.5,1,-0.35355339059327,-2,1,0.35355339059327,-2,1,0.35355339059327,-2.5,1,0,-2.5,1.3535533905933,-2.7755575615629e-17,-2,1.3535533905933,-0.75,-1.5,0.75,-0.25,-1.25,0.25,0.25,-1.25,0.25,0.75,-1.5,0.75,0.75,-1.75,1.25,0.25,-2,1.75,-0.25,-2,1.75,-0.75,-1.75,1.25,-0.75,-0.75,0.75,-0.25,-0.5,0.25,0.25,-0.5,0.25,0.75,-0.75,0.75,0.75,-1,1.25,0.25,-1.25,1.75,-0.25,-1.25,1.75,-0.75,-1,1.25,-0.5625,-1.8125,0.8125,-0.1875,-1.8125,0.4375,0.1875,-1.8125,0.4375,0.5625,-1.8125,0.8125,0.5625,-1.8125,1.1875,0.1875,-1.8125,1.5625,-0.1875,-1.8125,1.5625,-0.5625,-1.8125,1.1875,-0.5625,-0.6875,0.8125,-0.1875,-0.6875,0.4375,0.1875,-0.6875,0.4375,0.5625,-0.6875,0.8125,0.5625,-0.6875,1.1875,0.1875,-0.6875,1.5625,-0.1875,-0.6875,1.5625,-0.5625,-0.6875,1.1875,-0.375,-0.3125,1,-8.7557618391469e-17,-0.3125,1.375,0.375,-0.3125,1,-1.2919098181491e-16,-0.3125,0.625,-0.375,-2.1875,1,1.0837430010319e-16,-2.1875,0.625,0.375,-2.1875,1,8.7557618391469e-17,-2.1875,1.375,0.25,0.75,-2.140625,0.5,1,-2.140625,0.5,1.5,-2.140625,0.25,1.75,-2.140625,-0.25,1.75,-2.140625,-0.5,1.5,-2.140625,-0.5,1,-2.140625,-0.25,0.75,-2.140625,0.25,0.75,-3.140625,0.5,1,-3.140625,0.5,1.5,-3.140625,0.25,1.75,-3.140625,-0.25,1.75,-3.140625,-0.5,1.5,-3.140625,-0.5,1,-3.140625,-0.25,0.75,-3.140625,0.25,0.5,-2,0.75,1,-2,0.75,1.5,-2,0.25,2,-2,-0.25,2,-2,-0.75,1.5,-2,-0.75,1,-2,-0.25,0.5,-2,0.25,0.5,-3,0.75,1,-3,0.75,1.5,-3,0.25,2,-3,-0.25,2,-3,-0.75,1.5,-3,-0.75,1,-3,-0.25,0.5,-3,-0.25,0.75,2.25,-0.5,1,2.25,-0.5,1.5,2.25,-0.25,1.75,2.25,0.25,1.75,2.25,0.5,1.5,2.25,0.5,1,2.25,0.25,0.75,2.25,-0.25,0.75,3.1640625,-0.5,1,3.1640625,-0.5,1.5,3.1640625,-0.25,1.75,3.1640625,0.25,1.75,3.1640625,0.5,1.5,3.1640625,0.5,1,3.1640625,0.25,0.75,3.1640625,-0.25,0.5,2,-0.75,1,2,-0.75,1.5,2,-0.25,2,2,0.25,2,2,0.75,1.5,2,0.75,1,2,0.25,0.5,2,-0.25,0.5,3,-0.75,1,3,-0.75,1.5,3,-0.25,2,3,0.25,2,3,0.75,1.5,3,0.75,1,3,0.25,0.5,3,0.5,-1.75,-0.25,0.25,-1.75,-0.5,-0.25,-1.75,-0.5,-0.5,-1.75,-0.25,-0.5,-1.75,0.25,-0.25,-1.75,0.5,0.25,-1.75,0.5,0.5,-1.75,0.25,0.5,-3,-0.25,0.25,-3,-0.5,-0.25,-3,-0.5,-0.5,-3,-0.25,-0.5,-3,0.25,-0.25,-3,0.5,0.25,-3,0.5,0.5,-3,0.25,-0.390625,0.359375,-2.75,-0.890625,0.859375,-2.75,-0.890625,1.609375,-2.75,-0.390625,2.109375,-2.75,0.359375,2.109375,-2.75,0.859375,1.609375,-2.75,0.859375,0.859375,-2.75,0.359375,0.359375,-2.75,-0.390625,0.359375,2.75,-0.890625,0.859375,2.75,-0.890625,1.609375,2.75,-0.390625,2.109375,2.75,0.359375,2.109375,2.75,0.859375,1.609375,2.75,0.859375,0.859375,2.75,0.359375,0.359375,2.75,-0.25,-0.25,-0.25,0.25,-0.25,-0.25,0.25,-1.75,-0.25,-0.25,-1.75,-0.25,-0.25,-0.25,0.25,0.25,-0.25,0.25,0.25,-1.75,0.25,-0.25,-1.75,0.25,-0.25,0,0,0.25,0,0,0.25,0.25,-0.25,-0.25,0.25,-0.25,0.25,0.25,-3.5,0.25,-0.25,-3.5,-0.25,-0.25,-3.5,-0.25,0.25,-3.5,0.25,0.25,-4,0.25,0,-3.75,-0.25,0,-3.75,-0.25,0.25,-4,-0.25,1,-4,-0.25,1,-3.5,0.25,1,-3.5,0.25,1,-4,-0.25,1.25,-3.75,-0.25,1.5,-3.5,0.25,1.5,-3.5,0.25,1.25,-3.75,-0.25,1.5,-3,-0.25,1,-3,0.25,1,-3,0.25,1.5,-3], + "name":"RollerModel", + "faces":[{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[1,2,3,4] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[6,5,8,7] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[5,6,2,1] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[5,1,4,8] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[2,6,7,3] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[4,3,7,8] + },{ + "color":10, + "uvs":[0.875,0.59375,0.84375,0.5625,0.84375,0.5,0.875,0.46875,0.9375,0.46875,0.96875,0.5,0.96875,0.5625,0.9375,0.59375], + "vertex_ids":[9,10,11,12,13,14,15,16] + },{ + "color":10, + "uvs":[0.875,0.59375,0.84375,0.5625,0.84375,0.5,0.875,0.46875,0.9375,0.46875,0.96875,0.5,0.96875,0.5625,0.9375,0.59375], + "vertex_ids":[24,23,22,21,20,19,18,17] + },{ + "color":10, + "uvs":[0.96875,0.46875,0.96875,0.59375,0.84375,0.59375,0.84375,0.46875], + "vertex_ids":[9,17,18,10] + },{ + "color":10, + "uvs":[0.96875,0.46875,0.96875,0.59375,0.84375,0.59375,0.84375,0.46875], + "vertex_ids":[10,18,19,11] + },{ + "color":10, + "uvs":[0.96875,0.46875,0.96875,0.59375,0.84375,0.59375,0.84375,0.46875], + "vertex_ids":[11,19,20,12] + },{ + "color":10, + "uvs":[0.96875,0.46875,0.96875,0.59375,0.84375,0.59375,0.84375,0.46875], + "vertex_ids":[12,20,21,13] + },{ + "color":10, + "uvs":[0.96875,0.46875,0.96875,0.59375,0.84375,0.59375,0.84375,0.46875], + "vertex_ids":[13,21,22,14] + },{ + "color":10, + "uvs":[0.96875,0.46875,0.96875,0.59375,0.84375,0.59375,0.84375,0.46875], + "vertex_ids":[14,22,23,15] + },{ + "color":10, + "uvs":[0.96875,0.46875,0.96875,0.59375,0.84375,0.59375,0.84375,0.46875], + "vertex_ids":[15,23,24,16] + },{ + "color":10, + "uvs":[0.96875,0.46875,0.96875,0.59375,0.84375,0.59375,0.84375,0.46875], + "vertex_ids":[16,24,17,9] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.65625,0.75,0.65625,0.6875,0.6875,0.65625,0.75,0.65625,0.78125,0.6875,0.78125,0.75,0.75,0.78125], + "vertex_ids":[45,46,46,47,47,48,48,45] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.65625,0.75,0.65625,0.6875,0.6875,0.65625,0.75,0.65625,0.78125,0.6875,0.78125,0.75,0.75,0.78125], + "vertex_ids":[41,42,42,43,43,44,44,41] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[25,33,34,26] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[26,34,35,27] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[27,35,36,28] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[28,36,37,29] + },{ + "color":10, + "uvs":[0.78125,0.6875,0.78125,0.8125,0.65625,0.8125,0.65625,0.6875], + "vertex_ids":[29,37,38,30] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[30,38,39,31] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[31,39,40,32] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[32,40,33,25] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[41,40,39,42] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[42,39,38,42] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[42,38,37,43] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[43,37,36,43] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[43,36,35,44] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[44,35,34,44] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[44,34,33,41] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[41,33,40,41] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[45,25,26,46] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[46,26,27,46] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[46,27,28,47] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[47,28,29,47] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[47,29,30,48] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[48,30,31,48] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[48,31,32,45] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[45,32,25,45] + },{ + "color":10, + "uvs":[0.875,0.78125,0.84375,0.75,0.84375,0.6875,0.875,0.65625,0.9375,0.65625,0.96875,0.6875,0.96875,0.75,0.9375,0.78125], + "vertex_ids":[64,63,62,61,60,59,58,57] + },{ + "color":10, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[49,57,58,50] + },{ + "color":10, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[50,58,59,51] + },{ + "color":10, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[51,59,60,52] + },{ + "color":10, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[52,60,61,53] + },{ + "color":10, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[53,61,62,54] + },{ + "color":10, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[54,62,63,55] + },{ + "color":10, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[55,63,64,56] + },{ + "color":10, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[56,64,57,49] + },{ + "color":10, + "uvs":[0.875,0.59375,0.84375,0.5625,0.84375,0.5,0.875,0.46875,0.9375,0.46875,0.96875,0.5,0.96875,0.5625,0.9375,0.59375], + "vertex_ids":[80,79,78,77,76,75,74,73] + },{ + "color":10, + "uvs":[0.96875,0.46875,0.96875,0.59375,0.84375,0.59375,0.84375,0.46875], + "vertex_ids":[65,73,74,66] + },{ + "color":10, + "uvs":[0.96875,0.46875,0.96875,0.59375,0.84375,0.59375,0.84375,0.46875], + "vertex_ids":[66,74,75,67] + },{ + "color":10, + "uvs":[0.96875,0.46875,0.96875,0.59375,0.84375,0.59375,0.84375,0.46875], + "vertex_ids":[67,75,76,68] + },{ + "color":10, + "uvs":[0.96875,0.46875,0.96875,0.59375,0.84375,0.59375,0.84375,0.46875], + "vertex_ids":[68,76,77,69] + },{ + "color":10, + "uvs":[0.96875,0.46875,0.96875,0.59375,0.84375,0.59375,0.84375,0.46875], + "vertex_ids":[69,77,78,70] + },{ + "color":10, + "uvs":[0.96875,0.46875,0.96875,0.59375,0.84375,0.59375,0.84375,0.46875], + "vertex_ids":[70,78,79,71] + },{ + "color":10, + "uvs":[0.96875,0.46875,0.96875,0.59375,0.84375,0.59375,0.84375,0.46875], + "vertex_ids":[71,79,80,72] + },{ + "color":10, + "uvs":[0.96875,0.46875,0.96875,0.59375,0.84375,0.59375,0.84375,0.46875], + "vertex_ids":[72,80,73,65] + },{ + "color":10, + "uvs":[0.875,0.78125,0.84375,0.75,0.84375,0.6875,0.875,0.65625,0.9375,0.65625,0.96875,0.6875,0.96875,0.75,0.9375,0.78125], + "vertex_ids":[96,95,94,93,92,91,90,89] + },{ + "color":10, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[81,89,90,82] + },{ + "color":10, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[82,90,91,83] + },{ + "color":10, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[83,91,92,84] + },{ + "color":10, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[84,92,93,85] + },{ + "color":10, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[85,93,94,86] + },{ + "color":10, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[86,94,95,87] + },{ + "color":10, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[87,95,96,88] + },{ + "color":10, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[88,96,89,81] + },{ + "color":10, + "uvs":[0.875,0.59375,0.84375,0.5625,0.84375,0.5,0.875,0.46875,0.9375,0.46875,0.96875,0.5,0.96875,0.5625,0.9375,0.59375], + "vertex_ids":[112,111,110,109,108,107,106,105] + },{ + "color":10, + "uvs":[0.96875,0.46875,0.96875,0.59375,0.84375,0.59375,0.84375,0.46875], + "vertex_ids":[97,105,106,98] + },{ + "color":10, + "uvs":[0.96875,0.46875,0.96875,0.59375,0.84375,0.59375,0.84375,0.46875], + "vertex_ids":[98,106,107,99] + },{ + "color":10, + "uvs":[0.96875,0.46875,0.96875,0.59375,0.84375,0.59375,0.84375,0.46875], + "vertex_ids":[99,107,108,100] + },{ + "color":10, + "uvs":[0.96875,0.46875,0.96875,0.59375,0.84375,0.59375,0.84375,0.46875], + "vertex_ids":[100,108,109,101] + },{ + "color":10, + "uvs":[0.96875,0.46875,0.96875,0.59375,0.84375,0.59375,0.84375,0.46875], + "vertex_ids":[101,109,110,102] + },{ + "color":10, + "uvs":[0.96875,0.46875,0.96875,0.59375,0.84375,0.59375,0.84375,0.46875], + "vertex_ids":[102,110,111,103] + },{ + "color":10, + "uvs":[0.96875,0.46875,0.96875,0.59375,0.84375,0.59375,0.84375,0.46875], + "vertex_ids":[103,111,112,104] + },{ + "color":10, + "uvs":[0.96875,0.46875,0.96875,0.59375,0.84375,0.59375,0.84375,0.46875], + "vertex_ids":[104,112,105,97] + },{ + "color":10, + "uvs":[0.6875,0.59375,0.65625,0.5625,0.65625,0.5,0.6875,0.46875,0.75,0.46875,0.78125,0.5,0.78125,0.5625,0.75,0.59375], + "vertex_ids":[113,114,115,116,117,118,119,120] + },{ + "color":10, + "uvs":[0.6875,0.59375,0.65625,0.5625,0.65625,0.5,0.6875,0.46875,0.75,0.46875,0.78125,0.5,0.78125,0.5625,0.75,0.59375], + "vertex_ids":[128,127,126,125,124,123,122,121] + },{ + "color":10, + "uvs":[0.78125,0.46875,0.78125,0.59375,0.65625,0.59375,0.65625,0.46875], + "vertex_ids":[113,121,122,114] + },{ + "color":10, + "uvs":[0.78125,0.46875,0.78125,0.59375,0.65625,0.59375,0.65625,0.46875], + "vertex_ids":[114,122,123,115] + },{ + "color":10, + "uvs":[0.78125,0.46875,0.78125,0.59375,0.65625,0.59375,0.65625,0.46875], + "vertex_ids":[115,123,124,116] + },{ + "color":10, + "uvs":[0.78125,0.46875,0.78125,0.59375,0.65625,0.59375,0.65625,0.46875], + "vertex_ids":[116,124,125,117] + },{ + "color":10, + "uvs":[0.78125,0.46875,0.78125,0.59375,0.65625,0.59375,0.65625,0.46875], + "vertex_ids":[117,125,126,118] + },{ + "color":10, + "uvs":[0.78125,0.46875,0.78125,0.59375,0.65625,0.59375,0.65625,0.46875], + "vertex_ids":[118,126,127,119] + },{ + "color":10, + "uvs":[0.78125,0.46875,0.78125,0.59375,0.65625,0.59375,0.65625,0.46875], + "vertex_ids":[119,127,128,120] + },{ + "color":10, + "uvs":[0.78125,0.46875,0.78125,0.59375,0.65625,0.59375,0.65625,0.46875], + "vertex_ids":[120,128,121,113] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.65625,0.75,0.65625,0.6875,0.6875,0.65625,0.75,0.65625,0.78125,0.6875,0.78125,0.75,0.75,0.78125], + "vertex_ids":[129,130,131,132,133,134,135,136] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.65625,0.75,0.65625,0.6875,0.6875,0.65625,0.75,0.65625,0.78125,0.6875,0.78125,0.75,0.75,0.78125], + "vertex_ids":[144,143,142,141,140,139,138,137] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[129,137,138,130] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[130,138,139,131] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[131,139,140,132] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[132,140,141,133] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[133,141,142,134] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[134,142,143,135] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[135,143,144,136] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[136,144,137,129] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[145,146,147,148] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[150,149,152,151] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[153,154,155,156] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[149,145,148,152] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[146,150,151,147] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[148,147,151,152] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[153,149,150,154] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[154,150,146,155] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[161,162,163,164] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[156,145,149,153] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[157,155,146,158] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[158,146,145,159] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[159,145,156,160] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[160,156,155,157] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[161,157,158,162] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[162,158,159,163] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[163,159,160,164] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[169,170,171,172] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[165,164,160,166] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[166,160,157,167] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[167,157,161,168] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[168,161,164,165] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[169,165,166,170] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[173,174,175,176] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[171,167,168,172] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[172,168,165,169] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[173,170,166,174] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[174,166,167,175] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[175,167,171,176] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[176,171,170,173] + }] + }, + "locked":true, + "transform":{ + "scale":{ + "x":1, + "y":1, + "z":1 + }, + "pos":{ + "x":0, + "y":5, + "z":0 + }, + "rot":{ + "x":0.26179938779915, + "y":-0, + "z":0 + } + } + },{ + "ghost":false, + "open":true, + "children":[], + "visible":true, + "name":"rod.1", + "motions":{ + "tracks":[[],[],[],[]] + }, + "mesh":{ + "vertices":[0.125,1.5,0.125,0.125,-3.25,0.125,-0.125,-3.25,0.125,-0.125,1.5,0.125,0.125,1.5,0.375,0.125,-3.25,0.375,-0.125,-3.25,0.375,-0.125,1.5,0.375], + "name":"cube.9", + "faces":[{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[1,2,3,4] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[6,5,8,7] + },{ + "color":11, + "uvs":[0.53125,0.65625,0.53125,0.78125,0.40625,0.78125,0.40625,0.65625], + "vertex_ids":[5,6,2,1] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[5,1,4,8] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[2,6,7,3] + },{ + "color":11, + "uvs":[0.5,0.65625,0.5,0.78125,0.375,0.78125,0.375,0.65625], + "vertex_ids":[4,3,7,8] + }] + }, + "locked":true, + "transform":{ + "scale":{ + "x":1, + "y":1, + "z":1 + }, + "pos":{ + "x":0, + "y":4, + "z":-2.25 + }, + "rot":{ + "x":0, + "y":-0, + "z":0 + } + } + },{ + "ghost":false, + "open":false, + "children":[], + "visible":true, + "name":"rod.2", + "motions":{ + "tracks":[[],[],[],[]] + }, + "mesh":{ + "vertices":[0.125,1.75,0.125,0.125,-3.25,0.125,-0.125,-3.25,0.125,-0.125,1.75,0.125,0.125,1.75,0.375,0.125,-3.25,0.375,-0.125,-3.25,0.375,-0.125,1.75,0.375], + "name":"cube.8", + "faces":[{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[1,2,3,4] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[6,5,8,7] + },{ + "color":11, + "uvs":[0.53125,0.65625,0.53125,0.78125,0.40625,0.78125,0.40625,0.65625], + "vertex_ids":[5,6,2,1] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[5,1,4,8] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[2,6,7,3] + },{ + "color":11, + "uvs":[0.5,0.65625,0.5,0.78125,0.375,0.78125,0.375,0.65625], + "vertex_ids":[4,3,7,8] + }] + }, + "locked":true, + "transform":{ + "scale":{ + "x":1, + "y":1, + "z":1 + }, + "pos":{ + "x":0, + "y":3.75, + "z":1.75 + }, + "rot":{ + "x":0, + "y":-0, + "z":0 + } + } + }], + "visible":true, + "name":"rollers", + "motions":{ + "tracks":[[],[],[],[]] + }, + "folder":true, + "locked":true, + "transform":{ + "scale":{ + "x":1, + "y":1, + "z":1 + }, + "pos":{ + "x":0, + "y":0, + "z":0 + }, + "rot":{ + "x":0, + "y":0, + "z":0 + } + } + },{ + "ghost":false, + "open":false, + "children":[{ + "ghost":false, + "open":false, + "children":[], + "visible":true, + "name":"Shooter.1", + "motions":{ + "tracks":[[],[],[],[]] + }, + "mesh":{ + "vertices":[1.140625,2,-1.3652833195514,0.640625,1.5,-1.6152833195514,-0.609375,1.5,-1.6152833195514,-1.109375,2,-1.3652833195514,1.140625,2,-0.61528331955145,0.640625,1.5,-0.86528331955145,-0.609375,1.5,-0.86528331955145,-1.109375,2,-0.61528331955145,1.140625,3,-0.36528331955145,1.140625,3,-1.1152833195514,-1.109375,3,-1.1152833195514,-1.109375,3,-0.36528331955145,0.640625,3.6268094313826,-0.36528331955145,0.640625,3.6268094313826,-0.86528331955145,-0.609375,3.6268094313826,-0.86528331955145,-0.609375,3.6268094313826,-0.36528331955145,1.140625,2,-0.11528331955145,0.640625,1.5,0.13471668044855,-0.609375,1.5,0.13471668044855,-1.109375,2,-0.11528331955145,1.140625,2,0.63471668044855,0.640625,1.5,0.88471668044855,-0.609375,1.5,0.88471668044855,-1.109375,2,0.63471668044855,1.140625,3,0.38471668044855,-1.109375,3,0.38471668044855,0.640625,3.6268094313826,0.13471668044855,0.640625,3.6268094313826,-0.61528331955145,-0.609375,3.6268094313826,-0.61528331955145,-0.609375,3.6268094313826,0.13471668044855,-0.25,2,-2.7038866721794,-0.5,2.25,-2.7038866721794,-0.5,2.75,-2.7038866721794,-0.25,3,-2.7038866721794,0.25,3,-2.7038866721794,0.5,2.75,-2.7038866721794,0.5,2.25,-2.7038866721794,0.25,2,-2.7038866721794,-0.25,2,-2,-0.5,2.25,-2,-0.5,2.75,-2,-0.25,3,-2,0.25,3,-2,0.5,2.75,-2,0.5,2.25,-2,0.25,2,-2,-0.5,1.5,-1.25,-1,2,-1.25,-1,3,-1.25,-0.5,3.5,-1.25,0.5,3.5,-1.25,1,3,-1.25,1,2,-1.25,0.5,1.5,-1.25,-0.5,1.5,1.25,-1,2,1.25,-1,3,1.25,-0.5,3.5,1.25,0.5,3.5,1.25,1,3,1.25,1,2,1.25,0.5,1.5,1.25,-0.25,1.75,-2,-0.75,2.25,-2,-0.75,2.75,-2,-0.25,3.25,-2,0.25,3.25,-2,0.75,2.75,-2,0.75,2.25,-2,0.25,1.75,-2,0.25,1.75,2,0.75,2.25,2,0.75,2.75,2,0.25,3.25,2,-0.25,3.25,2,-0.75,2.75,2,-0.75,2.25,2,-0.25,1.75,2,0.25,2.75,2,0.25,2.25,2,-0.25,2.25,2,-0.25,2.75,2,0.75,3.25,3,0.75,1.75,3,-0.75,1.75,3,-0.75,3.25,3,0.5,1.5,0,0.5,0.75,0,-0.5,0.75,0,-0.5,1.5,0,0.5,0.75,1.25,-0.5,0.75,1.25,0.5,0.5,-1.5,0.5,-0.5,-1.75,-0.5,-0.5,-1.75,-0.5,0.5,-1.5,0.5,0.25,-0.75,0.5,-0.5,-0.25,-0.5,-0.5,-0.25,-0.5,0.25,-0.75,0.5,1.5,-0.75,0.5,1.5,-1.75,-0.5,1.5,-1.75,-0.5,1.5,-0.75,-0.5,1.5,0.5,-0.5,0.5,0,0.5,0.5,0,0.5,1.5,0.5], + "name":"Shooter.1", + "faces":[{ + "color":8, + "uvs":[0.84375,0.46875,0.96875,0.46875,0.96875,0.59375,0.84375,0.59375], + "vertex_ids":[1,2,3,4] + },{ + "color":8, + "uvs":[0.84375,0.46875,0.96875,0.46875,0.96875,0.59375,0.84375,0.59375], + "vertex_ids":[6,5,8,7] + },{ + "color":8, + "uvs":[0.96875,0.46875,0.96875,0.59375,0.84375,0.59375,0.84375,0.46875], + "vertex_ids":[5,6,2,1] + },{ + "color":8, + "uvs":[0.84375,0.46875,0.96875,0.46875,0.96875,0.59375,0.84375,0.59375], + "vertex_ids":[13,14,15,16] + },{ + "color":8, + "uvs":[0.84375,0.46875,0.96875,0.46875,0.96875,0.59375,0.84375,0.59375], + "vertex_ids":[2,6,7,3] + },{ + "color":8, + "uvs":[0.96875,0.46875,0.96875,0.59375,0.84375,0.59375,0.84375,0.46875], + "vertex_ids":[4,3,7,8] + },{ + "color":8, + "uvs":[0.84375,0.46875,0.96875,0.46875,0.96875,0.59375,0.84375,0.59375], + "vertex_ids":[9,5,1,10] + },{ + "color":8, + "uvs":[0.84375,0.46875,0.96875,0.46875,0.96875,0.59375,0.84375,0.59375], + "vertex_ids":[10,1,4,11] + },{ + "color":8, + "uvs":[0.84375,0.46875,0.96875,0.46875,0.96875,0.59375,0.84375,0.59375], + "vertex_ids":[11,4,8,12] + },{ + "color":8, + "uvs":[0.84375,0.46875,0.96875,0.46875,0.96875,0.59375,0.84375,0.59375], + "vertex_ids":[12,8,5,9] + },{ + "color":8, + "uvs":[0.84375,0.46875,0.96875,0.46875,0.96875,0.59375,0.84375,0.59375], + "vertex_ids":[13,9,10,14] + },{ + "color":8, + "uvs":[0.84375,0.46875,0.96875,0.46875,0.96875,0.59375,0.84375,0.59375], + "vertex_ids":[14,10,11,15] + },{ + "color":8, + "uvs":[0.84375,0.46875,0.96875,0.46875,0.96875,0.59375,0.84375,0.59375], + "vertex_ids":[15,11,12,16] + },{ + "color":8, + "uvs":[0.84375,0.46875,0.96875,0.46875,0.96875,0.59375,0.84375,0.59375], + "vertex_ids":[16,12,9,13] + },{ + "color":8, + "uvs":[0.84375,0.46875,0.96875,0.46875,0.96875,0.59375,0.84375,0.59375], + "vertex_ids":[17,18,19,20] + },{ + "color":8, + "uvs":[0.84375,0.46875,0.96875,0.46875,0.96875,0.59375,0.84375,0.59375], + "vertex_ids":[22,21,24,23] + },{ + "color":8, + "uvs":[0.96875,0.46875,0.96875,0.59375,0.84375,0.59375,0.84375,0.46875], + "vertex_ids":[21,22,18,17] + },{ + "color":8, + "uvs":[0.84375,0.46875,0.96875,0.46875,0.96875,0.59375,0.84375,0.59375], + "vertex_ids":[27,28,29,30] + },{ + "color":8, + "uvs":[0.84375,0.46875,0.96875,0.46875,0.96875,0.59375,0.84375,0.59375], + "vertex_ids":[18,22,23,19] + },{ + "color":8, + "uvs":[0.96875,0.46875,0.96875,0.59375,0.84375,0.59375,0.84375,0.46875], + "vertex_ids":[20,19,23,24] + },{ + "color":8, + "uvs":[0.84375,0.46875,0.96875,0.46875,0.96875,0.59375,0.84375,0.59375], + "vertex_ids":[25,21,17,9] + },{ + "color":8, + "uvs":[0.84375,0.46875,0.96875,0.46875,0.96875,0.59375,0.84375,0.59375], + "vertex_ids":[9,17,20,12] + },{ + "color":8, + "uvs":[0.84375,0.46875,0.96875,0.46875,0.96875,0.59375,0.84375,0.59375], + "vertex_ids":[12,20,24,26] + },{ + "color":8, + "uvs":[0.84375,0.46875,0.96875,0.46875,0.96875,0.59375,0.84375,0.59375], + "vertex_ids":[26,24,21,25] + },{ + "color":8, + "uvs":[0.84375,0.46875,0.96875,0.46875,0.96875,0.59375,0.84375,0.59375], + "vertex_ids":[27,25,9,28] + },{ + "color":8, + "uvs":[0.84375,0.46875,0.96875,0.46875,0.96875,0.59375,0.84375,0.59375], + "vertex_ids":[28,9,12,29] + },{ + "color":8, + "uvs":[0.84375,0.46875,0.96875,0.46875,0.96875,0.59375,0.84375,0.59375], + "vertex_ids":[29,12,26,30] + },{ + "color":8, + "uvs":[0.84375,0.46875,0.96875,0.46875,0.96875,0.59375,0.84375,0.59375], + "vertex_ids":[30,26,25,27] + },{ + "color":10, + "uvs":[0.875,0.78125,0.84375,0.75,0.84375,0.6875,0.875,0.65625,0.9375,0.65625,0.96875,0.6875,0.96875,0.75,0.9375,0.78125], + "vertex_ids":[31,32,33,34,35,36,37,38] + },{ + "color":10, + "uvs":[0.875,0.78125,0.84375,0.75,0.84375,0.6875,0.875,0.65625,0.9375,0.65625,0.96875,0.6875,0.96875,0.75,0.9375,0.78125], + "vertex_ids":[46,45,44,43,42,41,40,39] + },{ + "color":10, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[31,39,40,32] + },{ + "color":10, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[32,40,41,33] + },{ + "color":10, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[33,41,42,34] + },{ + "color":10, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[34,42,43,35] + },{ + "color":10, + "uvs":[0.9609375,0.65625,0.9609375,0.78125,0.8359375,0.78125,0.8359375,0.65625], + "vertex_ids":[35,43,44,36] + },{ + "color":10, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[36,44,45,37] + },{ + "color":10, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[37,45,46,38] + },{ + "color":10, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[38,46,39,31] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.65625,0.75,0.65625,0.6875,0.6875,0.65625,0.75,0.65625,0.78125,0.6875,0.78125,0.75,0.75,0.78125], + "vertex_ids":[63,64,65,66,67,68,69,70] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.65625,0.75,0.65625,0.6875,0.6875,0.65625,0.75,0.65625,0.78125,0.6875,0.78125,0.75,0.75,0.78125], + "vertex_ids":[71,72,73,74,75,76,77,78] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[47,55,56,48] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[48,56,57,49] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[49,57,58,50] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[50,58,59,51] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[51,59,60,52] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[52,60,61,53] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[53,61,62,54] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[54,62,55,47] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[63,47,48,64] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[64,48,49,65] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[65,49,50,66] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[66,50,51,67] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[67,51,52,68] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[68,52,53,69] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[69,53,54,70] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[70,54,47,63] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[71,62,61,72] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[72,61,60,73] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[73,60,59,74] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[74,59,58,75] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[75,58,57,76] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[76,57,56,77] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[77,56,55,78] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[78,55,62,71] + },{ + "color":8, + "uvs":[0.84375,0.46875,0.96875,0.46875,0.96875,0.59375,0.84375,0.59375], + "vertex_ids":[79,80,81,82] + },{ + "color":8, + "uvs":[0.84375,0.46875,0.96875,0.46875,0.96875,0.59375,0.84375,0.59375], + "vertex_ids":[84,83,86,85] + },{ + "color":8, + "uvs":[0.96875,0.46875,0.96875,0.59375,0.84375,0.59375,0.84375,0.46875], + "vertex_ids":[83,84,80,79] + },{ + "color":8, + "uvs":[0.84375,0.46875,0.96875,0.46875,0.96875,0.59375,0.84375,0.59375], + "vertex_ids":[83,79,82,86] + },{ + "color":8, + "uvs":[0.84375,0.46875,0.96875,0.46875,0.96875,0.59375,0.84375,0.59375], + "vertex_ids":[80,84,85,81] + },{ + "color":8, + "uvs":[0.96875,0.46875,0.96875,0.59375,0.84375,0.59375,0.84375,0.46875], + "vertex_ids":[82,81,85,86] + },{ + "color":8, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[87,88,89,90] + },{ + "color":8, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[91,62,55,92] + },{ + "color":8, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[62,91,88,87] + },{ + "color":8, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[62,87,90,55] + },{ + "color":8, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[88,91,92,89] + },{ + "color":8, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[90,89,92,55] + },{ + "color":8, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[93,94,95,96] + },{ + "color":8, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[98,97,100,99] + },{ + "color":8, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[97,98,94,93] + },{ + "color":8, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[101,102,103,104] + },{ + "color":8, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[94,98,99,95] + },{ + "color":8, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[96,95,99,100] + },{ + "color":8, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[101,97,93,102] + },{ + "color":8, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[102,93,96,103] + },{ + "color":8, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[103,96,100,104] + },{ + "color":8, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[105,106,107,108] + },{ + "color":8, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[105,104,100,106] + },{ + "color":8, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[106,100,97,107] + },{ + "color":8, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[107,97,101,108] + },{ + "color":8, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[108,101,104,105] + }] + }, + "locked":true, + "transform":{ + "scale":{ + "x":1, + "y":1, + "z":1 + }, + "pos":{ + "x":0, + "y":2.75, + "z":0.25 + }, + "rot":{ + "x":-0.26179938779915, + "y":-0, + "z":0 + } + } + },{ + "ghost":false, + "open":false, + "children":[], + "visible":true, + "name":"rod.1", + "motions":{ + "tracks":[[],[],[],[]] + }, + "mesh":{ + "vertices":[0.125,1.75,0.125,0.125,-3.25,0.125,-0.125,-3.25,0.125,-0.125,1.75,0.125,0.125,1.75,0.375,0.125,-3.25,0.375,-0.125,-3.25,0.375,-0.125,1.75,0.375], + "name":"cube.13", + "faces":[{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[1,2,3,4] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[6,5,8,7] + },{ + "color":11, + "uvs":[0.53125,0.65625,0.53125,0.78125,0.40625,0.78125,0.40625,0.65625], + "vertex_ids":[5,6,2,1] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[5,1,4,8] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[2,6,7,3] + },{ + "color":11, + "uvs":[0.5,0.65625,0.5,0.78125,0.375,0.78125,0.375,0.65625], + "vertex_ids":[4,3,7,8] + }] + }, + "locked":true, + "transform":{ + "scale":{ + "x":1, + "y":1, + "z":1 + }, + "pos":{ + "x":0, + "y":2.5, + "z":0.75 + }, + "rot":{ + "x":0, + "y":-0, + "z":0 + } + } + },{ + "ghost":false, + "open":true, + "children":[], + "visible":true, + "name":"rod.2", + "motions":{ + "tracks":[[],[],[],[]] + }, + "mesh":{ + "vertices":[0.125,3.75,-0.125,0.125,-1,-0.125,-0.125,-1,-0.125,-0.125,3.75,-0.125,0.125,3.75,0.125,0.125,-1,0.125,-0.125,-1,0.125,-0.125,3.75,0.125], + "name":"cube.12", + "faces":[{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[1,2,3,4] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[6,5,8,7] + },{ + "color":11, + "uvs":[0.53125,0.65625,0.53125,0.78125,0.40625,0.78125,0.40625,0.65625], + "vertex_ids":[5,6,2,1] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[5,1,4,8] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[2,6,7,3] + },{ + "color":11, + "uvs":[0.5,0.65625,0.5,0.78125,0.375,0.78125,0.375,0.65625], + "vertex_ids":[4,3,7,8] + }] + }, + "locked":true, + "transform":{ + "scale":{ + "x":1, + "y":1, + "z":1 + }, + "pos":{ + "x":0, + "y":0, + "z":-1.6015625 + }, + "rot":{ + "x":0, + "y":-0, + "z":0 + } + } + }], + "visible":true, + "name":"shooters", + "motions":{ + "tracks":[[],[],[],[]] + }, + "folder":true, + "locked":true, + "transform":{ + "scale":{ + "x":1, + "y":1, + "z":1 + }, + "pos":{ + "x":0, + "y":0, + "z":0 + }, + "rot":{ + "x":0, + "y":0, + "z":0 + } + } + },{ + "ghost":false, + "open":false, + "children":[{ + "ghost":false, + "open":false, + "children":[], + "visible":true, + "name":"DualiesUNO", + "motions":{ + "tracks":[[],[],[],[]] + }, + "mesh":{ + "vertices":[-0.4375,4.125,2.5625,-0.625,4.3125,2.5625,-0.625,4.6875,2.5625,-0.4375,4.875,2.5625,-0.062500000000001,4.875,2.5625,0.125,4.6875,2.5625,0.125,4.3125,2.5625,-0.062500000000001,4.125,2.5625,-0.4375,4.125,3.125,-0.625,4.3125,3.125,-0.625,4.6875,3.125,-0.4375,4.875,3.125,-0.062499999999999,4.875,3.125,0.125,4.6875,3.125,0.125,4.3125,3.125,-0.062499999999999,4.125,3.125,-0.375,4.125,1.75,-0.625,4.375,1.75,-0.625,4.625,1.75,-0.375,4.875,1.75,-0.125,4.875,1.75,0.125,4.625,1.75,0.125,4.375,1.75,-0.125,4.125,1.75,-0.5,3.875,2.875,-0.875,4.25,2.875,-0.875,4.75,2.875,-0.5,5.125,2.875,3.0531133177192e-15,5.125,2.875,0.375,4.75,2.875,0.375,4.25,2.875,3.0531133177192e-15,3.875,2.875,-0.07224410137778,3.7734375,1.5,-0.07224410137778,3.0234375,1.25,-0.4296875,3.0234375,1.25,-0.4296875,3.7734375,1.5,-0.07224410137778,3.7734375,2,-0.07224410137778,3.0234375,1.75,-0.4296875,3.0234375,1.75,-0.4296875,3.7734375,2,-0.07224410137778,4.5234375,2,-0.07224410137778,4.2734375,1,-0.4296875,4.2734375,1,-0.4296875,4.5234375,2,0,4.25,-0.25,0,3.75,-0.25,-0.5,3.75,-0.25,-0.5,4.25,-0.25,0,4,1,0,3.75,0.75,-0.5,3.75,0.75,-0.5,4,1,0,4,-0.75,-0.5,4,-0.75,0,4.75,0.75,0,4.5,0,-0.5,4.5,0,-0.5,4.75,0.75,-0.5,4.75,1.75,-0.5,4.25,1.75,0,4.25,1.75,0,4.75,1.75,-0.125,3.0183731652573,1.6295371454337,-0.125,3.1433731652573,1.4130307944876,-0.375,3.1433731652573,1.4130307944876,-0.375,3.0183731652573,1.6295371454337,-0.125,2.368854112419,1.2545371454337,-0.125,2.493854112419,1.0380307944876,-0.375,2.493854112419,1.0380307944876,-0.375,2.368854112419,1.2545371454337,-0.125,2.6171875,0.5078125,-0.125,2.3671875,0.5078125,-0.375,2.3671875,0.5078125,-0.375,2.6171875,0.5078125,-0.125,2.6171875,1.2578125,-0.375,2.6171875,1.2578125,-0.1171875,4.015625,0,-0.1171875,2.515625,-0.5,-0.3671875,2.515625,-0.5,-0.3671875,4.015625,0,-0.1171875,4.015625,0.62653062314252,-0.1171875,2.515625,0.25,-0.3671875,2.515625,0.25,-0.3671875,4.015625,0.62653062314252,-0.25,2.8535533905933,-0.75,0.10355339059327,2.5,-0.75,-0.25,2.1464466094067,-0.75,-0.60355339059327,2.5,-0.75,-0.25,2.8535533905933,0.5,0.10355339059327,2.5,0.5,-0.25,2.1464466094067,0.5,-0.60355339059327,2.5,0.5,-0.096016886276438,1.9626088941116,-1.5,-0.44924817255421,1.9776972470551,-1.5,-0.78739110588844,2.3460168862764,-1.5,-0.77230275294489,2.6992481725542,-1.5,-0.40398311372356,3.0373911058884,-1.5,-0.050751827445789,3.0223027529449,-1.5,0.28739110588844,2.6539831137236,-1.5,0.27230275294489,2.3007518274458,-1.5,-0.096016886276437,1.9626088941116,-0.75,-0.44924817255421,1.9776972470551,-0.75,-0.78739110588844,2.3460168862764,-0.75,-0.77230275294489,2.6992481725542,-0.75,-0.40398311372356,3.0373911058884,-0.75,-0.050751827445788,3.0223027529449,-0.75,0.28739110588844,2.6539831137236,-0.75,0.27230275294489,2.3007518274458,-0.75,0.030074691562397,2.488036547268,-0.5,-0.238036547268,2.7800746915624,-0.5,-0.5300746915624,2.511963452732,-0.5,-0.261963452732,2.2199253084376,-0.5,-0.096016886276438,1.9626088941116,-1.75,-0.44924817255421,1.9776972470551,-1.75,-0.78739110588844,2.3460168862764,-1.75,-0.77230275294489,2.6992481725542,-1.75,-0.40398311372356,3.0373911058884,-1.75,-0.050751827445789,3.0223027529449,-1.75,0.28739110588844,2.6539831137236,-1.75,0.27230275294489,2.3007518274458,-1.75], + "name":"DualiesUNO", + "faces":[{ + "color":10, + "uvs":[0.875,0.78125,0.84375,0.75,0.84375,0.6875,0.875,0.65625,0.9375,0.65625,0.96875,0.6875,0.96875,0.75,0.9375,0.78125], + "vertex_ids":[1,2,3,4,5,6,7,8] + },{ + "color":10, + "uvs":[0.875,0.78125,0.84375,0.75,0.84375,0.6875,0.875,0.65625,0.9375,0.65625,0.96875,0.6875,0.96875,0.75,0.9375,0.78125], + "vertex_ids":[16,15,14,13,12,11,10,9] + },{ + "color":10, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[1,9,10,2] + },{ + "color":10, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[2,10,11,3] + },{ + "color":10, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[3,11,12,4] + },{ + "color":10, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[4,12,13,5] + },{ + "color":10, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[5,13,14,6] + },{ + "color":10, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[6,14,15,7] + },{ + "color":10, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[7,15,16,8] + },{ + "color":10, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[8,16,9,1] + },{ + "color":10, + "uvs":[0.875,0.59375,0.84375,0.5625,0.84375,0.5,0.875,0.46875,0.9375,0.46875,0.96875,0.5,0.96875,0.5625,0.9375,0.59375], + "vertex_ids":[17,18,19,20,21,22,23,24] + },{ + "color":10, + "uvs":[0.875,0.59375,0.84375,0.5625,0.84375,0.5,0.875,0.46875,0.9375,0.46875,0.96875,0.5,0.96875,0.5625,0.9375,0.59375], + "vertex_ids":[32,31,30,29,28,27,26,25] + },{ + "color":10, + "uvs":[0.96875,0.46875,0.96875,0.59375,0.84375,0.59375,0.84375,0.46875], + "vertex_ids":[17,25,26,18] + },{ + "color":10, + "uvs":[0.96875,0.46875,0.96875,0.59375,0.84375,0.59375,0.84375,0.46875], + "vertex_ids":[18,26,27,19] + },{ + "color":10, + "uvs":[0.96875,0.46875,0.96875,0.59375,0.84375,0.59375,0.84375,0.46875], + "vertex_ids":[19,27,28,20] + },{ + "color":10, + "uvs":[0.96875,0.46875,0.96875,0.59375,0.84375,0.59375,0.84375,0.46875], + "vertex_ids":[20,28,29,21] + },{ + "color":10, + "uvs":[0.96875,0.46875,0.96875,0.59375,0.84375,0.59375,0.84375,0.46875], + "vertex_ids":[21,29,30,22] + },{ + "color":10, + "uvs":[0.96875,0.46875,0.96875,0.59375,0.84375,0.59375,0.84375,0.46875], + "vertex_ids":[22,30,31,23] + },{ + "color":10, + "uvs":[0.96875,0.46875,0.96875,0.59375,0.84375,0.59375,0.84375,0.46875], + "vertex_ids":[23,31,32,24] + },{ + "color":10, + "uvs":[0.96875,0.46875,0.96875,0.59375,0.84375,0.59375,0.84375,0.46875], + "vertex_ids":[24,32,25,17] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[33,34,35,36] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[38,37,40,39] + },{ + "color":11, + "uvs":[0.5,0,0.5,0.125,0.375,0.125,0.375,0], + "vertex_ids":[37,38,34,33] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[41,42,43,44] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[34,38,39,35] + },{ + "color":11, + "uvs":[0.5,0,0.5,0.125,0.375,0.125,0.375,0], + "vertex_ids":[36,35,39,40] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[41,37,33,42] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[42,33,36,43] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[43,36,40,44] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[44,40,37,41] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[53,53,54,54] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[50,49,52,51] + },{ + "color":11, + "uvs":[0.5,0,0.5,0.125,0.375,0.125,0.375,0], + "vertex_ids":[49,50,46,45] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[55,56,57,58] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[46,50,51,47] + },{ + "color":11, + "uvs":[0.5,0,0.5,0.125,0.375,0.125,0.375,0], + "vertex_ids":[48,47,51,52] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[53,45,46,53] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[53,46,47,54] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[54,47,48,54] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[54,48,45,53] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[55,49,45,56] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[56,45,48,57] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[57,48,52,58] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[59,60,61,62] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[59,58,52,60] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[60,52,49,61] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[61,49,55,62] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[62,55,58,59] + },{ + "color":11, + "uvs":[0.40625,0.65625,0.53125,0.65625,0.53125,0.78125,0.40625,0.78125], + "vertex_ids":[63,64,65,66] + },{ + "color":11, + "uvs":[0.4375,0.65625,0.5625,0.65625,0.5625,0.78125,0.4375,0.78125], + "vertex_ids":[68,67,70,69] + },{ + "color":11, + "uvs":[0.53125,0.65625,0.53125,0.78125,0.40625,0.78125,0.40625,0.65625], + "vertex_ids":[67,68,64,63] + },{ + "color":11, + "uvs":[0.4375,0.65625,0.5625,0.65625,0.5625,0.78125,0.4375,0.78125], + "vertex_ids":[67,63,66,70] + },{ + "color":11, + "uvs":[0.4375,0.65625,0.5625,0.65625,0.5625,0.78125,0.4375,0.78125], + "vertex_ids":[64,68,69,65] + },{ + "color":11, + "uvs":[0.53125,0.65625,0.53125,0.78125,0.40625,0.78125,0.40625,0.65625], + "vertex_ids":[66,65,69,70] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[71,72,73,74] + },{ + "color":11, + "uvs":[0.4375,0.65625,0.5625,0.65625,0.5625,0.78125,0.4375,0.78125], + "vertex_ids":[67,75,76,70] + },{ + "color":11, + "uvs":[0.53125,0.65625,0.53125,0.78125,0.40625,0.78125,0.40625,0.65625], + "vertex_ids":[75,67,72,71] + },{ + "color":11, + "uvs":[0.4375,0.65625,0.5625,0.65625,0.5625,0.78125,0.4375,0.78125], + "vertex_ids":[75,71,74,76] + },{ + "color":11, + "uvs":[0.4375,0.65625,0.5625,0.65625,0.5625,0.78125,0.4375,0.78125], + "vertex_ids":[72,67,70,73] + },{ + "color":11, + "uvs":[0.53125,0.65625,0.53125,0.78125,0.40625,0.78125,0.40625,0.65625], + "vertex_ids":[74,73,70,76] + },{ + "color":11, + "uvs":[0.84375,0.46875,0.96875,0.46875,0.96875,0.59375,0.84375,0.59375], + "vertex_ids":[77,78,79,80] + },{ + "color":11, + "uvs":[0.84375,0.46875,0.96875,0.46875,0.96875,0.59375,0.84375,0.59375], + "vertex_ids":[82,81,84,83] + },{ + "color":11, + "uvs":[0.96875,0.46875,0.96875,0.59375,0.84375,0.59375,0.84375,0.46875], + "vertex_ids":[81,82,78,77] + },{ + "color":11, + "uvs":[0.84375,0.46875,0.96875,0.46875,0.96875,0.59375,0.84375,0.59375], + "vertex_ids":[81,77,80,84] + },{ + "color":11, + "uvs":[0.84375,0.46875,0.96875,0.46875,0.96875,0.59375,0.84375,0.59375], + "vertex_ids":[78,82,83,79] + },{ + "color":11, + "uvs":[0.96875,0.46875,0.96875,0.59375,0.84375,0.59375,0.84375,0.46875], + "vertex_ids":[80,79,83,84] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[85,86,87,88] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[90,89,92,91] + },{ + "color":11, + "uvs":[0.5,0,0.5,0.125,0.375,0.125,0.375,0], + "vertex_ids":[89,90,86,85] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[89,85,88,92] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[86,90,91,87] + },{ + "color":11, + "uvs":[0.5,0,0.5,0.125,0.375,0.125,0.375,0], + "vertex_ids":[88,87,91,92] + },{ + "color":10, + "uvs":[0.6875,0.59375,0.65625,0.5625,0.65625,0.5,0.6875,0.46875,0.75,0.46875,0.78125,0.5,0.78125,0.5625,0.75,0.59375], + "vertex_ids":[113,114,115,116,117,118,119,120] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.65625,0.75,0.65625,0.6875,0.6875,0.65625,0.75,0.65625,0.78125,0.6875,0.78125,0.75,0.75,0.78125], + "vertex_ids":[109,109,110,110,111,111,112,112] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[93,101,102,94] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[94,102,103,95] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[95,103,104,96] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[96,104,105,97] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[97,105,106,98] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[98,106,107,99] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[99,107,108,100] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[100,108,101,93] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[109,108,107,109] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[109,107,106,110] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[110,106,105,110] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[110,105,104,111] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[111,104,103,111] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[111,103,102,112] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[112,102,101,112] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[112,101,108,109] + },{ + "color":10, + "uvs":[0.6875,0.53125,0.75,0.53125,0.75,0.59375,0.6875,0.59375], + "vertex_ids":[113,93,94,114] + },{ + "color":10, + "uvs":[0.6875,0.5,0.75,0.5,0.75,0.5625,0.6875,0.5625], + "vertex_ids":[114,94,95,115] + },{ + "color":10, + "uvs":[0.6875,0.5,0.75,0.5,0.75,0.5625,0.6875,0.5625], + "vertex_ids":[115,95,96,116] + },{ + "color":10, + "uvs":[0.6875,0.5,0.75,0.5,0.75,0.5625,0.6875,0.5625], + "vertex_ids":[116,96,97,117] + },{ + "color":10, + "uvs":[0.6875,0.5,0.75,0.5,0.75,0.5625,0.6875,0.5625], + "vertex_ids":[117,97,98,118] + },{ + "color":10, + "uvs":[0.6875,0.5,0.75,0.5,0.75,0.5625,0.6875,0.5625], + "vertex_ids":[118,98,99,119] + },{ + "color":10, + "uvs":[0.6875,0.5,0.75,0.5,0.75,0.5625,0.6875,0.5625], + "vertex_ids":[119,99,100,120] + },{ + "color":10, + "uvs":[0.6875,0.53125,0.75,0.53125,0.75,0.59375,0.6875,0.59375], + "vertex_ids":[120,100,93,113] + }] + }, + "locked":true, + "transform":{ + "scale":{ + "x":1, + "y":1, + "z":1 + }, + "pos":{ + "x":1.25, + "y":0.25, + "z":0.25 + }, + "rot":{ + "x":-0.26179938779915, + "y":-0, + "z":0 + } + } + },{ + "ghost":false, + "open":false, + "children":[], + "visible":true, + "name":"DualiesDOS", + "motions":{ + "tracks":[[],[],[],[]] + }, + "mesh":{ + "vertices":[-0.4375,3.8835185434277,2.4977952387244,-0.625,4.0710185434277,2.4977952387244,-0.625,4.4460185434277,2.4977952387244,-0.4375,4.6335185434277,2.4977952387244,-0.062500000000001,4.6335185434277,2.4977952387244,0.125,4.4460185434277,2.4977952387244,0.125,4.0710185434277,2.4977952387244,-0.062500000000001,3.8835185434277,2.4977952387244,-0.4375,3.8835185434277,3.0602952387244,-0.625,4.0710185434277,3.0602952387244,-0.625,4.4460185434277,3.0602952387244,-0.4375,4.6335185434277,3.0602952387244,-0.062499999999999,4.6335185434277,3.0602952387244,0.125,4.4460185434277,3.0602952387244,0.125,4.0710185434277,3.0602952387244,-0.062499999999999,3.8835185434277,3.0602952387244,-0.375,3.8835185434277,1.6852952387244,-0.625,4.1335185434277,1.6852952387244,-0.625,4.3835185434277,1.6852952387244,-0.375,4.6335185434277,1.6852952387244,-0.125,4.6335185434277,1.6852952387244,0.125,4.3835185434277,1.6852952387244,0.125,4.1335185434277,1.6852952387244,-0.125,3.8835185434277,1.6852952387244,-0.5,3.6335185434277,2.8102952387244,-0.875,4.0085185434277,2.8102952387244,-0.875,4.5085185434277,2.8102952387244,-0.5,4.8835185434277,2.8102952387244,3.0531133177192e-15,4.8835185434277,2.8102952387244,0.375,4.5085185434277,2.8102952387244,0.375,4.0085185434277,2.8102952387244,3.0531133177192e-15,3.6335185434277,2.8102952387244,-0.07224410137778,3.5319560434277,1.4352952387244,-0.07224410137778,2.7819560434277,1.1852952387244,-0.4296875,2.7819560434277,1.1852952387244,-0.4296875,3.5319560434277,1.4352952387244,-0.07224410137778,3.5319560434277,1.9352952387244,-0.07224410137778,2.7819560434277,1.6852952387244,-0.4296875,2.7819560434277,1.6852952387244,-0.4296875,3.5319560434277,1.9352952387244,-0.07224410137778,4.2819560434277,1.9352952387244,-0.07224410137778,4.0319560434277,0.93529523872437,-0.4296875,4.0319560434277,0.93529523872437,-0.4296875,4.2819560434277,1.9352952387244,0,4.0085185434277,-0.31470476127563,0,3.5085185434277,-0.31470476127563,-0.5,3.5085185434277,-0.31470476127563,-0.5,4.0085185434277,-0.31470476127563,0,3.7585185434277,0.93529523872437,0,3.5085185434277,0.68529523872437,-0.5,3.5085185434277,0.68529523872437,-0.5,3.7585185434277,0.93529523872437,0,3.7585185434277,-0.81470476127563,-0.5,3.7585185434277,-0.81470476127563,0,4.5085185434277,0.68529523872437,0,4.2585185434277,-0.06470476127563,-0.5,4.2585185434277,-0.06470476127563,-0.5,4.5085185434277,0.68529523872437,-0.5,4.5085185434277,1.6852952387244,-0.5,4.0085185434277,1.6852952387244,0,4.0085185434277,1.6852952387244,0,4.5085185434277,1.6852952387244,-0.125,2.776891708685,1.5648323841581,-0.125,2.901891708685,1.348326033212,-0.375,2.901891708685,1.348326033212,-0.375,2.776891708685,1.5648323841581,-0.125,2.1273726558467,1.1898323841581,-0.125,2.2523726558467,0.97332603321197,-0.375,2.2523726558467,0.97332603321197,-0.375,2.1273726558467,1.1898323841581,-0.125,2.3757060434277,0.44310773872437,-0.125,2.1257060434277,0.44310773872437,-0.375,2.1257060434277,0.44310773872437,-0.375,2.3757060434277,0.44310773872437,-0.125,2.3757060434277,1.1931077387244,-0.375,2.3757060434277,1.1931077387244,-0.1171875,3.7741435434277,-0.06470476127563,-0.1171875,2.2741435434277,-0.56470476127563,-0.3671875,2.2741435434277,-0.56470476127563,-0.3671875,3.7741435434277,-0.06470476127563,-0.1171875,3.7741435434277,0.56182586186689,-0.1171875,2.2741435434277,0.18529523872437,-0.3671875,2.2741435434277,0.18529523872437,-0.3671875,3.7741435434277,0.56182586186689,-0.25,2.612071934021,-0.81470476127563,0.10355339059327,2.2585185434277,-0.81470476127563,-0.25,1.9049651528345,-0.81470476127563,-0.60355339059327,2.2585185434277,-0.81470476127563,-0.25,2.612071934021,0.43529523872437,0.10355339059327,2.2585185434277,0.43529523872437,-0.25,1.9049651528345,0.43529523872437,-0.60355339059327,2.2585185434277,0.43529523872437,-0.096016886276438,1.7211274375393,-1.5647047612756,-0.44924817255421,1.7362157904828,-1.5647047612756,-0.78739110588844,2.1045354297042,-1.5647047612756,-0.77230275294489,2.4577667159819,-1.5647047612756,-0.40398311372356,2.7959096493162,-1.5647047612756,-0.050751827445789,2.7808212963726,-1.5647047612756,0.28739110588844,2.4125016571513,-1.5647047612756,0.27230275294489,2.0592703708735,-1.5647047612756,-0.096016886276437,1.7211274375393,-0.81470476127563,-0.44924817255421,1.7362157904828,-0.81470476127563,-0.78739110588844,2.1045354297042,-0.81470476127563,-0.77230275294489,2.4577667159819,-0.81470476127563,-0.40398311372356,2.7959096493162,-0.81470476127563,-0.050751827445788,2.7808212963726,-0.81470476127563,0.28739110588844,2.4125016571513,-0.81470476127563,0.27230275294489,2.0592703708735,-0.81470476127563,0.030074691562397,2.2465550906957,-0.56470476127563,-0.238036547268,2.5385932349901,-0.56470476127563,-0.5300746915624,2.2704819961597,-0.56470476127563,-0.261963452732,1.9784438518653,-0.56470476127563,-0.096016886276438,1.7211274375393,-1.8147047612756,-0.44924817255421,1.7362157904828,-1.8147047612756,-0.78739110588844,2.1045354297042,-1.8147047612756,-0.77230275294489,2.4577667159819,-1.8147047612756,-0.40398311372356,2.7959096493162,-1.8147047612756,-0.050751827445789,2.7808212963726,-1.8147047612756,0.28739110588844,2.4125016571513,-1.8147047612756,0.27230275294489,2.0592703708735,-1.8147047612756], + "name":"DualiesDOS", + "faces":[{ + "color":10, + "uvs":[0.875,0.78125,0.84375,0.75,0.84375,0.6875,0.875,0.65625,0.9375,0.65625,0.96875,0.6875,0.96875,0.75,0.9375,0.78125], + "vertex_ids":[1,2,3,4,5,6,7,8] + },{ + "color":10, + "uvs":[0.875,0.78125,0.84375,0.75,0.84375,0.6875,0.875,0.65625,0.9375,0.65625,0.96875,0.6875,0.96875,0.75,0.9375,0.78125], + "vertex_ids":[16,15,14,13,12,11,10,9] + },{ + "color":10, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[1,9,10,2] + },{ + "color":10, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[2,10,11,3] + },{ + "color":10, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[3,11,12,4] + },{ + "color":10, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[4,12,13,5] + },{ + "color":10, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[5,13,14,6] + },{ + "color":10, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[6,14,15,7] + },{ + "color":10, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[7,15,16,8] + },{ + "color":10, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[8,16,9,1] + },{ + "color":10, + "uvs":[0.875,0.59375,0.84375,0.5625,0.84375,0.5,0.875,0.46875,0.9375,0.46875,0.96875,0.5,0.96875,0.5625,0.9375,0.59375], + "vertex_ids":[17,18,19,20,21,22,23,24] + },{ + "color":10, + "uvs":[0.875,0.59375,0.84375,0.5625,0.84375,0.5,0.875,0.46875,0.9375,0.46875,0.96875,0.5,0.96875,0.5625,0.9375,0.59375], + "vertex_ids":[32,31,30,29,28,27,26,25] + },{ + "color":10, + "uvs":[0.96875,0.46875,0.96875,0.59375,0.84375,0.59375,0.84375,0.46875], + "vertex_ids":[17,25,26,18] + },{ + "color":10, + "uvs":[0.96875,0.46875,0.96875,0.59375,0.84375,0.59375,0.84375,0.46875], + "vertex_ids":[18,26,27,19] + },{ + "color":10, + "uvs":[0.96875,0.46875,0.96875,0.59375,0.84375,0.59375,0.84375,0.46875], + "vertex_ids":[19,27,28,20] + },{ + "color":10, + "uvs":[0.96875,0.46875,0.96875,0.59375,0.84375,0.59375,0.84375,0.46875], + "vertex_ids":[20,28,29,21] + },{ + "color":10, + "uvs":[0.96875,0.46875,0.96875,0.59375,0.84375,0.59375,0.84375,0.46875], + "vertex_ids":[21,29,30,22] + },{ + "color":10, + "uvs":[0.96875,0.46875,0.96875,0.59375,0.84375,0.59375,0.84375,0.46875], + "vertex_ids":[22,30,31,23] + },{ + "color":10, + "uvs":[0.96875,0.46875,0.96875,0.59375,0.84375,0.59375,0.84375,0.46875], + "vertex_ids":[23,31,32,24] + },{ + "color":10, + "uvs":[0.96875,0.46875,0.96875,0.59375,0.84375,0.59375,0.84375,0.46875], + "vertex_ids":[24,32,25,17] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[33,34,35,36] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[38,37,40,39] + },{ + "color":11, + "uvs":[0.5,0,0.5,0.125,0.375,0.125,0.375,0], + "vertex_ids":[37,38,34,33] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[41,42,43,44] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[34,38,39,35] + },{ + "color":11, + "uvs":[0.5,0,0.5,0.125,0.375,0.125,0.375,0], + "vertex_ids":[36,35,39,40] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[41,37,33,42] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[42,33,36,43] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[43,36,40,44] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[44,40,37,41] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[53,53,54,54] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[50,49,52,51] + },{ + "color":11, + "uvs":[0.5,0,0.5,0.125,0.375,0.125,0.375,0], + "vertex_ids":[49,50,46,45] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[55,56,57,58] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[46,50,51,47] + },{ + "color":11, + "uvs":[0.5,0,0.5,0.125,0.375,0.125,0.375,0], + "vertex_ids":[48,47,51,52] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[53,45,46,53] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[53,46,47,54] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[54,47,48,54] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[54,48,45,53] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[55,49,45,56] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[56,45,48,57] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[57,48,52,58] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[59,60,61,62] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[59,58,52,60] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[60,52,49,61] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[61,49,55,62] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[62,55,58,59] + },{ + "color":11, + "uvs":[0.40625,0.65625,0.53125,0.65625,0.53125,0.78125,0.40625,0.78125], + "vertex_ids":[63,64,65,66] + },{ + "color":11, + "uvs":[0.4375,0.65625,0.5625,0.65625,0.5625,0.78125,0.4375,0.78125], + "vertex_ids":[68,67,70,69] + },{ + "color":11, + "uvs":[0.53125,0.65625,0.53125,0.78125,0.40625,0.78125,0.40625,0.65625], + "vertex_ids":[67,68,64,63] + },{ + "color":11, + "uvs":[0.4375,0.65625,0.5625,0.65625,0.5625,0.78125,0.4375,0.78125], + "vertex_ids":[67,63,66,70] + },{ + "color":11, + "uvs":[0.4375,0.65625,0.5625,0.65625,0.5625,0.78125,0.4375,0.78125], + "vertex_ids":[64,68,69,65] + },{ + "color":11, + "uvs":[0.53125,0.65625,0.53125,0.78125,0.40625,0.78125,0.40625,0.65625], + "vertex_ids":[66,65,69,70] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[71,72,73,74] + },{ + "color":11, + "uvs":[0.4375,0.65625,0.5625,0.65625,0.5625,0.78125,0.4375,0.78125], + "vertex_ids":[67,75,76,70] + },{ + "color":11, + "uvs":[0.53125,0.65625,0.53125,0.78125,0.40625,0.78125,0.40625,0.65625], + "vertex_ids":[75,67,72,71] + },{ + "color":11, + "uvs":[0.4375,0.65625,0.5625,0.65625,0.5625,0.78125,0.4375,0.78125], + "vertex_ids":[75,71,74,76] + },{ + "color":11, + "uvs":[0.4375,0.65625,0.5625,0.65625,0.5625,0.78125,0.4375,0.78125], + "vertex_ids":[72,67,70,73] + },{ + "color":11, + "uvs":[0.53125,0.65625,0.53125,0.78125,0.40625,0.78125,0.40625,0.65625], + "vertex_ids":[74,73,70,76] + },{ + "color":11, + "uvs":[0.84375,0.46875,0.96875,0.46875,0.96875,0.59375,0.84375,0.59375], + "vertex_ids":[77,78,79,80] + },{ + "color":11, + "uvs":[0.84375,0.46875,0.96875,0.46875,0.96875,0.59375,0.84375,0.59375], + "vertex_ids":[82,81,84,83] + },{ + "color":11, + "uvs":[0.96875,0.46875,0.96875,0.59375,0.84375,0.59375,0.84375,0.46875], + "vertex_ids":[81,82,78,77] + },{ + "color":11, + "uvs":[0.84375,0.46875,0.96875,0.46875,0.96875,0.59375,0.84375,0.59375], + "vertex_ids":[81,77,80,84] + },{ + "color":11, + "uvs":[0.84375,0.46875,0.96875,0.46875,0.96875,0.59375,0.84375,0.59375], + "vertex_ids":[78,82,83,79] + },{ + "color":11, + "uvs":[0.96875,0.46875,0.96875,0.59375,0.84375,0.59375,0.84375,0.46875], + "vertex_ids":[80,79,83,84] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[85,86,87,88] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[90,89,92,91] + },{ + "color":11, + "uvs":[0.5,0,0.5,0.125,0.375,0.125,0.375,0], + "vertex_ids":[89,90,86,85] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[89,85,88,92] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[86,90,91,87] + },{ + "color":11, + "uvs":[0.5,0,0.5,0.125,0.375,0.125,0.375,0], + "vertex_ids":[88,87,91,92] + },{ + "color":10, + "uvs":[0.6875,0.59375,0.65625,0.5625,0.65625,0.5,0.6875,0.46875,0.75,0.46875,0.78125,0.5,0.78125,0.5625,0.75,0.59375], + "vertex_ids":[113,114,115,116,117,118,119,120] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.65625,0.75,0.65625,0.6875,0.6875,0.65625,0.75,0.65625,0.78125,0.6875,0.78125,0.75,0.75,0.78125], + "vertex_ids":[109,109,110,110,111,111,112,112] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[93,101,102,94] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[94,102,103,95] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[95,103,104,96] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[96,104,105,97] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[97,105,106,98] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[98,106,107,99] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[99,107,108,100] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[100,108,101,93] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[109,108,107,109] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[109,107,106,110] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[110,106,105,110] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[110,105,104,111] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[111,104,103,111] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[111,103,102,112] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[112,102,101,112] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[112,101,108,109] + },{ + "color":10, + "uvs":[0.6875,0.53125,0.75,0.53125,0.75,0.59375,0.6875,0.59375], + "vertex_ids":[113,93,94,114] + },{ + "color":10, + "uvs":[0.6875,0.5,0.75,0.5,0.75,0.5625,0.6875,0.5625], + "vertex_ids":[114,94,95,115] + },{ + "color":10, + "uvs":[0.6875,0.5,0.75,0.5,0.75,0.5625,0.6875,0.5625], + "vertex_ids":[115,95,96,116] + },{ + "color":10, + "uvs":[0.6875,0.5,0.75,0.5,0.75,0.5625,0.6875,0.5625], + "vertex_ids":[116,96,97,117] + },{ + "color":10, + "uvs":[0.6875,0.5,0.75,0.5,0.75,0.5625,0.6875,0.5625], + "vertex_ids":[117,97,98,118] + },{ + "color":10, + "uvs":[0.6875,0.5,0.75,0.5,0.75,0.5625,0.6875,0.5625], + "vertex_ids":[118,98,99,119] + },{ + "color":10, + "uvs":[0.6875,0.5,0.75,0.5,0.75,0.5625,0.6875,0.5625], + "vertex_ids":[119,99,100,120] + },{ + "color":10, + "uvs":[0.6875,0.53125,0.75,0.53125,0.75,0.59375,0.6875,0.59375], + "vertex_ids":[120,100,93,113] + }] + }, + "locked":true, + "transform":{ + "scale":{ + "x":1, + "y":1, + "z":1 + }, + "pos":{ + "x":-0.75, + "y":1, + "z":0.25 + }, + "rot":{ + "x":-0.26179938779915, + "y":-0, + "z":0 + } + } + },{ + "ghost":false, + "open":true, + "children":[], + "visible":true, + "name":"rod.1", + "motions":{ + "tracks":[[],[],[],[]] + }, + "mesh":{ + "vertices":[0.125,3.75,-0.125,0.125,0.5,-0.125,-0.125,0.5,-0.125,-0.125,3.75,-0.125,0.125,3.75,0.125,0.125,0.5,0.125,-0.125,0.5,0.125,-0.125,3.75,0.125], + "name":"UNOrod1", + "faces":[{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[1,2,3,4] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[6,5,8,7] + },{ + "color":11, + "uvs":[0.53125,0.65625,0.53125,0.78125,0.40625,0.78125,0.40625,0.65625], + "vertex_ids":[5,6,2,1] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[5,1,4,8] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[2,6,7,3] + },{ + "color":11, + "uvs":[0.5,0.65625,0.5,0.78125,0.375,0.78125,0.375,0.65625], + "vertex_ids":[4,3,7,8] + }] + }, + "locked":true, + "transform":{ + "scale":{ + "x":1, + "y":1, + "z":1 + }, + "pos":{ + "x":1, + "y":-1.75, + "z":-1.5 + }, + "rot":{ + "x":0, + "y":-0, + "z":0 + } + } + },{ + "ghost":false, + "open":false, + "children":[], + "visible":true, + "name":"rod.2", + "motions":{ + "tracks":[[],[],[],[]] + }, + "mesh":{ + "vertices":[0.125,1.75,0.125,0.125,-3.25,0.125,-0.125,-3.25,0.125,-0.125,1.75,0.125,0.125,1.75,0.375,0.125,-3.25,0.375,-0.125,-3.25,0.375,-0.125,1.75,0.375], + "name":"UNOrod2", + "faces":[{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[1,2,3,4] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[6,5,8,7] + },{ + "color":11, + "uvs":[0.53125,0.65625,0.53125,0.78125,0.40625,0.78125,0.40625,0.65625], + "vertex_ids":[5,6,2,1] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[5,1,4,8] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[2,6,7,3] + },{ + "color":11, + "uvs":[0.5,0.65625,0.5,0.78125,0.375,0.78125,0.375,0.65625], + "vertex_ids":[4,3,7,8] + }] + }, + "locked":true, + "transform":{ + "scale":{ + "x":1, + "y":1, + "z":1 + }, + "pos":{ + "x":1, + "y":3.3046875, + "z":1.171875 + }, + "rot":{ + "x":0, + "y":-0, + "z":0 + } + } + },{ + "ghost":false, + "open":true, + "children":[], + "visible":true, + "name":"rod.3", + "motions":{ + "tracks":[[],[],[],[]] + }, + "mesh":{ + "vertices":[0.125,3.5,-0.125,0.125,0.25,-0.125,-0.125,0.25,-0.125,-0.125,3.5,-0.125,0.125,3.5,0.125,0.125,0.25,0.125,-0.125,0.25,0.125,-0.125,3.5,0.125], + "name":"DOSrod1", + "faces":[{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[1,2,3,4] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[6,5,8,7] + },{ + "color":11, + "uvs":[0.53125,0.65625,0.53125,0.78125,0.40625,0.78125,0.40625,0.65625], + "vertex_ids":[5,6,2,1] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[5,1,4,8] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[2,6,7,3] + },{ + "color":11, + "uvs":[0.5,0.65625,0.5,0.78125,0.375,0.78125,0.375,0.65625], + "vertex_ids":[4,3,7,8] + }] + }, + "locked":true, + "transform":{ + "scale":{ + "x":1, + "y":1, + "z":1 + }, + "pos":{ + "x":-1, + "y":-0.5, + "z":-1.5 + }, + "rot":{ + "x":0, + "y":-0, + "z":0 + } + } + },{ + "ghost":false, + "open":false, + "children":[], + "visible":true, + "name":"rod.4", + "motions":{ + "tracks":[[],[],[],[]] + }, + "mesh":{ + "vertices":[0.125,1.5,0.125,0.125,-3.5,0.125,-0.125,-3.5,0.125,-0.125,1.5,0.125,0.125,1.5,0.375,0.125,-3.5,0.375,-0.125,-3.5,0.375,-0.125,1.5,0.375], + "name":"DOSrod2", + "faces":[{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[1,2,3,4] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[6,5,8,7] + },{ + "color":11, + "uvs":[0.53125,0.65625,0.53125,0.78125,0.40625,0.78125,0.40625,0.65625], + "vertex_ids":[5,6,2,1] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[5,1,4,8] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[2,6,7,3] + },{ + "color":11, + "uvs":[0.5,0.65625,0.5,0.78125,0.375,0.78125,0.375,0.65625], + "vertex_ids":[4,3,7,8] + }] + }, + "locked":true, + "transform":{ + "scale":{ + "x":1, + "y":1, + "z":1 + }, + "pos":{ + "x":-1, + "y":4.25, + "z":1.171875 + }, + "rot":{ + "x":0, + "y":-0, + "z":0 + } + } + }], + "visible":true, + "name":"dualies", + "motions":{ + "tracks":[[],[],[],[]] + }, + "folder":true, + "locked":true, + "transform":{ + "scale":{ + "x":1, + "y":1, + "z":1 + }, + "pos":{ + "x":0, + "y":0, + "z":0 + }, + "rot":{ + "x":0, + "y":0, + "z":0 + } + } + },{ + "ghost":false, + "open":false, + "children":[{ + "ghost":false, + "open":false, + "children":[], + "visible":true, + "name":"HEAVY", + "motions":{ + "tracks":[[],[],[],[]] + }, + "mesh":{ + "vertices":[-1.59375,3.6875,-1.701171875,-1.40625,3.6875,-1.701171875,-1.40625,3.5,-1.701171875,-1.59375,3.5,-1.701171875,-1.59375,3.6875,-1.513671875,-1.40625,3.6875,-1.513671875,-1.40625,3.5,-1.513671875,-1.59375,3.5,-1.513671875,-1.59375,3.817182447608,-1.454152507362,-1.40625,3.817182447608,-1.454152507362,-1.40625,3.817182447608,-1.641652507362,-1.59375,3.817182447608,-1.641652507362,-1.59375,4.004682447608,-1.454152507362,-1.40625,4.004682447608,-1.454152507362,-1.59375,4.064201815246,-1.324470059754,-1.59375,3.876701815246,-1.324470059754,-1.40625,3.876701815246,-1.324470059754,-1.40625,4.064201815246,-1.324470059754,-1.59375,4.064201815246,-0.82499397418682,-1.59375,3.876701815246,-0.82499397418682,-1.40625,3.876701815246,-0.82499397418682,-1.40625,4.064201815246,-0.82499397418682,-1.40625,3.5602563509461,-1.2220752018922,-0.40625,3.5602563509461,-1.2220752018922,-0.40625,3.1272436490539,-1.4720752018922,-1.40625,3.1272436490539,-1.4720752018922,-1.40625,3.0602563509461,-0.35604979810778,-0.40625,3.0602563509461,-0.35604979810778,-0.40625,2.6272436490539,-0.60604979810778,-1.40625,2.6272436490539,-0.60604979810778,-1,3.125,-1.9051499462909,-1.25,2.875,-1.9051499462909,-1.75,2.875,-1.9051499462909,-2,3.125,-1.9051499462909,-2,3.375,-1.9051499462909,-1.75,3.625,-1.9051499462909,-1.25,3.625,-1.9051499462909,-1,3.375,-1.9051499462909,-1,3.125,-0.5,-1.25,2.875,-0.5,-1.75,2.875,-0.5,-2,3.125,-0.5,-2,3.375,-0.5,-1.75,3.625,-0.5,-1.25,3.625,-0.5,-1,3.375,-0.5,-1.3535533905933,3.25,3,-1.1767766952966,3.4267766952966,3,-1,3.25,3,-1.1767766952966,3.0732233047034,3,-1.3535533905933,3.25,3.25,-1.1767766952966,3.4267766952966,3.25,-1,3.25,3.25,-1.1767766952966,3.0732233047034,3.25,-1.5,3.3964466094067,3,-1.6767766952966,3.5732233047034,3,-1.5,3.75,3,-1.3232233047034,3.5732233047034,3,-1.5,3.3964466094067,3.25,-1.6767766952966,3.5732233047034,3.25,-1.5,3.75,3.25,-1.3232233047034,3.5732233047034,3.25,-1.6464466094067,3.25,3,-1.8232233047034,3.0732233047034,3,-2,3.25,3,-1.8232233047034,3.4267766952966,3,-1.6464466094067,3.25,3.25,-1.8232233047034,3.0732233047034,3.25,-2,3.25,3.25,-1.8232233047034,3.4267766952966,3.25,-2,4.2578125,0.425,-2,4.3578125,0.525,-2,4.4578125,0.525,-2,4.5578125,0.425,-2,4.5578125,0.325,-2,4.4578125,0.225,-2,4.3578125,0.225,-2,4.2578125,0.325,-1,4.2578125,0.425,-1,4.3578125,0.525,-1,4.4578125,0.525,-1,4.5578125,0.425,-1,4.5578125,0.325,-1,4.4578125,0.225,-1,4.3578125,0.225,-1,4.2578125,0.325,-1,4,0,-1,3.75,-0.25,-1.25,3.75,-0.25,-1.25,4,0,-1,4,0.25,-1,3.75,0.5,-1.25,3.75,0.5,-1.25,4,0.25,-1,4.4296875,0.515625,-1,4.4296875,0.265625,-1.25,4.4296875,0.265625,-1.25,4.4296875,0.515625,-1,3.25,-0.25,-1,3.25,0.5,-1.25,3.25,0.5,-1.25,3.25,-0.25,-1.5,3.1035533905933,3,-1.3232233047034,2.9267766952966,3,-1.5,2.75,3,-1.6767766952966,2.9267766952966,3,-1.5,3.1035533905933,3.25,-1.3232233047034,2.9267766952966,3.25,-1.5,2.75,3.25,-1.6767766952966,2.9267766952966,3.25,-1.75,4,0,-1.75,3.75,-0.25,-2,3.75,-0.25,-2,4,0,-1.75,4,0.25,-1.75,3.75,0.5,-2,3.75,0.5,-2,4,0.25,-1.75,4.4296875,0.515625,-1.75,4.4296875,0.265625,-2,4.4296875,0.265625,-2,4.4296875,0.515625,-1.75,3.25,-0.25,-1.75,3.25,0.5,-2,3.25,0.5,-2,3.25,-0.25,-1.8125,2.6328125,2.7578125,-2.125,2.9453125,2.7578125,-2.125,3.5703125,2.7578125,-1.8125,3.8828125,2.7578125,-1.1875,3.8828125,2.7578125,-0.875,3.5703125,2.7578125,-0.875,2.9453125,2.7578125,-1.1875,2.6328125,2.7578125,-1.8125,2.6328125,3.0078125,-2.125,2.9453125,3.0078125,-2.125,3.5703125,3.0078125,-1.8125,3.8828125,3.0078125,-1.1875,3.8828125,3.0078125,-0.875,3.5703125,3.0078125,-0.875,2.9453125,3.0078125,-1.1875,2.6328125,3.0078125,-1.8125,2.625,1.625,-2.125,2.9375,1.625,-2.125,3.5625,1.625,-1.8125,3.875,1.625,-1.1875,3.875,1.625,-0.875,3.5625,1.625,-0.875,2.9375,1.625,-1.1875,2.625,1.625,-1.8125,2.625,1.875,-2.125,2.9375,1.875,-2.125,3.5625,1.875,-1.8125,3.875,1.875,-1.1875,3.875,1.875,-0.875,3.5625,1.875,-0.875,2.9375,1.875,-1.1875,2.625,1.875,-1.8125,2.625,-0.625,-2.125,2.9375,-0.625,-2.125,3.5625,-0.625,-1.8125,3.875,-0.625,-1.1875,3.875,-0.625,-0.875,3.5625,-0.625,-0.875,2.9375,-0.625,-1.1875,2.625,-0.625,-1.8125,2.625,0.875,-2.125,2.9375,0.875,-2.125,3.5625,0.875,-1.8125,3.875,0.875,-1.1875,3.875,0.875,-0.875,3.5625,0.875,-0.875,2.9375,0.875,-1.1875,2.625,0.875,-1.75,2.75,0.75,-2,3,0.75,-2,3.5,0.75,-1.75,3.75,0.75,-1.25,3.75,0.75,-1,3.5,0.75,-1,3,0.75,-1.25,2.75,0.75,-1.75,2.75,2.75,-2,3,2.75,-2,3.5,2.75,-1.75,3.75,2.75,-1.25,3.75,2.75,-1,3.5,2.75,-1,3,2.75,-1.25,2.75,2.75,-0.375,2.7986712000404,-1.3321378856587,-0.875,3.2316839019326,-1.0821378856587,-0.875,3.8812029547709,-0.70713788565866,-0.375,4.3142156566632,-0.45713788565866,0.375,4.3142156566632,-0.45713788565866,0.875,3.8812029547709,-0.70713788565866,0.875,3.2316839019326,-1.0821378856587,0.375,2.7986712000404,-1.3321378856587,-0.375,3.1254120987934,-1.8980697232095,-0.875,3.5584248006856,-1.6480697232095,-0.875,4.2079438535239,-1.2730697232095,-0.375,4.6409565554161,-1.0230697232095,0.375,4.6409565554161,-1.0230697232095,0.875,4.2079438535239,-1.2730697232095,0.875,3.5584248006856,-1.6480697232095,0.375,3.1254120987934,-1.8980697232095,0.125,3.4669184497395,-1.9895760741557,0.625,3.8999311516317,-1.7395760741557,0.625,4.1164375025778,-1.6145760741557,0.125,4.54945020447,-1.3645760741557,-0.125,4.54945020447,-1.3645760741557,-0.625,4.1164375025778,-1.6145760741557,-0.625,3.8999311516317,-1.7395760741557,-0.125,3.4669184497395,-1.9895760741557,-0.375,2.4719303012874,-0.76620604810778,-0.875,2.9049430031796,-0.51620604810778,-0.875,3.554462056018,-0.14120604810778,-0.375,3.9874747579102,0.10879395189222,0.375,3.9874747579102,0.10879395189222,0.875,3.554462056018,-0.14120604810778,0.875,2.9049430031796,-0.51620604810778,0.375,2.4719303012874,-0.76620604810778,-0.375,2.1451894025344,-0.2002742105569,-0.875,2.5782021044267,0.049725789443101,-0.875,3.227721157265,0.4247257894431,-0.375,3.6607338591572,0.6747257894431,0.375,3.6607338591572,0.6747257894431,0.875,3.227721157265,0.4247257894431,0.875,2.5782021044267,0.049725789443101,0.375,2.1451894025344,-0.2002742105569,0.125,2.2366957534805,0.14123214038921,0.625,2.6697084553728,0.39123214038921,0.625,2.8862148063189,0.51623214038921,0.125,3.3192275082111,0.76623214038921,-0.125,3.3192275082111,0.76623214038921,-0.625,2.8862148063189,0.51623214038921,-0.625,2.6697084553728,0.39123214038921,-0.125,2.2366957534805,0.14123214038921,-0.375,2.8757553231178,-1.2876333464497,-0.78599092158203,3.2316839019326,-1.0821378856587,-0.78599092158203,3.8812029547709,-0.70713788565866,-0.375,4.2371315335858,-0.50164242486765,0.375,4.2371315335858,-0.50164242486765,0.78599092158203,3.8812029547709,-0.70713788565866,0.78599092158203,3.2316839019326,-1.0821378856587,0.375,2.8757553231178,-1.2876333464497,-0.375,2.5490144243648,-0.7217015088988,-0.78599092158203,2.9049430031796,-0.51620604810778,-0.78599092158203,3.554462056018,-0.14120604810778,-0.375,3.9103906348328,0.064289412683235,0.375,3.9103906348328,0.064289412683235,0.78599092158203,3.554462056018,-0.14120604810778,0.78599092158203,2.9049430031796,-0.51620604810778,0.375,2.5490144243648,-0.7217015088988], + "name":"HEAVY", + "faces":[{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[1,2,3,4] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[6,5,8,7] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[13,14,14,13] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[5,1,4,8] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[2,6,7,3] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[4,3,7,8] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[9,5,6,10] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[10,6,2,11] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[11,2,1,12] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[12,1,5,9] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[19,20,21,22] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[14,10,11,14] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[14,11,12,13] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[13,12,9,13] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[15,13,9,16] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[16,9,10,17] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[17,10,14,18] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[18,14,13,15] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[19,15,16,20] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[20,16,17,21] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[21,17,18,22] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[22,18,15,19] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[23,24,25,26] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[28,27,30,29] + },{ + "color":11, + "uvs":[0.5,0,0.5,0.125,0.375,0.125,0.375,0], + "vertex_ids":[27,28,24,23] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[27,23,26,30] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[24,28,29,25] + },{ + "color":11, + "uvs":[0.5,0,0.5,0.125,0.375,0.125,0.375,0], + "vertex_ids":[26,25,29,30] + },{ + "color":10, + "uvs":[0.78125,0.125,0.75,0.09375,0.75,0.03125,0.78125,0,0.84375,0,0.875,0.03125,0.875,0.09375,0.84375,0.125], + "vertex_ids":[31,32,33,34,35,36,37,38] + },{ + "color":10, + "uvs":[0.78125,0.125,0.75,0.09375,0.75,0.03125,0.78125,0,0.84375,0,0.875,0.03125,0.875,0.09375,0.84375,0.125], + "vertex_ids":[46,45,44,43,42,41,40,39] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[31,39,40,32] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[32,40,41,33] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[33,41,42,34] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[34,42,43,35] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[35,43,44,36] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[36,44,45,37] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[37,45,46,38] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[38,46,39,31] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[47,48,49,50] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[52,51,54,53] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[51,52,48,47] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[51,47,50,54] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[48,52,53,49] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[50,49,53,54] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[55,56,57,58] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[60,59,62,61] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[59,60,56,55] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[59,55,58,62] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[56,60,61,57] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[58,57,61,62] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[63,64,65,66] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[68,67,70,69] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[67,68,64,63] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[67,63,66,70] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[64,68,69,65] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[66,65,69,70] + },{ + "color":10, + "uvs":[0.875,0.78125,0.84375,0.75,0.84375,0.6875,0.875,0.65625,0.9375,0.65625,0.96875,0.6875,0.96875,0.75,0.9375,0.78125], + "vertex_ids":[71,72,73,74,75,76,77,78] + },{ + "color":10, + "uvs":[0.875,0.78125,0.84375,0.75,0.84375,0.6875,0.875,0.65625,0.9375,0.65625,0.96875,0.6875,0.96875,0.75,0.9375,0.78125], + "vertex_ids":[86,85,84,83,82,81,80,79] + },{ + "color":10, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[71,79,80,72] + },{ + "color":10, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[72,80,81,73] + },{ + "color":10, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[73,81,82,74] + },{ + "color":10, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[74,82,83,75] + },{ + "color":10, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[75,83,84,76] + },{ + "color":10, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[76,84,85,77] + },{ + "color":10, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[77,85,86,78] + },{ + "color":10, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[78,86,79,71] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[87,88,89,90] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[92,91,94,93] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[91,92,88,87] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[95,96,97,98] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[99,100,101,102] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[90,89,93,94] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[95,91,87,96] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[96,87,90,97] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[97,90,94,98] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[98,94,91,95] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[99,88,92,100] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[100,92,93,101] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[101,93,89,102] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[102,89,88,99] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[103,104,105,106] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[108,107,110,109] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[107,108,104,103] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[107,103,106,110] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[104,108,109,105] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[106,105,109,110] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[111,112,113,114] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[116,115,118,117] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[115,116,112,111] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[119,120,121,122] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[123,124,125,126] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[114,113,117,118] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[119,115,111,120] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[120,111,114,121] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[121,114,118,122] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[122,118,115,119] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[123,112,116,124] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[124,116,117,125] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[125,117,113,126] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[126,113,112,123] + },{ + "color":10, + "uvs":[0.875,0.78125,0.84375,0.75,0.84375,0.6875,0.875,0.65625,0.9375,0.65625,0.96875,0.6875,0.96875,0.75,0.9375,0.78125], + "vertex_ids":[127,128,129,130,131,132,133,134] + },{ + "color":10, + "uvs":[0.875,0.78125,0.84375,0.75,0.84375,0.6875,0.875,0.65625,0.9375,0.65625,0.96875,0.6875,0.96875,0.75,0.9375,0.78125], + "vertex_ids":[142,141,140,139,138,137,136,135] + },{ + "color":10, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[127,135,136,128] + },{ + "color":10, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[128,136,137,129] + },{ + "color":10, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[129,137,138,130] + },{ + "color":10, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[130,138,139,131] + },{ + "color":10, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[131,139,140,132] + },{ + "color":10, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[132,140,141,133] + },{ + "color":10, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[133,141,142,134] + },{ + "color":10, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[134,142,135,127] + },{ + "color":10, + "uvs":[0.875,0.78125,0.84375,0.75,0.84375,0.6875,0.875,0.65625,0.9375,0.65625,0.96875,0.6875,0.96875,0.75,0.9375,0.78125], + "vertex_ids":[143,144,145,146,147,148,149,150] + },{ + "color":10, + "uvs":[0.875,0.78125,0.84375,0.75,0.84375,0.6875,0.875,0.65625,0.9375,0.65625,0.96875,0.6875,0.96875,0.75,0.9375,0.78125], + "vertex_ids":[158,157,156,155,154,153,152,151] + },{ + "color":10, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[143,151,152,144] + },{ + "color":10, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[144,152,153,145] + },{ + "color":10, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[145,153,154,146] + },{ + "color":10, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[146,154,155,147] + },{ + "color":10, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[147,155,156,148] + },{ + "color":10, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[148,156,157,149] + },{ + "color":10, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[149,157,158,150] + },{ + "color":10, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[150,158,151,143] + },{ + "color":10, + "uvs":[0.78125,0.125,0.75,0.09375,0.75,0.03125,0.78125,0,0.84375,0,0.875,0.03125,0.875,0.09375,0.84375,0.125], + "vertex_ids":[159,160,161,162,163,164,165,166] + },{ + "color":10, + "uvs":[0.78125,0.125,0.75,0.09375,0.75,0.03125,0.78125,0,0.84375,0,0.875,0.03125,0.875,0.09375,0.84375,0.125], + "vertex_ids":[174,173,172,171,170,169,168,167] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[159,167,168,160] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[160,168,169,161] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[161,169,170,162] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[162,170,171,163] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[163,171,172,164] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[164,172,173,165] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[165,173,174,166] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[166,174,167,159] + },{ + "color":10, + "uvs":[0.78125,0.125,0.75,0.09375,0.75,0.03125,0.78125,0,0.84375,0,0.875,0.03125,0.875,0.09375,0.84375,0.125], + "vertex_ids":[175,176,177,178,179,180,181,182] + },{ + "color":10, + "uvs":[0.78125,0.125,0.75,0.09375,0.75,0.03125,0.78125,0,0.84375,0,0.875,0.03125,0.875,0.09375,0.84375,0.125], + "vertex_ids":[190,189,188,187,186,185,184,183] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[175,183,184,176] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[176,184,185,177] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[177,185,186,178] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[178,186,187,179] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[179,187,188,180] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[180,188,189,181] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[181,189,190,182] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[182,190,183,175] + },{ + "color":10, + "uvs":[0.75,0.78125,0.78125,0.75,0.78125,0.6875,0.75,0.65625,0.6875,0.65625,0.65625,0.6875,0.65625,0.75,0.6875,0.78125], + "vertex_ids":[198,197,196,195,194,193,192,191] + },{ + "color":10, + "uvs":[0.75,0.78125,0.78125,0.75,0.78125,0.6875,0.75,0.65625,0.6875,0.65625,0.65625,0.6875,0.65625,0.75,0.6875,0.78125], + "vertex_ids":[214,213,212,211,210,209,208,207] + },{ + "color":10, + "uvs":[0.65625,0.65625,0.65625,0.78125,0.78125,0.78125,0.78125,0.65625], + "vertex_ids":[192,200,199,191] + },{ + "color":10, + "uvs":[0.65625,0.65625,0.65625,0.78125,0.78125,0.78125,0.78125,0.65625], + "vertex_ids":[193,201,200,192] + },{ + "color":10, + "uvs":[0.65625,0.65625,0.65625,0.78125,0.78125,0.78125,0.78125,0.65625], + "vertex_ids":[194,202,201,193] + },{ + "color":10, + "uvs":[0.65625,0.65625,0.65625,0.78125,0.78125,0.78125,0.78125,0.65625], + "vertex_ids":[195,203,202,194] + },{ + "color":10, + "uvs":[0.65625,0.65625,0.65625,0.78125,0.78125,0.78125,0.78125,0.65625], + "vertex_ids":[196,204,203,195] + },{ + "color":10, + "uvs":[0.65625,0.65625,0.65625,0.78125,0.78125,0.78125,0.78125,0.65625], + "vertex_ids":[197,205,204,196] + },{ + "color":10, + "uvs":[0.65625,0.65625,0.65625,0.78125,0.78125,0.78125,0.78125,0.65625], + "vertex_ids":[198,206,205,197] + },{ + "color":10, + "uvs":[0.65625,0.65625,0.65625,0.78125,0.78125,0.78125,0.78125,0.65625], + "vertex_ids":[191,199,206,198] + },{ + "color":10, + "uvs":[0.6875,0.84375,0.75,0.84375,0.75,0.78125,0.6875,0.78125], + "vertex_ids":[208,205,206,207] + },{ + "color":10, + "uvs":[0.6875,0.84375,0.75,0.84375,0.75,0.78125,0.6875,0.78125], + "vertex_ids":[209,204,205,208] + },{ + "color":10, + "uvs":[0.6875,0.84375,0.75,0.84375,0.75,0.78125,0.6875,0.78125], + "vertex_ids":[210,203,204,209] + },{ + "color":10, + "uvs":[0.6875,0.84375,0.75,0.84375,0.75,0.78125,0.6875,0.78125], + "vertex_ids":[211,202,203,210] + },{ + "color":10, + "uvs":[0.6875,0.84375,0.75,0.84375,0.75,0.78125,0.6875,0.78125], + "vertex_ids":[212,201,202,211] + },{ + "color":10, + "uvs":[0.6875,0.84375,0.75,0.84375,0.75,0.78125,0.6875,0.78125], + "vertex_ids":[213,200,201,212] + },{ + "color":10, + "uvs":[0.6875,0.84375,0.75,0.84375,0.75,0.78125,0.6875,0.78125], + "vertex_ids":[214,199,200,213] + },{ + "color":10, + "uvs":[0.6875,0.84375,0.75,0.84375,0.75,0.78125,0.6875,0.78125], + "vertex_ids":[207,206,199,214] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.65625,0.75,0.65625,0.6875,0.6875,0.65625,0.75,0.65625,0.78125,0.6875,0.78125,0.75,0.75,0.78125], + "vertex_ids":[215,216,217,218,219,220,221,222] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.65625,0.75,0.65625,0.6875,0.6875,0.65625,0.75,0.65625,0.78125,0.6875,0.78125,0.75,0.75,0.78125], + "vertex_ids":[231,232,233,234,235,236,237,238] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[215,223,224,216] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[216,224,225,217] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[217,225,226,218] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[218,226,227,219] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[219,227,228,220] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[220,228,229,221] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[221,229,230,222] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[222,230,223,215] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[231,230,229,232] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[232,229,228,233] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[233,228,227,234] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[234,227,226,235] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[235,226,225,236] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[236,225,224,237] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[237,224,223,238] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[238,223,230,231] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.65625,0.75,0.65625,0.6875,0.6875,0.65625,0.75,0.65625,0.78125,0.6875,0.78125,0.75,0.75,0.78125], + "vertex_ids":[239,240,241,242,243,244,245,246] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.65625,0.75,0.65625,0.6875,0.6875,0.65625,0.75,0.65625,0.78125,0.6875,0.78125,0.75,0.75,0.78125], + "vertex_ids":[254,253,252,251,250,249,248,247] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[239,247,248,240] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[240,248,249,241] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[241,249,250,242] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[242,250,251,243] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[243,251,252,244] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[244,252,253,245] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[245,253,254,246] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[246,254,247,239] + }] + }, + "locked":true, + "transform":{ + "scale":{ + "x":1.25, + "y":1.25, + "z":1.25 + }, + "pos":{ + "x":0.9453125, + "y":-0.5078125, + "z":0.2265625 + }, + "rot":{ + "x":-0.26179938779915, + "y":-0, + "z":0 + } + } + },{ + "ghost":false, + "open":true, + "children":[], + "visible":true, + "name":"rod.1", + "motions":{ + "tracks":[[],[],[],[]] + }, + "mesh":{ + "vertices":[0.125,3.75,-0.125,0.125,-0.25,-0.125,-0.125,-0.25,-0.125,-0.125,3.75,-0.125,0.125,3.75,0.125,0.125,-0.25,0.125,-0.125,-0.25,0.125,-0.125,3.75,0.125], + "name":"cube..13", + "faces":[{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[1,2,3,4] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[6,5,8,7] + },{ + "color":11, + "uvs":[0.53125,0.65625,0.53125,0.78125,0.40625,0.78125,0.40625,0.65625], + "vertex_ids":[5,6,2,1] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[5,1,4,8] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[2,6,7,3] + },{ + "color":11, + "uvs":[0.5,0.65625,0.5,0.78125,0.375,0.78125,0.375,0.65625], + "vertex_ids":[4,3,7,8] + }] + }, + "locked":true, + "transform":{ + "scale":{ + "x":1, + "y":1, + "z":1 + }, + "pos":{ + "x":0.953125, + "y":-0.9609375, + "z":-1.828125 + }, + "rot":{ + "x":0, + "y":-0, + "z":0 + } + } + },{ + "ghost":false, + "open":false, + "children":[], + "visible":true, + "name":"rod.2", + "motions":{ + "tracks":[[],[],[],[]] + }, + "mesh":{ + "vertices":[0.125,1.75,0.125,0.125,-3.25,0.125,-0.125,-3.25,0.125,-0.125,1.75,0.125,0.125,1.75,0.375,0.125,-3.25,0.375,-0.125,-3.25,0.375,-0.125,1.75,0.375], + "name":"cube..14", + "faces":[{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[1,2,3,4] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[6,5,8,7] + },{ + "color":11, + "uvs":[0.53125,0.65625,0.53125,0.78125,0.40625,0.78125,0.40625,0.65625], + "vertex_ids":[5,6,2,1] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[5,1,4,8] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[2,6,7,3] + },{ + "color":11, + "uvs":[0.5,0.65625,0.5,0.78125,0.375,0.78125,0.375,0.65625], + "vertex_ids":[4,3,7,8] + }] + }, + "locked":true, + "transform":{ + "scale":{ + "x":1, + "y":1, + "z":1 + }, + "pos":{ + "x":-0.9375, + "y":1.9140625, + "z":1.7890625 + }, + "rot":{ + "x":0, + "y":-0, + "z":0 + } + } + }], + "visible":true, + "name":"splatlings", + "motions":{ + "tracks":[[],[],[],[]] + }, + "folder":true, + "locked":true, + "transform":{ + "scale":{ + "x":1, + "y":1, + "z":1 + }, + "pos":{ + "x":0, + "y":0, + "z":0 + }, + "rot":{ + "x":0, + "y":0, + "z":0 + } + } + },{ + "ghost":false, + "open":false, + "children":[{ + "ghost":false, + "open":false, + "children":[], + "visible":true, + "name":"sword", + "motions":{ + "tracks":[[],[],[],[]] + }, + "mesh":{ + "vertices":[0.1015625,-0.25623044243112,-0.95331017229342,0.1015625,-1.98828125,-1.9533101722934,-0.1484375,-1.98828125,-1.9533101722934,-0.1484375,-0.25623044243112,-0.95331017229342,0.1015625,-0.38123044243112,-0.73680382134731,0.1015625,-2.11328125,-1.7368038213473,-0.1484375,-2.11328125,-1.7368038213473,-0.1484375,-0.38123044243112,-0.73680382134731,0.263671875,-1.8298778508234,-1.837047907759,0.076171875,-1.7361278508234,-1.9994276709686,-0.111328125,-1.7361278508234,-1.9994276709686,-0.298828125,-1.8298778508234,-1.837047907759,-0.298828125,-1.9236278508234,-1.6746681445494,-0.111328125,-2.0173778508234,-1.5122883813398,0.076171875,-2.0173778508234,-1.5122883813398,0.263671875,-1.9236278508234,-1.6746681445494,0.263671875,-2.6959032546078,-2.337047907759,0.076171875,-2.6021532546078,-2.4994276709686,-0.111328125,-2.6021532546078,-2.4994276709686,-0.298828125,-2.6959032546078,-2.337047907759,-0.298828125,-2.7896532546078,-2.1746681445494,-0.111328125,-2.8834032546078,-2.0122883813398,0.076171875,-2.8834032546078,-2.0122883813398,0.263671875,-2.7896532546078,-2.1746681445494,0.263671875,-1.5051183244042,-1.649547907759,0.076171875,-1.4113683244042,-1.8119276709686,-0.111328125,-1.4113683244042,-1.8119276709686,-0.298828125,-1.5051183244042,-1.649547907759,-0.298828125,-1.5988683244042,-1.4871681445494,-0.111328125,-1.6926183244042,-1.3247883813398,0.076171875,-1.6926183244042,-1.3247883813398,0.263671875,-1.5988683244042,-1.4871681445494,0.1015625,-2.7962939518922,-1.5537911194551,0.1015625,-3.2293066537844,-1.8037911194551,-0.1484375,-3.2293066537844,-1.8037911194551,-0.1484375,-2.7962939518922,-1.5537911194551,0.1015625,-2.9212939518922,-1.337284768509,0.1015625,-3.3543066537844,-1.587284768509,-0.1484375,-3.3543066537844,-1.587284768509,-0.1484375,-2.9212939518922,-1.337284768509,0.1015625,-3.4458130047305,-1.9287911194551,0.1015625,-3.5708130047305,-1.712284768509,-0.1484375,-3.5708130047305,-1.712284768509,-0.1484375,-3.4458130047305,-1.9287911194551,-0.1484375,-3.1958130047305,-2.3618038213473,-0.1484375,-2.9793066537844,-2.2368038213473,0.1015625,-2.9793066537844,-2.2368038213473,0.1015625,-3.1958130047305,-2.3618038213473,-0.1484375,-3.0708130047305,-2.5783101722934,-0.1484375,-2.8543066537844,-2.4533101722934,0.1015625,-2.8543066537844,-2.4533101722934,0.1015625,-3.0708130047305,-2.5783101722934,0.25,2.1764746513685,0.66324802433628,0.25,0.87743654569181,-0.086751975663723,-0.25,0.87743654569181,-0.086751975663723,-0.25,2.1764746513685,0.66324802433628,0.25,2.1070508075689,0.78349364905389,0.25,1.4575317547305,0.40849364905389,-0.25,1.4575317547305,0.40849364905389,-0.25,2.1070508075689,0.78349364905389,0.25,1.8684619494762,0.19674167339017,0.25,1.2728020999572,-0.27154520321395,-0.25,1.2728020999572,-0.27154520321395,-0.25,1.8684619494762,0.19674167339017,0.25,-0.026236005719494,-1.0215452032139,0.25,0.011411141907369,-0.58675197566372,-0.25,0.011411141907369,-0.58675197566372,-0.25,-0.026236005719494,-1.0215452032139,0.25,-0.72961426187707,-1.3032583266098,0.25,-1.2876269637693,-1.3367519756637,-0.25,-1.2876269637693,-1.3367519756637,-0.25,-0.72961426187707,-1.3032583266098,0.25,-1.3570508075689,-1.2165063509461,0.25,-0.70753175473055,-0.84150635094611,-0.25,-0.70753175473055,-0.84150635094611,-0.25,-1.3570508075689,-1.2165063509461,0.25,2.2679810023146,1.0047543752824,0.25,1.6184619494762,0.62975437528239,-0.25,1.6184619494762,0.62975437528239,-0.25,2.2679810023146,1.0047543752824,0.25,2.198557158515,1.125,0.25,1.7655444566228,0.875,-0.25,1.7655444566228,0.875,-0.25,2.198557158515,1.125,0.25,2.0138275037416,0.44496114773216,-0.25,2.0138275037416,0.44496114773216,0.25,1.1478020999572,-0.055038852267839,0.25,1.185449247584,0.37975437528239,-0.25,1.185449247584,0.37975437528239,-0.25,1.1478020999572,-0.055038852267839,0.25,0.5359301947457,0.0047543752823874,-0.25,0.5359301947457,0.0047543752823874,0.25,0.46650635094611,0.125,0.25,0.89951905283833,0.375,-0.25,0.89951905283833,0.375,-0.25,0.46650635094611,0.125,0.25,0.10291749285348,-0.24524562471761,0.25,-0.54660155998485,-0.62024562471761,-0.25,-0.54660155998485,-0.62024562471761,-0.25,0.10291749285348,-0.24524562471761,0.25,0.033493649053891,-0.125,0.25,-0.39951905283833,-0.375,-0.25,-0.39951905283833,-0.375,-0.25,0.033493649053891,-0.125,0.25,-0.15123600571949,-0.80503885226784,-0.25,-0.15123600571949,-0.80503885226784,0.25,-1.0172614095039,-1.3050388522678,0.25,-0.97961426187707,-0.87024562471761,-0.25,-0.97961426187707,-0.87024562471761,-0.25,-1.0172614095039,-1.3050388522678,0.25,-1.6291333147154,-1.2452456247176,-0.25,-1.6291333147154,-1.2452456247176,0.25,-1.698557158515,-1.125,0.25,-1.2655444566228,-0.875,-0.25,-1.2655444566228,-0.875,-0.25,-1.698557158515,-1.125,0.3125,2.3045666849341,1.6913861141557,0.3125,-2.2420666849342,-0.93361388584431,-0.3125,-2.2420666849342,-0.93361388584431,-0.3125,2.3045666849341,1.6913861141557,0.3125,1.9920666849341,2.232651991521,0.3125,-2.5545666849342,-0.39234800847903,-0.3125,-2.5545666849342,-0.39234800847903,-0.3125,1.9920666849341,2.232651991521,0.25,2.4150635094611,1.25,0.25,-1.9150635094611,-1.25,-0.25,-1.9150635094611,-1.25,-0.25,2.4150635094611,1.25,0.25,2.1650635094611,1.6830127018922,0.25,-2.1650635094611,-0.81698729810778,-0.25,-2.1650635094611,-0.81698729810778,-0.25,2.1650635094611,1.6830127018922], + "name":"sword", + "faces":[{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[1,2,3,4] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[6,5,8,7] + },{ + "color":11, + "uvs":[0.5,0,0.5,0.125,0.375,0.125,0.375,0], + "vertex_ids":[5,6,2,1] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[5,1,4,8] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[2,6,7,3] + },{ + "color":11, + "uvs":[0.5,0,0.5,0.125,0.375,0.125,0.375,0], + "vertex_ids":[4,3,7,8] + },{ + "color":10, + "uvs":[0.5,0.75,0.46875,0.71875,0.46875,0.65625,0.5,0.625,0.5625,0.625,0.59375,0.65625,0.59375,0.71875,0.5625,0.75], + "vertex_ids":[25,26,27,28,29,30,31,32] + },{ + "color":10, + "uvs":[0.6875,0.59375,0.65625,0.5625,0.65625,0.5,0.6875,0.46875,0.75,0.46875,0.78125,0.5,0.78125,0.5625,0.75,0.59375], + "vertex_ids":[24,23,22,21,20,19,18,17] + },{ + "color":10, + "uvs":[0.78125,0.46875,0.78125,0.59375,0.65625,0.59375,0.65625,0.46875], + "vertex_ids":[9,17,18,10] + },{ + "color":10, + "uvs":[0.78125,0.46875,0.78125,0.59375,0.65625,0.59375,0.65625,0.46875], + "vertex_ids":[10,18,19,11] + },{ + "color":10, + "uvs":[0.78125,0.46875,0.78125,0.59375,0.65625,0.59375,0.65625,0.46875], + "vertex_ids":[11,19,20,12] + },{ + "color":10, + "uvs":[0.78125,0.46875,0.78125,0.59375,0.65625,0.59375,0.65625,0.46875], + "vertex_ids":[12,20,21,13] + },{ + "color":10, + "uvs":[0.78125,0.46875,0.78125,0.59375,0.65625,0.59375,0.65625,0.46875], + "vertex_ids":[13,21,22,14] + },{ + "color":10, + "uvs":[0.78125,0.46875,0.78125,0.59375,0.65625,0.59375,0.65625,0.46875], + "vertex_ids":[14,22,23,15] + },{ + "color":10, + "uvs":[0.78125,0.46875,0.78125,0.59375,0.65625,0.59375,0.65625,0.46875], + "vertex_ids":[15,23,24,16] + },{ + "color":10, + "uvs":[0.78125,0.46875,0.78125,0.59375,0.65625,0.59375,0.65625,0.46875], + "vertex_ids":[16,24,17,9] + },{ + "color":10, + "uvs":[0.5,0.65625,0.5625,0.65625,0.5625,0.71875,0.5,0.71875], + "vertex_ids":[25,9,10,26] + },{ + "color":10, + "uvs":[0.4921875,0.65625,0.5546875,0.65625,0.5546875,0.71875,0.4921875,0.71875], + "vertex_ids":[26,10,11,27] + },{ + "color":10, + "uvs":[0.46875,0.6875,0.53125,0.6875,0.53125,0.75,0.46875,0.75], + "vertex_ids":[27,11,12,28] + },{ + "color":10, + "uvs":[0.53125,0.65625,0.59375,0.65625,0.59375,0.71875,0.53125,0.71875], + "vertex_ids":[28,12,13,29] + },{ + "color":10, + "uvs":[0.53125,0.65625,0.59375,0.65625,0.59375,0.71875,0.53125,0.71875], + "vertex_ids":[29,13,14,30] + },{ + "color":10, + "uvs":[0.5,0.65625,0.5625,0.65625,0.5625,0.71875,0.5,0.71875], + "vertex_ids":[30,14,15,31] + },{ + "color":10, + "uvs":[0.5,0.6875,0.5625,0.6875,0.5625,0.75,0.5,0.75], + "vertex_ids":[31,15,16,32] + },{ + "color":10, + "uvs":[0.53125,0.65625,0.59375,0.65625,0.59375,0.71875,0.53125,0.71875], + "vertex_ids":[32,16,9,25] + },{ + "color":11, + "uvs":[0.4375,0.625,0.5625,0.625,0.5625,0.75,0.4375,0.75], + "vertex_ids":[33,34,35,36] + },{ + "color":11, + "uvs":[0.4375,0.625,0.5625,0.625,0.5625,0.75,0.4375,0.75], + "vertex_ids":[38,37,40,39] + },{ + "color":11, + "uvs":[0.5625,0.625,0.5625,0.75,0.4375,0.75,0.4375,0.625], + "vertex_ids":[37,38,34,33] + },{ + "color":11, + "uvs":[0.4375,0.625,0.5625,0.625,0.5625,0.75,0.4375,0.75], + "vertex_ids":[37,33,36,40] + },{ + "color":11, + "uvs":[0.4375,0.625,0.5625,0.625,0.5625,0.75,0.4375,0.75], + "vertex_ids":[41,42,43,44] + },{ + "color":11, + "uvs":[0.5625,0.65625,0.5625,0.78125,0.4375,0.78125,0.4375,0.65625], + "vertex_ids":[36,35,39,40] + },{ + "color":11, + "uvs":[0.4375,0.625,0.5625,0.625,0.5625,0.75,0.4375,0.75], + "vertex_ids":[41,34,38,42] + },{ + "color":11, + "uvs":[0.4375,0.625,0.5625,0.625,0.5625,0.75,0.4375,0.75], + "vertex_ids":[42,38,39,43] + },{ + "color":11, + "uvs":[0.4375,0.625,0.5625,0.625,0.5625,0.75,0.4375,0.75], + "vertex_ids":[43,39,35,44] + },{ + "color":11, + "uvs":[0.4375,0.625,0.5625,0.625,0.5625,0.75,0.4375,0.75], + "vertex_ids":[49,50,51,52] + },{ + "color":11, + "uvs":[0.4375,0.625,0.5625,0.625,0.5625,0.75,0.4375,0.75], + "vertex_ids":[45,44,35,46] + },{ + "color":11, + "uvs":[0.4375,0.625,0.5625,0.625,0.5625,0.75,0.4375,0.75], + "vertex_ids":[46,35,34,47] + },{ + "color":11, + "uvs":[0.4375,0.625,0.5625,0.625,0.5625,0.75,0.4375,0.75], + "vertex_ids":[47,34,41,48] + },{ + "color":11, + "uvs":[0.4375,0.625,0.5625,0.625,0.5625,0.75,0.4375,0.75], + "vertex_ids":[48,41,44,45] + },{ + "color":11, + "uvs":[0.4375,0.625,0.5625,0.625,0.5625,0.75,0.4375,0.75], + "vertex_ids":[49,45,46,50] + },{ + "color":11, + "uvs":[0.4375,0.625,0.5625,0.625,0.5625,0.75,0.4375,0.75], + "vertex_ids":[3,7,6,2] + },{ + "color":11, + "uvs":[0.4375,0.625,0.5625,0.625,0.5625,0.75,0.4375,0.75], + "vertex_ids":[51,47,48,52] + },{ + "color":11, + "uvs":[0.4375,0.625,0.5625,0.625,0.5625,0.75,0.4375,0.75], + "vertex_ids":[52,48,45,49] + },{ + "color":11, + "uvs":[0.4375,0.625,0.5625,0.625,0.5625,0.75,0.4375,0.75], + "vertex_ids":[3,50,46,7] + },{ + "color":11, + "uvs":[0.4375,0.625,0.5625,0.625,0.5625,0.75,0.4375,0.75], + "vertex_ids":[7,46,47,6] + },{ + "color":11, + "uvs":[0.4375,0.625,0.5625,0.625,0.5625,0.75,0.4375,0.75], + "vertex_ids":[6,47,51,2] + },{ + "color":11, + "uvs":[0.4375,0.625,0.5625,0.625,0.5625,0.75,0.4375,0.75], + "vertex_ids":[2,51,50,3] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[61,62,63,64] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[58,57,60,59] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[57,58,54,53] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[57,53,56,60] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[54,58,59,55] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[56,55,59,60] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[61,53,54,62] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[69,70,71,72] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[63,55,56,64] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[64,56,53,61] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[65,62,54,66] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[66,54,55,67] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[67,55,63,68] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[68,63,62,65] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[69,65,66,70] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[73,74,75,76] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[71,67,68,72] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[72,68,65,69] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[73,70,66,74] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[74,66,67,75] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[75,67,71,76] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[76,71,70,73] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[53,85,86,56] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[82,81,84,83] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[81,82,78,77] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[81,77,80,84] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[78,82,83,79] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[80,79,83,84] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[53,77,78,85] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[54,91,92,55] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[86,79,80,56] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[56,80,77,53] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[87,85,78,88] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[88,78,79,89] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[89,79,86,90] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[90,86,85,87] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[54,87,88,91] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[93,94,95,96] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[92,89,90,55] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[55,90,87,54] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[93,91,88,94] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[94,88,89,95] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[95,89,92,96] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[96,92,91,93] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[66,105,106,67] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[102,101,104,103] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[101,102,98,97] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[101,97,100,104] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[98,102,103,99] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[100,99,103,104] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[66,97,98,105] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[70,111,112,71] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[106,99,100,67] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[67,100,97,66] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[107,105,98,108] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[108,98,99,109] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[109,99,106,110] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[110,106,105,107] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[70,107,108,111] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[113,114,115,116] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[112,109,110,71] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[71,110,107,70] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[113,111,108,114] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[114,108,109,115] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[115,109,112,116] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[116,112,111,113] + },{ + "color":11, + "uvs":[0.65625,0.65625,0.78125,0.65625,0.78125,0.78125,0.65625,0.78125], + "vertex_ids":[117,118,119,120] + },{ + "color":11, + "uvs":[0.65625,0.65625,0.78125,0.65625,0.78125,0.78125,0.65625,0.78125], + "vertex_ids":[122,121,124,123] + },{ + "color":11, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[121,122,118,117] + },{ + "color":11, + "uvs":[0.65625,0.65625,0.78125,0.65625,0.78125,0.78125,0.65625,0.78125], + "vertex_ids":[121,117,120,124] + },{ + "color":11, + "uvs":[0.65625,0.65625,0.78125,0.65625,0.78125,0.78125,0.65625,0.78125], + "vertex_ids":[118,122,123,119] + },{ + "color":11, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[120,119,123,124] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[125,126,127,128] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[130,129,132,131] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[129,130,126,125] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[129,125,128,132] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[126,130,131,127] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[128,127,131,132] + }] + }, + "locked":true, + "transform":{ + "scale":{ + "x":1, + "y":1, + "z":1 + }, + "pos":{ + "x":0, + "y":5.25, + "z":0.25 + }, + "rot":{ + "x":0, + "y":-0, + "z":0 + } + } + },{ + "ghost":false, + "open":false, + "children":[], + "visible":true, + "name":"rod.1", + "motions":{ + "tracks":[[],[],[],[]] + }, + "mesh":{ + "vertices":[0.125,1.75,-0.125,0.125,-4.25,-0.125,-0.125,-4.25,-0.125,-0.125,1.75,-0.125,0.125,1.75,0.125,0.125,-4.25,0.125,-0.125,-4.25,0.125,-0.125,1.75,0.125,0.125,2,0.125,0.125,2,-0.125,-0.125,2,-0.125,-0.125,2,0.125,0.625,2,0.125,0.625,1.75,0.125,0.625,1.75,-0.125,0.625,2,-0.125], + "name":"cube...15", + "faces":[{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[1,2,3,4] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[6,5,8,7] + },{ + "color":11, + "uvs":[0.53125,0.65625,0.53125,0.78125,0.40625,0.78125,0.40625,0.65625], + "vertex_ids":[5,6,2,1] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[9,10,11,12] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[2,6,7,3] + },{ + "color":11, + "uvs":[0.5,0.65625,0.5,0.78125,0.375,0.78125,0.375,0.65625], + "vertex_ids":[4,3,7,8] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[13,14,15,16] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[10,1,4,11] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[11,4,8,12] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[12,8,5,9] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[13,9,5,14] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[14,5,1,15] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[15,1,10,16] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[16,10,9,13] + }] + }, + "locked":true, + "transform":{ + "scale":{ + "x":1, + "y":1, + "z":1 + }, + "pos":{ + "x":-0.75, + "y":5.328125, + "z":1.2421875 + }, + "rot":{ + "x":0, + "y":-0, + "z":0 + } + } + },{ + "ghost":false, + "open":true, + "children":[], + "visible":true, + "name":"rod.2", + "motions":{ + "tracks":[[],[],[],[]] + }, + "mesh":{ + "vertices":[0.125,3.75,-0.375,0.125,-0.25,-0.375,-0.125,-0.25,-0.375,-0.125,3.75,-0.375,0.125,3.75,-0.125,0.125,-0.25,-0.125,-0.125,-0.25,-0.125,-0.125,3.75,-0.125,0.125,4,-0.125,0.125,4,-0.375,-0.125,4,-0.375,-0.125,4,-0.125,0.625,4,-0.125,0.625,3.75,-0.125,0.625,3.75,-0.375,0.625,4,-0.375], + "name":"cube...14", + "faces":[{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[1,2,3,4] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[6,5,8,7] + },{ + "color":11, + "uvs":[0.53125,0.65625,0.53125,0.78125,0.40625,0.78125,0.40625,0.65625], + "vertex_ids":[5,6,2,1] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[9,10,11,12] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[2,6,7,3] + },{ + "color":11, + "uvs":[0.5,0.65625,0.5,0.78125,0.375,0.78125,0.375,0.65625], + "vertex_ids":[4,3,7,8] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[13,14,15,16] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[10,1,4,11] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[11,4,8,12] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[12,8,5,9] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[13,9,5,14] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[14,5,1,15] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[15,1,10,16] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[16,10,9,13] + }] + }, + "locked":true, + "transform":{ + "scale":{ + "x":1, + "y":1, + "z":1 + }, + "pos":{ + "x":-0.75, + "y":-0.796875, + "z":-1.4765625 + }, + "rot":{ + "x":0, + "y":-0, + "z":0 + } + } + }], + "visible":true, + "name":"splatanas", + "motions":{ + "tracks":[[],[],[],[]] + }, + "folder":true, + "locked":true, + "transform":{ + "scale":{ + "x":1, + "y":1, + "z":1 + }, + "pos":{ + "x":0, + "y":0, + "z":0 + }, + "rot":{ + "x":0, + "y":0, + "z":0 + } + } + },{ + "ghost":false, + "open":false, + "children":[{ + "ghost":false, + "open":false, + "children":[], + "visible":true, + "name":"Bow", + "motions":{ + "tracks":[[],[],[],[]] + }, + "mesh":{ + "vertices":[0.18738129781946,2.1758275979673,0.035355339059327,0.18738129781946,1.6758275979673,0.035355339059327,-0.1796875,1.6758275979673,0.035355339059327,-0.1796875,2.1758275979673,0.035355339059327,0.18738129781946,2.0609014187372,-1.0221077505557,0.18738129781946,1.5609014187372,-1.0221077505557,-0.1796875,1.5609014187372,-1.0221077505557,-0.1796875,2.0609014187372,-1.0221077505557,0.18738129781946,1.3109014187372,-2.0221077505557,0.18738129781946,1.8109014187372,-2.0221077505557,-0.1796875,1.8109014187372,-2.0221077505557,-0.1796875,1.3109014187372,-2.0221077505557,0.18738129781946,1.0243249771767,-2.6487279709179,0.18738129781946,1.4535527643736,-2.8544747760831,-0.1796875,1.4535527643736,-2.8544747760831,-0.1796875,1.0243249771767,-2.6487279709179,0.18738129781946,2.0609014187372,1.0928184286744,0.18738129781946,1.5609014187372,1.0928184286744,-0.1796875,1.5609014187372,1.0928184286744,-0.1796875,2.0609014187372,1.0928184286744,0.18738129781946,1.3109014187372,2.0928184286744,0.18738129781946,1.8109014187372,2.0928184286744,-0.1796875,1.8109014187372,2.0928184286744,-0.1796875,1.3109014187372,2.0928184286744,0.18738129781946,1.0243249771767,2.7194386490365,0.18738129781946,1.4535527643736,2.9251854542017,-0.1796875,1.4535527643736,2.9251854542017,-0.1796875,1.0243249771767,2.7194386490365,0.25,3.1854816049064,0.16035533905933,0.125,3.1854816049064,0.28535533905933,-0.125,3.1854816049064,0.28535533905933,-0.25,3.1854816049064,0.16035533905933,-0.25,3.1854816049064,-0.089644660940673,-0.125,3.1854816049064,-0.21464466094067,0.125,3.1854816049064,-0.21464466094067,0.25,3.1854816049064,-0.089644660940673,0.25,3.7511927950683,0.16035533905933,0.125,3.7511927950683,0.28535533905933,-0.125,3.7511927950683,0.28535533905933,-0.25,3.7511927950683,0.16035533905933,-0.25,3.7511927950683,-0.089644660940673,-0.125,3.7511927950683,-0.21464466094067,0.125,3.7511927950683,-0.21464466094067,0.25,3.7511927950683,-0.089644660940673,0.28125,2.5555114842748,1.2099511603326,0.09375,2.5069829133181,1.3910622527618,-0.09375,2.5069829133181,1.3910622527618,-0.28125,2.5555114842748,1.2099511603326,-0.28125,2.6040400552316,1.0288400679034,-0.09375,2.6525686261883,0.84772897547417,0.09375,2.6525686261883,0.84772897547417,0.28125,2.6040400552316,1.0288400679034,0.2229148510965,3.1145615175693,1.296881141255,0.035414851096496,3.0660329466126,1.4779922336842,-0.031649186045994,3.0660329466126,1.4779922336842,-0.21914918604599,3.1145615175693,1.296881141255,-0.21914918604599,3.1316565765123,1.2330815127212,-0.031649186045994,3.1801851474691,1.051970420292,0.035414851096496,3.1801851474691,1.051970420292,0.2229148510965,3.1316565765123,1.2330815127212,0.28125,1.2877338372704,0.87025116363551,0.09375,1.2392052663137,1.0513622560647,-0.09375,1.2392052663137,1.0513622560647,-0.28125,1.2877338372704,0.87025116363551,-0.28125,1.3362624082272,0.68914007120631,-0.09375,1.3847909791839,0.50802897877711,0.09375,1.3847909791839,0.50802897877711,0.28125,1.3362624082272,0.68914007120631,0.28125,2.6010070195468,-0.96944883306154,0.09375,2.6495355905035,-0.78833774063234,-0.09375,2.6495355905035,-0.78833774063234,-0.28125,2.6010070195468,-0.96944883306154,-0.28125,2.5524784485901,-1.1505599254907,-0.09375,2.5039498776333,-1.3316710179199,0.09375,2.5039498776333,-1.3316710179199,0.28125,2.5524784485901,-1.1505599254907,0.2229148510965,3.1286235408275,-1.1736902778794,0.035414851096496,3.1771521117843,-0.9925791854502,-0.031649186045994,3.1771521117843,-0.9925791854502,-0.21914918604599,3.1286235408275,-1.1736902778794,-0.21914918604599,3.1115284818845,-1.2374899064132,-0.031649186045994,3.0629999109278,-1.4186009988424,0.035414851096496,3.0629999109278,-1.4186009988424,0.2229148510965,3.1115284818845,-1.2374899064132,0.28125,1.3332293725424,-0.62974883636449,0.09375,1.3817579434991,-0.44863774393529,-0.09375,1.3817579434991,-0.44863774393529,-0.28125,1.3332293725424,-0.62974883636449,-0.28125,1.2847008015857,-0.81085992879369,-0.09375,1.2361722306289,-0.99197102122289,0.09375,1.2361722306289,-0.99197102122289,0.28125,1.2847008015857,-0.81085992879369,0.375,2.9432941049064,0.15254283905933,0.125,2.9432941049064,0.40254283905933,-0.125,2.9432941049064,0.40254283905933,-0.375,2.9432941049064,0.15254283905933,-0.375,2.9432941049064,-0.097457160940673,-0.125,2.9432941049064,-0.34745716094067,0.125,2.9432941049064,-0.34745716094067,0.375,2.9432941049064,-0.097457160940673,0.375,3.4432941049064,0.15254283905933,0.125,3.4432941049064,0.40254283905933,-0.125,3.4432941049064,0.40254283905933,-0.375,3.4432941049064,0.15254283905933,-0.375,3.4432941049064,-0.097457160940673,-0.125,3.4432941049064,-0.34745716094067,0.125,3.4432941049064,-0.34745716094067,0.375,3.4432941049064,-0.097457160940673,0.375,1.4432941049064,0.15254283905933,0.125,1.4432941049064,0.40254283905933,-0.125,1.4432941049064,0.40254283905933,-0.375,1.4432941049064,0.15254283905933,-0.375,1.4432941049064,-0.097457160940673,-0.125,1.4432941049064,-0.34745716094067,0.125,1.4432941049064,-0.34745716094067,0.375,1.4432941049064,-0.097457160940673,0.375,1.1932941049064,0.15254283905933,0.125,1.1932941049064,0.40254283905933,-0.125,1.1932941049064,0.40254283905933,-0.375,1.1932941049064,0.15254283905933,-0.375,1.1932941049064,-0.097457160940673,-0.125,1.1932941049064,-0.34745716094067,0.125,1.1932941049064,-0.34745716094067,0.375,1.1932941049064,-0.097457160940673,0.1875,0.18548160490641,0.035355339059327,0.1875,-0.18951839509359,-0.15214466094067,-0.1875,-0.18951839509359,-0.15214466094067,-0.1875,0.18548160490641,0.035355339059327,0.1875,-0.18951839509359,0.22285533905933,-0.1875,-0.18951839509359,0.22285533905933,0.1875,0.37298160490641,-0.71464466094067,0.1875,-0.18951839509359,-0.52714466094067,-0.1875,-0.18951839509359,-0.52714466094067,-0.1875,0.37298160490641,-0.71464466094067,0.1875,-0.18951839509359,0.59785533905933,0.1875,0.37298160490641,0.78535533905933,-0.1875,0.37298160490641,0.78535533905933,-0.1875,-0.18951839509359,0.59785533905933,0.1875,0.56048160490641,0.59785533905933,0.1875,0.37298160490641,0.22285533905933,-0.1875,0.37298160490641,0.22285533905933,-0.1875,0.56048160490641,0.59785533905933,-0.1875,0.56048160490641,-0.52714466094067,-0.1875,0.37298160490641,-0.15214466094067,0.1875,0.37298160490641,-0.15214466094067,0.1875,0.56048160490641,-0.52714466094067,0.1875,-0.0020183950935892,-0.90214466094067,-0.1875,-0.0020183950935892,-0.90214466094067,0.1875,-0.0020183950935892,0.97285533905933,-0.1875,-0.0020183950935892,0.97285533905933,0.1171875,1.1944159294334,-2.6786765234676,0.1171875,-0.055584070566644,-0.51361301400654,-0.1328125,-0.055584070566644,-0.51361301400654,-0.1328125,1.1944159294334,-2.6786765234676,0.1171875,1.4109222803795,-2.5536765234676,0.1171875,0.16092228037947,-0.38861301400654,-0.1328125,0.16092228037947,-0.38861301400654,-0.1328125,1.4109222803795,-2.5536765234676,0.1171875,1.4109222803795,2.6243872015863,0.1171875,0.16092228037947,0.4593236921252,-0.1328125,0.16092228037947,0.4593236921252,-0.1328125,1.4109222803795,2.6243872015863,0.1171875,1.1944159294334,2.7493872015863,0.1171875,-0.055584070566644,0.5843236921252,-0.1328125,-0.055584070566644,0.5843236921252,-0.1328125,1.1944159294334,2.7493872015863,0.1171875,2.6778511989555,-1.2283889544034,0.1171875,0.26303663323283,-0.58134134164708,-0.1328125,0.26303663323283,-0.58134134164708,-0.1328125,2.6778511989555,-1.2283889544034,0.1171875,2.7425559602311,-0.98690749783111,0.1171875,0.32774139450846,-0.33985988507481,-0.1328125,0.32774139450846,-0.33985988507481,-0.1328125,2.7425559602311,-0.98690749783111,0.1171875,2.7425559602311,1.0576181759498,0.1171875,0.32774139450846,0.41057056319347,-0.1328125,0.32774139450846,0.41057056319347,-0.1328125,2.7425559602311,1.0576181759498,0.1171875,2.6778511989555,1.299099632522,0.1171875,0.26303663323283,0.65205201976573,-0.1328125,0.26303663323283,0.65205201976573,-0.1328125,2.6778511989555,1.299099632522,0.1171875,2.5448566049064,-0.089644660940673,0.1171875,0.044856604906411,-0.089644660940673,-0.1328125,0.044856604906411,-0.089644660940673,-0.1328125,2.5448566049064,-0.089644660940673,0.1171875,2.5448566049064,0.16035533905933,0.1171875,0.044856604906411,0.16035533905933,-0.1328125,0.044856604906411,0.16035533905933,-0.1328125,2.5448566049064,0.16035533905933], + "name":"Bow", + "faces":[{ + "color":11, + "uvs":[0.84375,0.78125,0.96875,0.78125,0.96875,0.65625,0.84375,0.65625], + "vertex_ids":[4,3,2,1] + },{ + "color":11, + "uvs":[0.84375,0.78125,0.96875,0.78125,0.96875,0.65625,0.84375,0.65625], + "vertex_ids":[16,15,14,13] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.84375,0.78125,0.96875,0.78125,0.96875,0.65625], + "vertex_ids":[1,2,6,5] + },{ + "color":11, + "uvs":[0.84375,0.78125,0.96875,0.78125,0.96875,0.65625,0.84375,0.65625], + "vertex_ids":[8,4,1,5] + },{ + "color":11, + "uvs":[0.84375,0.78125,0.96875,0.78125,0.96875,0.65625,0.84375,0.65625], + "vertex_ids":[3,7,6,2] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.84375,0.78125,0.96875,0.78125,0.96875,0.65625], + "vertex_ids":[8,7,3,4] + },{ + "color":11, + "uvs":[0.84375,0.78125,0.96875,0.78125,0.96875,0.65625,0.84375,0.65625], + "vertex_ids":[10,5,6,9] + },{ + "color":11, + "uvs":[0.84375,0.78125,0.96875,0.78125,0.96875,0.65625,0.84375,0.65625], + "vertex_ids":[11,8,5,10] + },{ + "color":11, + "uvs":[0.84375,0.78125,0.96875,0.78125,0.96875,0.65625,0.84375,0.65625], + "vertex_ids":[12,7,8,11] + },{ + "color":11, + "uvs":[0.84375,0.78125,0.96875,0.78125,0.96875,0.65625,0.84375,0.65625], + "vertex_ids":[9,6,7,12] + },{ + "color":11, + "uvs":[0.84375,0.78125,0.96875,0.78125,0.96875,0.65625,0.84375,0.65625], + "vertex_ids":[14,10,9,13] + },{ + "color":11, + "uvs":[0.84375,0.78125,0.96875,0.78125,0.96875,0.65625,0.84375,0.65625], + "vertex_ids":[15,11,10,14] + },{ + "color":11, + "uvs":[0.84375,0.78125,0.96875,0.78125,0.96875,0.65625,0.84375,0.65625], + "vertex_ids":[16,12,11,15] + },{ + "color":11, + "uvs":[0.84375,0.78125,0.96875,0.78125,0.96875,0.65625,0.84375,0.65625], + "vertex_ids":[13,9,12,16] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[1,2,3,4] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[25,26,27,28] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[17,18,2,1] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[17,1,4,20] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[2,18,19,3] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[4,3,19,20] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[21,18,17,22] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[22,17,20,23] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[23,20,19,24] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[24,19,18,21] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[25,21,22,26] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[26,22,23,27] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[27,23,24,28] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[28,24,21,25] + },{ + "color":10, + "uvs":[0.78125,0.125,0.75,0.09375,0.75,0.03125,0.78125,0,0.84375,0,0.875,0.03125,0.875,0.09375,0.84375,0.125], + "vertex_ids":[29,30,31,32,33,34,35,36] + },{ + "color":10, + "uvs":[0.78125,0.125,0.75,0.09375,0.75,0.03125,0.78125,0,0.84375,0,0.875,0.03125,0.875,0.09375,0.84375,0.125], + "vertex_ids":[44,43,42,41,40,39,38,37] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[29,37,38,30] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[30,38,39,31] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[31,39,40,32] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[32,40,41,33] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[33,41,42,34] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[34,42,43,35] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[35,43,44,36] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[36,44,37,29] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.65625,0.75,0.65625,0.6875,0.6875,0.65625,0.75,0.65625,0.78125,0.6875,0.78125,0.75,0.75,0.78125], + "vertex_ids":[61,62,63,64,65,66,67,68] + },{ + "color":10, + "uvs":[0.78125,0.125,0.75,0.09375,0.75,0.03125,0.78125,0,0.84375,0,0.875,0.03125,0.875,0.09375,0.84375,0.125], + "vertex_ids":[60,59,58,57,56,55,54,53] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[45,53,54,46] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[46,54,55,47] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[47,55,56,48] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[48,56,57,49] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[49,57,58,50] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[50,58,59,51] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[51,59,60,52] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[52,60,53,45] + },{ + "color":10, + "uvs":[0.71875,0.65625,0.78125,0.65625,0.78125,0.71875,0.71875,0.71875], + "vertex_ids":[61,45,46,62] + },{ + "color":10, + "uvs":[0.6875,0.65625,0.75,0.65625,0.75,0.71875,0.6875,0.71875], + "vertex_ids":[62,46,47,63] + },{ + "color":10, + "uvs":[0.6875,0.6875,0.75,0.6875,0.75,0.75,0.6875,0.75], + "vertex_ids":[63,47,48,64] + },{ + "color":10, + "uvs":[0.6875,0.65625,0.75,0.65625,0.75,0.71875,0.6875,0.71875], + "vertex_ids":[64,48,49,65] + },{ + "color":10, + "uvs":[0.6875,0.6875,0.75,0.6875,0.75,0.75,0.6875,0.75], + "vertex_ids":[65,49,50,66] + },{ + "color":10, + "uvs":[0.6875,0.6875,0.75,0.6875,0.75,0.75,0.6875,0.75], + "vertex_ids":[66,50,51,67] + },{ + "color":10, + "uvs":[0.6875,0.6875,0.75,0.6875,0.75,0.75,0.6875,0.75], + "vertex_ids":[67,51,52,68] + },{ + "color":10, + "uvs":[0.6875,0.6875,0.75,0.6875,0.75,0.75,0.6875,0.75], + "vertex_ids":[68,52,45,61] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.65625,0.75,0.65625,0.6875,0.6875,0.65625,0.75,0.65625,0.78125,0.6875,0.78125,0.75,0.75,0.78125], + "vertex_ids":[85,86,87,88,89,90,91,92] + },{ + "color":10, + "uvs":[0.78125,0.125,0.75,0.09375,0.75,0.03125,0.78125,0,0.84375,0,0.875,0.03125,0.875,0.09375,0.84375,0.125], + "vertex_ids":[84,83,82,81,80,79,78,77] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[69,77,78,70] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[70,78,79,71] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[71,79,80,72] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[72,80,81,73] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[73,81,82,74] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[74,82,83,75] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[75,83,84,76] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[76,84,77,69] + },{ + "color":10, + "uvs":[0.71875,0.65625,0.78125,0.65625,0.78125,0.71875,0.71875,0.71875], + "vertex_ids":[85,69,70,86] + },{ + "color":10, + "uvs":[0.6875,0.65625,0.75,0.65625,0.75,0.71875,0.6875,0.71875], + "vertex_ids":[86,70,71,87] + },{ + "color":10, + "uvs":[0.6875,0.6875,0.75,0.6875,0.75,0.75,0.6875,0.75], + "vertex_ids":[87,71,72,88] + },{ + "color":10, + "uvs":[0.6875,0.65625,0.75,0.65625,0.75,0.71875,0.6875,0.71875], + "vertex_ids":[88,72,73,89] + },{ + "color":10, + "uvs":[0.6875,0.6875,0.75,0.6875,0.75,0.75,0.6875,0.75], + "vertex_ids":[89,73,74,90] + },{ + "color":10, + "uvs":[0.6875,0.6875,0.75,0.6875,0.75,0.75,0.6875,0.75], + "vertex_ids":[90,74,75,91] + },{ + "color":10, + "uvs":[0.6875,0.6875,0.75,0.6875,0.75,0.75,0.6875,0.75], + "vertex_ids":[91,75,76,92] + },{ + "color":10, + "uvs":[0.6875,0.6875,0.75,0.6875,0.75,0.75,0.6875,0.75], + "vertex_ids":[92,76,69,85] + },{ + "color":10, + "uvs":[0.78125,0.15625,0.75,0.125,0.75,0.0625,0.78125,0.03125,0.84375,0.03125,0.875,0.0625,0.875,0.125,0.84375,0.15625], + "vertex_ids":[117,118,119,120,121,122,123,124] + },{ + "color":10, + "uvs":[0.78125,0.125,0.75,0.09375,0.75,0.03125,0.78125,0,0.84375,0,0.875,0.03125,0.875,0.09375,0.84375,0.125], + "vertex_ids":[108,107,106,105,104,103,102,101] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[93,101,102,94] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[94,102,103,95] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[95,103,104,96] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[96,104,105,97] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[97,105,106,98] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[98,106,107,99] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[99,107,108,100] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[100,108,101,93] + },{ + "color":10, + "uvs":[0.71875,0.65625,0.78125,0.65625,0.78125,0.71875,0.71875,0.71875], + "vertex_ids":[109,93,94,110] + },{ + "color":10, + "uvs":[0.6875,0.65625,0.75,0.65625,0.75,0.71875,0.6875,0.71875], + "vertex_ids":[110,94,95,111] + },{ + "color":10, + "uvs":[0.6875,0.6875,0.75,0.6875,0.75,0.75,0.6875,0.75], + "vertex_ids":[111,95,96,112] + },{ + "color":10, + "uvs":[0.6875,0.65625,0.75,0.65625,0.75,0.71875,0.6875,0.71875], + "vertex_ids":[112,96,97,113] + },{ + "color":10, + "uvs":[0.6875,0.6875,0.75,0.6875,0.75,0.75,0.6875,0.75], + "vertex_ids":[113,97,98,114] + },{ + "color":10, + "uvs":[0.6875,0.6875,0.75,0.6875,0.75,0.75,0.6875,0.75], + "vertex_ids":[114,98,99,115] + },{ + "color":10, + "uvs":[0.6875,0.6875,0.75,0.6875,0.75,0.75,0.6875,0.75], + "vertex_ids":[115,99,100,116] + },{ + "color":10, + "uvs":[0.6875,0.6875,0.75,0.6875,0.75,0.75,0.6875,0.75], + "vertex_ids":[116,100,93,109] + },{ + "color":10, + "uvs":[0.75,0.09375,0.8125,0.09375,0.8125,0.15625,0.75,0.15625], + "vertex_ids":[117,109,110,118] + },{ + "color":10, + "uvs":[0.78125,0.03125,0.84375,0.03125,0.84375,0.09375,0.78125,0.09375], + "vertex_ids":[118,110,111,119] + },{ + "color":10, + "uvs":[0.78125,0.0625,0.84375,0.0625,0.84375,0.125,0.78125,0.125], + "vertex_ids":[119,111,112,120] + },{ + "color":10, + "uvs":[0.78125,0.0625,0.84375,0.0625,0.84375,0.125,0.78125,0.125], + "vertex_ids":[120,112,113,121] + },{ + "color":10, + "uvs":[0.78125,0.0625,0.84375,0.0625,0.84375,0.125,0.78125,0.125], + "vertex_ids":[121,113,114,122] + },{ + "color":10, + "uvs":[0.75,0.0625,0.8125,0.0625,0.8125,0.125,0.75,0.125], + "vertex_ids":[122,114,115,123] + },{ + "color":10, + "uvs":[0.75,0.09375,0.8125,0.09375,0.8125,0.15625,0.75,0.15625], + "vertex_ids":[123,115,116,124] + },{ + "color":10, + "uvs":[0.75,0.09375,0.8125,0.09375,0.8125,0.15625,0.75,0.15625], + "vertex_ids":[124,116,109,117] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[147,147,148,148] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[149,149,150,150] + },{ + "color":11, + "uvs":[0.5,0,0.5,0.125,0.375,0.125,0.375,0], + "vertex_ids":[125,129,126,125] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[125,125,128,128] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[126,129,130,127] + },{ + "color":11, + "uvs":[0.5,0,0.5,0.125,0.375,0.125,0.375,0], + "vertex_ids":[128,127,130,128] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[131,125,126,132] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[132,126,127,133] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[133,127,128,134] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[143,144,145,146] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[135,129,125,136] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[139,140,141,142] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[137,128,130,138] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[138,130,129,135] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[139,136,125,140] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[140,125,128,141] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[141,128,137,142] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[142,137,136,139] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[143,134,128,144] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[144,128,125,145] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[145,125,131,146] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[146,131,134,143] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[147,131,132,147] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[147,132,133,148] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[148,133,134,148] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[148,134,131,147] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[149,135,136,149] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[149,136,137,150] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[150,137,138,150] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[150,138,135,149] + },{ + "color":11, + "uvs":[0.46875,0.625,0.59375,0.625,0.59375,0.75,0.46875,0.75], + "vertex_ids":[151,152,153,154] + },{ + "color":11, + "uvs":[0.4609375,0.625,0.5859375,0.625,0.5859375,0.75,0.4609375,0.75], + "vertex_ids":[156,155,158,157] + },{ + "color":11, + "uvs":[0.59375,0.625,0.59375,0.75,0.46875,0.75,0.46875,0.625], + "vertex_ids":[155,156,152,151] + },{ + "color":11, + "uvs":[0.46875,0.625,0.59375,0.625,0.59375,0.75,0.46875,0.75], + "vertex_ids":[155,151,154,158] + },{ + "color":11, + "uvs":[0.46875,0.625,0.59375,0.625,0.59375,0.75,0.46875,0.75], + "vertex_ids":[152,156,157,153] + },{ + "color":11, + "uvs":[0.5859375,0.625,0.5859375,0.75,0.4609375,0.75,0.4609375,0.625], + "vertex_ids":[154,153,157,158] + },{ + "color":11, + "uvs":[0.46875,0.625,0.59375,0.625,0.59375,0.75,0.46875,0.75], + "vertex_ids":[159,160,161,162] + },{ + "color":11, + "uvs":[0.4609375,0.625,0.5859375,0.625,0.5859375,0.75,0.4609375,0.75], + "vertex_ids":[164,163,166,165] + },{ + "color":11, + "uvs":[0.59375,0.625,0.59375,0.75,0.46875,0.75,0.46875,0.625], + "vertex_ids":[163,164,160,159] + },{ + "color":11, + "uvs":[0.46875,0.625,0.59375,0.625,0.59375,0.75,0.46875,0.75], + "vertex_ids":[163,159,162,166] + },{ + "color":11, + "uvs":[0.46875,0.625,0.59375,0.625,0.59375,0.75,0.46875,0.75], + "vertex_ids":[160,164,165,161] + },{ + "color":11, + "uvs":[0.5859375,0.625,0.5859375,0.75,0.4609375,0.75,0.4609375,0.625], + "vertex_ids":[162,161,165,166] + },{ + "color":11, + "uvs":[0.46875,0.625,0.59375,0.625,0.59375,0.75,0.46875,0.75], + "vertex_ids":[167,168,169,170] + },{ + "color":11, + "uvs":[0.4609375,0.625,0.5859375,0.625,0.5859375,0.75,0.4609375,0.75], + "vertex_ids":[172,171,174,173] + },{ + "color":11, + "uvs":[0.59375,0.625,0.59375,0.75,0.46875,0.75,0.46875,0.625], + "vertex_ids":[171,172,168,167] + },{ + "color":11, + "uvs":[0.46875,0.625,0.59375,0.625,0.59375,0.75,0.46875,0.75], + "vertex_ids":[171,167,170,174] + },{ + "color":11, + "uvs":[0.46875,0.625,0.59375,0.625,0.59375,0.75,0.46875,0.75], + "vertex_ids":[168,172,173,169] + },{ + "color":11, + "uvs":[0.5859375,0.625,0.5859375,0.75,0.4609375,0.75,0.4609375,0.625], + "vertex_ids":[170,169,173,174] + },{ + "color":11, + "uvs":[0.46875,0.625,0.59375,0.625,0.59375,0.75,0.46875,0.75], + "vertex_ids":[175,176,177,178] + },{ + "color":11, + "uvs":[0.4609375,0.625,0.5859375,0.625,0.5859375,0.75,0.4609375,0.75], + "vertex_ids":[180,179,182,181] + },{ + "color":11, + "uvs":[0.59375,0.625,0.59375,0.75,0.46875,0.75,0.46875,0.625], + "vertex_ids":[179,180,176,175] + },{ + "color":11, + "uvs":[0.46875,0.625,0.59375,0.625,0.59375,0.75,0.46875,0.75], + "vertex_ids":[179,175,178,182] + },{ + "color":11, + "uvs":[0.46875,0.625,0.59375,0.625,0.59375,0.75,0.46875,0.75], + "vertex_ids":[176,180,181,177] + },{ + "color":11, + "uvs":[0.5859375,0.625,0.5859375,0.75,0.4609375,0.75,0.4609375,0.625], + "vertex_ids":[178,177,181,182] + },{ + "color":11, + "uvs":[0.46875,0.625,0.59375,0.625,0.59375,0.75,0.46875,0.75], + "vertex_ids":[183,184,185,186] + },{ + "color":11, + "uvs":[0.4609375,0.625,0.5859375,0.625,0.5859375,0.75,0.4609375,0.75], + "vertex_ids":[188,187,190,189] + },{ + "color":11, + "uvs":[0.59375,0.625,0.59375,0.75,0.46875,0.75,0.46875,0.625], + "vertex_ids":[187,188,184,183] + },{ + "color":11, + "uvs":[0.46875,0.625,0.59375,0.625,0.59375,0.75,0.46875,0.75], + "vertex_ids":[187,183,186,190] + },{ + "color":11, + "uvs":[0.46875,0.625,0.59375,0.625,0.59375,0.75,0.46875,0.75], + "vertex_ids":[184,188,189,185] + },{ + "color":11, + "uvs":[0.5859375,0.625,0.5859375,0.75,0.4609375,0.75,0.4609375,0.625], + "vertex_ids":[186,185,189,190] + }] + }, + "locked":true, + "transform":{ + "scale":{ + "x":1.25, + "y":1.25, + "z":1.25 + }, + "pos":{ + "x":0, + "y":3.25, + "z":-1.5 + }, + "rot":{ + "x":0.78539816339745, + "y":-0, + "z":0 + } + } + },{ + "ghost":false, + "open":true, + "children":[], + "visible":true, + "name":"rod.1", + "motions":{ + "tracks":[[],[],[],[]] + }, + "mesh":{ + "vertices":[0.125,3.75,-0.125,0.125,-1,-0.125,-0.125,-1,-0.125,-0.125,3.75,-0.125,0.125,3.75,0.125,0.125,-1,0.125,-0.125,-1,0.125,-0.125,3.75,0.125], + "name":"cube..18", + "faces":[{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[1,2,3,4] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[6,5,8,7] + },{ + "color":11, + "uvs":[0.53125,0.65625,0.53125,0.78125,0.40625,0.78125,0.40625,0.65625], + "vertex_ids":[5,6,2,1] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[5,1,4,8] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[2,6,7,3] + },{ + "color":11, + "uvs":[0.5,0.65625,0.5,0.78125,0.375,0.78125,0.375,0.65625], + "vertex_ids":[4,3,7,8] + }] + }, + "locked":true, + "transform":{ + "scale":{ + "x":1, + "y":1, + "z":1 + }, + "pos":{ + "x":0, + "y":-0.0703125, + "z":-1.71875 + }, + "rot":{ + "x":0, + "y":-0, + "z":0 + } + } + },{ + "ghost":false, + "open":false, + "children":[], + "visible":true, + "name":"rod.2", + "motions":{ + "tracks":[[],[],[],[]] + }, + "mesh":{ + "vertices":[0.125,1.75,0.125,0.125,-1.25,0.125,-0.125,-1.25,0.125,-0.125,1.75,0.125,0.125,1.75,0.375,0.125,-1.25,0.375,-0.125,-1.25,0.375,-0.125,1.75,0.375], + "name":"cube..16", + "faces":[{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[1,2,3,4] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[6,5,8,7] + },{ + "color":11, + "uvs":[0.53125,0.65625,0.53125,0.78125,0.40625,0.78125,0.40625,0.65625], + "vertex_ids":[5,6,2,1] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[5,1,4,8] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[2,6,7,3] + },{ + "color":11, + "uvs":[0.5,0.65625,0.5,0.78125,0.375,0.78125,0.375,0.65625], + "vertex_ids":[4,3,7,8] + }] + }, + "locked":true, + "transform":{ + "scale":{ + "x":1, + "y":1, + "z":1 + }, + "pos":{ + "x":0, + "y":0.4921875, + "z":1.7734375 + }, + "rot":{ + "x":0, + "y":-0, + "z":0 + } + } + }], + "visible":true, + "name":"stringers", + "motions":{ + "tracks":[[],[],[],[]] + }, + "folder":true, + "locked":true, + "transform":{ + "scale":{ + "x":1, + "y":1, + "z":1 + }, + "pos":{ + "x":0, + "y":0, + "z":0 + }, + "rot":{ + "x":0, + "y":0, + "z":0 + } + } + },{ + "ghost":false, + "open":false, + "children":[{ + "ghost":false, + "open":false, + "children":[], + "visible":true, + "name":"deflect the rain", + "motions":{ + "tracks":[[],[],[],[]] + }, + "mesh":{ + "vertices":[-0.099609374999999,4.20703125,-2.0625,-0.287109375,4.39453125,-2.0625,-0.287109375,4.58203125,-2.0625,-0.099609374999999,4.76953125,-2.0625,0.087890625000001,4.76953125,-2.0625,0.275390625,4.58203125,-2.0625,0.275390625,4.39453125,-2.0625,0.087890625000001,4.20703125,-2.0625,-0.099609375000005,4.20703125,-0.5,-0.28710937500001,4.39453125,-0.5,-0.28710937500001,4.58203125,-0.5,-0.099609375000005,4.76953125,-0.5,0.087890624999995,4.76953125,-0.5,0.27539062499999,4.58203125,-0.5,0.27539062499999,4.39453125,-0.5,0.087890624999995,4.20703125,-0.5,-0.099609375000002,4.20703125,0.625,-0.287109375,4.39453125,0.625,-0.287109375,4.58203125,0.625,-0.099609375000002,4.76953125,0.625,0.087890624999998,4.76953125,0.625,0.275390625,4.58203125,0.625,0.275390625,4.39453125,0.625,0.087890624999998,4.20703125,0.625,-0.5,5,2,-0.5,4,2,0.5,4,2,0.5,5,2,-0.25,4.75,1.5,-0.25,4.25,1.5,0.25,4.25,1.5,0.25,4.75,1.5,-0.29296875,4.775390625,-2.056640625,0.26953125,4.775390625,-2.056640625,0.26953125,4.775390625,-2.619140625,-0.29296875,4.775390625,-2.619140625,-0.29296875,4.212890625,-2.056640625,0.26953125,4.212890625,-2.056640625,0.26953125,4.212890625,-2.619140625,-0.29296875,4.212890625,-2.619140625,-0.29296875,4.4230655897141,-2.2936487670614,0.26953125,4.4230655897141,-2.2936487670614,0.26953125,4.4230655897141,-2.6184082934805,-0.29296875,4.4230655897141,-2.6184082934805,-0.29296875,3.7484263000853,-2.5748987670614,0.26953125,3.7484263000853,-2.5748987670614,0.26953125,3.9359263000853,-2.8996582934805,-0.29296875,3.9359263000853,-2.8996582934805,-0.75,2.25,0.5,-2.25,3.75,0.49999999999999,-2.25,5.25,0.49999999999999,-0.75,6.75,0.5,0.75,6.75,0.5,2.25,5.25,0.50000000000001,2.25,3.75,0.50000000000001,0.75,2.25,0.5,-0.75,2.5,1,-2,3.75,0.99999999999999,-2,5.25,0.99999999999999,-0.75,6.5,1,0.75,6.5,1,2,5.25,1,2,3.75,1,0.75,2.5,1,0.75,3.5,1.5,1,3.75,1.5,1,5.25,1.5,0.75,5.5,1.5,-0.75,5.5,1.5,-1,5.25,1.5,-1,3.75,1.5,-0.75,3.5,1.5], + "name":"deflect the rain", + "faces":[{ + "color":10, + "uvs":[0.6875,0.59375,0.65625,0.5625,0.65625,0.5,0.6875,0.46875,0.75,0.46875,0.78125,0.5,0.78125,0.5625,0.75,0.59375], + "vertex_ids":[1,2,3,4,5,6,7,8] + },{ + "color":10, + "uvs":[0.6875,0.59375,0.65625,0.5625,0.65625,0.5,0.6875,0.46875,0.75,0.46875,0.78125,0.5,0.78125,0.5625,0.75,0.59375], + "vertex_ids":[16,15,14,13,12,11,10,9] + },{ + "color":10, + "uvs":[0.78125,0.46875,0.78125,0.59375,0.65625,0.59375,0.65625,0.46875], + "vertex_ids":[1,9,10,2] + },{ + "color":10, + "uvs":[0.78125,0.46875,0.78125,0.59375,0.65625,0.59375,0.65625,0.46875], + "vertex_ids":[2,10,11,3] + },{ + "color":10, + "uvs":[0.78125,0.46875,0.78125,0.59375,0.65625,0.59375,0.65625,0.46875], + "vertex_ids":[3,11,12,4] + },{ + "color":10, + "uvs":[0.78125,0.46875,0.78125,0.59375,0.65625,0.59375,0.65625,0.46875], + "vertex_ids":[4,12,13,5] + },{ + "color":10, + "uvs":[0.78125,0.46875,0.78125,0.59375,0.65625,0.59375,0.65625,0.46875], + "vertex_ids":[5,13,14,6] + },{ + "color":10, + "uvs":[0.78125,0.46875,0.78125,0.59375,0.65625,0.59375,0.65625,0.46875], + "vertex_ids":[6,14,15,7] + },{ + "color":10, + "uvs":[0.78125,0.46875,0.78125,0.59375,0.65625,0.59375,0.65625,0.46875], + "vertex_ids":[7,15,16,8] + },{ + "color":10, + "uvs":[0.78125,0.46875,0.78125,0.59375,0.65625,0.59375,0.65625,0.46875], + "vertex_ids":[8,16,9,1] + },{ + "color":10, + "uvs":[0.875,0.78125,0.84375,0.75,0.84375,0.6875,0.875,0.65625,0.9375,0.65625,0.96875,0.6875,0.96875,0.75,0.9375,0.78125], + "vertex_ids":[9,10,11,12,13,14,15,16] + },{ + "color":10, + "uvs":[0.78125,0.125,0.75,0.09375,0.75,0.03125,0.78125,0,0.84375,0,0.875,0.03125,0.875,0.09375,0.84375,0.125], + "vertex_ids":[24,23,22,21,20,19,18,17] + },{ + "color":10, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[9,17,18,10] + },{ + "color":10, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[10,18,19,11] + },{ + "color":10, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[11,19,20,12] + },{ + "color":10, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[12,20,21,13] + },{ + "color":10, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[13,21,22,14] + },{ + "color":10, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[14,22,23,15] + },{ + "color":10, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[15,23,24,16] + },{ + "color":10, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[16,24,17,9] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[25,26,27,28] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[30,29,32,31] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[29,30,26,25] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[29,25,28,32] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[26,30,31,27] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[28,27,31,32] + },{ + "color":11, + "uvs":[0.4375,0.65625,0.5625,0.65625,0.5625,0.78125,0.4375,0.78125], + "vertex_ids":[33,34,35,36] + },{ + "color":11, + "uvs":[0.4375,0.65625,0.5625,0.65625,0.5625,0.78125,0.4375,0.78125], + "vertex_ids":[38,37,40,39] + },{ + "color":11, + "uvs":[0.5625,0.65625,0.5625,0.78125,0.4375,0.78125,0.4375,0.65625], + "vertex_ids":[37,38,34,33] + },{ + "color":11, + "uvs":[0.40625,0.65625,0.53125,0.65625,0.53125,0.78125,0.40625,0.78125], + "vertex_ids":[37,33,36,40] + },{ + "color":11, + "uvs":[0.4375,0.65625,0.5625,0.65625,0.5625,0.78125,0.4375,0.78125], + "vertex_ids":[34,38,39,35] + },{ + "color":11, + "uvs":[0.53125,0.65625,0.53125,0.78125,0.40625,0.78125,0.40625,0.65625], + "vertex_ids":[36,35,39,40] + },{ + "color":11, + "uvs":[0.4375,0.65625,0.5625,0.65625,0.5625,0.78125,0.4375,0.78125], + "vertex_ids":[41,42,43,44] + },{ + "color":11, + "uvs":[0.4375,0.65625,0.5625,0.65625,0.5625,0.78125,0.4375,0.78125], + "vertex_ids":[46,45,48,47] + },{ + "color":11, + "uvs":[0.5625,0.65625,0.5625,0.78125,0.4375,0.78125,0.4375,0.65625], + "vertex_ids":[45,46,42,41] + },{ + "color":11, + "uvs":[0.40625,0.65625,0.53125,0.65625,0.53125,0.78125,0.40625,0.78125], + "vertex_ids":[45,41,44,48] + },{ + "color":11, + "uvs":[0.4375,0.65625,0.5625,0.65625,0.5625,0.78125,0.4375,0.78125], + "vertex_ids":[42,46,47,43] + },{ + "color":11, + "uvs":[0.53125,0.65625,0.53125,0.78125,0.40625,0.78125,0.40625,0.65625], + "vertex_ids":[44,43,47,48] + },{ + "color":15, + "uvs":[0.6875,0.78125,0.65625,0.75,0.65625,0.6875,0.6875,0.65625,0.75,0.65625,0.78125,0.6875,0.78125,0.75,0.75,0.78125], + "vertex_ids":[49,50,51,52,53,54,55,56] + },{ + "color":15, + "uvs":[0.6875,0.78125,0.65625,0.75,0.65625,0.6875,0.6875,0.65625,0.75,0.65625,0.78125,0.6875,0.78125,0.75,0.75,0.78125], + "vertex_ids":[65,66,67,68,69,70,71,72] + },{ + "color":15, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[49,57,58,50] + },{ + "color":15, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[50,58,59,51] + },{ + "color":15, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[51,59,60,52] + },{ + "color":15, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[52,60,61,53] + },{ + "color":15, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[53,61,62,54] + },{ + "color":15, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[54,62,63,55] + },{ + "color":15, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[55,63,64,56] + },{ + "color":15, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[56,64,57,49] + },{ + "color":15, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[65,64,63,66] + },{ + "color":15, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[66,63,62,67] + },{ + "color":15, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[67,62,61,68] + },{ + "color":15, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[68,61,60,69] + },{ + "color":15, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[69,60,59,70] + },{ + "color":15, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[70,59,58,71] + },{ + "color":15, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[71,58,57,72] + },{ + "color":15, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[72,57,64,65] + }] + }, + "locked":true, + "transform":{ + "scale":{ + "x":1.25, + "y":1.25, + "z":1.25 + }, + "pos":{ + "x":0, + "y":-1.359375, + "z":1.8125 + }, + "rot":{ + "x":-0.26179938779915, + "y":-0, + "z":0 + } + } + },{ + "ghost":false, + "open":true, + "children":[], + "visible":true, + "name":"rod.1", + "motions":{ + "tracks":[[],[],[],[]] + }, + "mesh":{ + "vertices":[0.125,3.75,-0.125,0.125,-1,-0.125,-0.125,-1,-0.125,-0.125,3.75,-0.125,0.125,3.75,0.125,0.125,-1,0.125,-0.125,-1,0.125,-0.125,3.75,0.125], + "name":"cube...19", + "faces":[{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[1,2,3,4] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[6,5,8,7] + },{ + "color":11, + "uvs":[0.53125,0.65625,0.53125,0.78125,0.40625,0.78125,0.40625,0.65625], + "vertex_ids":[5,6,2,1] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[5,1,4,8] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[2,6,7,3] + },{ + "color":11, + "uvs":[0.5,0.65625,0.5,0.78125,0.375,0.78125,0.375,0.65625], + "vertex_ids":[4,3,7,8] + }] + }, + "locked":true, + "transform":{ + "scale":{ + "x":1, + "y":1, + "z":1 + }, + "pos":{ + "x":0, + "y":-0.1640625, + "z":-1.2265625 + }, + "rot":{ + "x":0, + "y":-0, + "z":0 + } + } + }], + "visible":true, + "name":"brellas", + "motions":{ + "tracks":[[],[],[],[]] + }, + "folder":true, + "locked":true, + "transform":{ + "scale":{ + "x":1, + "y":1, + "z":1 + }, + "pos":{ + "x":0, + "y":0, + "z":0 + }, + "rot":{ + "x":0, + "y":0, + "z":0 + } + } + },{ + "ghost":false, + "open":false, + "children":[{ + "ghost":false, + "open":false, + "children":[], + "visible":true, + "name":"EXPLOSION", + "motions":{ + "tracks":[[],[],[],[]] + }, + "mesh":{ + "vertices":[0.375,4.453125,1.9375,0.125,4.203125,1.9375,-0.125,4.203125,1.9375,-0.375,4.453125,1.9375,-0.375,4.703125,1.9375,-0.125,4.953125,1.9375,0.125,4.953125,1.9375,0.375,4.703125,1.9375,0.25,4.453125,2.2791175075414,0.125,4.328125,2.2791175075414,-0.125,4.328125,2.2791175075414,-0.25,4.453125,2.2791175075414,-0.25,4.703125,2.2791175075414,-0.125,4.828125,2.2791175075414,0.125,4.828125,2.2791175075414,0.25,4.703125,2.2791175075414,0.78969057052349,4.0703125,0.3125,0.3515625,3.6321844294765,0.3125,-0.3984375,3.6321844294765,0.3125,-0.83656557052349,4.0703125,0.3125,-0.83656557052349,4.8203125,0.3125,-0.3984375,5.2584405705235,0.3125,0.3515625,5.2584405705235,0.3125,0.78969057052349,4.8203125,0.3125,0.78969057052349,4.0703125,1.9375,0.3515625,3.6321844294765,1.9375,-0.3984375,3.6321844294765,1.9375,-0.83656557052349,4.0703125,1.9375,-0.83656557052349,4.8203125,1.9375,-0.3984375,5.2584405705235,1.9375,0.3515625,5.2584405705235,1.9375,0.78969057052349,4.8203125,1.9375,-0.90625,3.1463990388911,0,-0.90625,4.8359375,0,-0.40625,5.3359375,5.5511151231258e-17,0.34375,5.3359375,5.5511151231258e-17,0.84375,4.8359375,5.5511151231258e-17,0.84375,3.1463990388911,5.5511151231258e-17,-0.90625,3.3452324228125,0.5,-0.90625,4.8359375,0.5,-0.40625,5.3359375,0.5,0.34375,5.3359375,0.5,0.84375,4.8359375,0.5,0.84375,3.3452324228125,0.5,0.59375,2.5229293741138,1.2680757621747,0.59375,2.8452324228125,1.5,-0.65625,2.8452324228125,1.5,-0.65625,2.5229293741138,1.2680757621747,0.1171875,4.1072214900304,-1.1854975524035,0.1171875,3.9304447947338,-1.0087208571068,-0.1328125,3.9304447947338,-1.0087208571068,-0.1328125,4.1072214900304,-1.1854975524035,0.1171875,4.3875515759203,-0.90516746651357,0.1171875,4.2107748806237,-0.72839077121694,-0.1328125,4.2107748806237,-0.72839077121694,-0.1328125,4.3875515759203,-0.90516746651357,0.1171875,4.3875515759203,-0.5516140759203,0.1171875,4.5643282712169,-0.72839077121694,-0.1328125,4.5643282712169,-0.72839077121694,-0.1328125,4.3875515759203,-0.5516140759203,-0.1328125,4.2107748806237,-0.37483738062366,-0.1328125,4.033998185327,-0.5516140759203,0.1171875,4.033998185327,-0.5516140759203,0.1171875,4.2107748806237,-0.37483738062366,0.1171875,4.3875515759203,-0.19806068532702,0.1171875,4.5643282712169,-0.37483738062366,-0.1328125,4.5643282712169,-0.37483738062366,-0.1328125,4.3875515759203,-0.19806068532702,-0.1328125,4.2107748806237,-0.021283990030388,-0.1328125,4.033998185327,-0.19806068532702,0.1171875,4.033998185327,-0.19806068532702,0.1171875,4.2107748806237,-0.021283990030388,0.1171875,4.268982086548,0.036923215893908,0.1171875,4.6002304886913,0.035816206311334,-0.1328125,4.6002304886913,0.035816206311334,-0.1328125,4.268982086548,0.036923215893908,0.1171875,4.8671875,-0.75,0.1171875,4.6171875,-0.75,-0.1328125,4.6171875,-0.75,-0.1328125,4.8671875,-0.75,0.1171875,4.8671875,0,0.1171875,4.6171875,0,-0.1328125,4.6171875,0,-0.1328125,4.8671875,0,0.5,4,-1,0.5,3.5,-1,-0.5,3.5,-1,-0.5,4,-1,0.5,4,0,0.5,3.5,0,-0.5,3.5,0,-0.5,4,0,-0.75,3.6634836962622,-1.4992120477131,-0.75,4.8623724356958,-1.1738658905933,-0.25,5.3453353488403,-1.044456368042,0.25,5.3453353488403,-1.044456368042,0.75,4.8623724356958,-1.1738658905933,0.75,3.6634836962622,-1.4992120477131,-0.75,3.4693694124353,-1.029006226057,-0.75,4.6682581518689,-0.69942152087647,-0.25,5.1512210650134,-0.57001199832521,0.25,5.1512210650134,-0.57001199832521,0.75,4.6682581518689,-0.69942152087648,0.75,3.4693694124353,-1.029006226057,0.75,3,-1.5703125,0.75,3,-1.0116686375267,-0.75,3,-1.0116686375267,-0.75,3,-1.5703125,0.75,2.5,-1.5703125,0.75,2.5,-0.7225727292112,-0.75,2.5,-0.72257272921119,-0.75,2.5,-1.5703125,0.29131451350563,3.9832323105531,-1.5706171727253,-0.29131451350563,3.9832323105531,-1.5706171727253,-0.57327156612105,4.2555819095787,-1.4976413176075,-0.57327156612105,4.8019992851992,-1.3512292230796,-0.29131451350563,5.0743488842248,-1.2782533679618,0.29131451350563,5.0743488842248,-1.2782533679618,0.57327156612105,4.8019992851992,-1.3512292230796,0.57327156612105,4.2555819095787,-1.4976413176075,0.29131451350563,3.9444094537877,-1.425728298782,-0.29131451350563,3.9444094537877,-1.425728298782,-0.57327156612105,4.2167590528133,-1.3527524436641,-0.57327156612105,4.7631764284338,-1.2063403491363,-0.29131451350563,5.0355260274594,-1.1333644940184,0.29131451350563,5.0355260274594,-1.1333644940184,0.57327156612105,4.7631764284338,-1.2063403491363,0.57327156612105,4.2167590528133,-1.3527524436641,-0.3125,3.8788189422817,-2.6209298785876,-0.9375,4.4825225837123,-2.4591679753986,-0.9375,5.086226225143,-2.2974060722095,-0.3125,5.6899298665737,-2.1356441690204,0.3125,5.6899298665737,-2.1356441690204,0.9375,5.086226225143,-2.2974060722095,0.9375,4.4825225837123,-2.4591679753986,0.3125,3.8788189422817,-2.6209298785876,-0.3125,3.814114181006,-2.3794484220154,-0.9375,4.4178178224367,-2.2176865188263,-0.9375,5.0215214638674,-2.0559246156372,-0.3125,5.625225105298,-1.8941627124481,0.3125,5.625225105298,-1.8941627124481,0.9375,5.0215214638674,-2.0559246156372,0.9375,4.4178178224367,-2.2176865188263,0.3125,3.814114181006,-2.3794484220154,-0.25,4.1933836048419,-3.0704568118112,-0.75,4.6763465179864,-2.9410472892599,-0.75,5.1593094311309,-2.8116377667087,-0.25,5.6422723442755,-2.6822282441574,0.25,5.6422723442755,-2.6822282441574,0.75,5.1593094311309,-2.8116377667087,0.75,4.6763465179864,-2.9410472892599,0.25,4.1933836048419,-3.0704568118112,-0.25,3.8698597984637,-1.8630495289499,-0.75,4.3528227116082,-1.7336400063986,-0.75,4.8357856247528,-1.6042304838474,-0.25,5.3187485378973,-1.4748209612961,0.25,5.3187485378973,-1.4748209612961,0.75,4.8357856247528,-1.6042304838474,0.75,4.3528227116082,-1.7336400063986,0.25,3.8698597984637,-1.8630495289499,0.25,4.0466364937604,-1.556863311102,0.5,4.2881179503326,-1.4921585498263,0.5,4.7710808634772,-1.3627490272751,0.25,5.0125623200494,-1.2980442659995,-0.25,5.0125623200494,-1.2980442659995,-0.5,4.7710808634772,-1.3627490272751,-0.5,4.2881179503326,-1.4921585498263,-0.25,4.0466364937604,-1.556863311102,-0.25,4.4995698226898,-3.2472335071078,-0.5,4.741051279262,-3.1825287458322,-0.5,5.2240141924066,-3.053119223281,-0.25,5.4654956489788,-2.9884144620053,0.25,5.4654956489788,-2.9884144620053,0.5,5.2240141924066,-3.053119223281,0.5,4.741051279262,-3.1825287458322,0.25,4.4995698226898,-3.2472335071078,0.29131451350563,4.4745840914899,-3.404366983571,-0.29131451350563,4.4745840914899,-3.404366983571,-0.57327156612105,4.7469336905155,-3.3313911284531,-0.57327156612105,5.293351066136,-3.1849790339253,-0.29131451350563,5.5657006651616,-3.1120031788074,0.29131451350563,5.5657006651616,-3.1120031788074,0.57327156612105,5.293351066136,-3.1849790339253,0.57327156612105,4.7469336905155,-3.3313911284531,0.29131451350563,4.4357612347245,-3.2594781096276,-0.29131451350563,4.4357612347245,-3.2594781096276,-0.57327156612105,4.7081108337501,-3.1865022545098,-0.57327156612105,5.2545282093706,-3.0400901599819,-0.29131451350563,5.5268778083962,-2.9671143048641,0.29131451350563,5.5268778083962,-2.9671143048641,0.57327156612105,5.2545282093706,-3.0400901599819,0.57327156612105,4.7081108337501,-3.1865022545098], + "name":"EXPLOSION", + "faces":[{ + "color":10, + "uvs":[0.78125,0.125,0.75,0.09375,0.75,0.03125,0.78125,0,0.84375,0,0.875,0.03125,0.875,0.09375,0.84375,0.125], + "vertex_ids":[1,2,3,4,5,6,7,8] + },{ + "color":10, + "uvs":[0.78125,0.125,0.75,0.09375,0.75,0.03125,0.78125,0,0.84375,0,0.875,0.03125,0.875,0.09375,0.84375,0.125], + "vertex_ids":[16,15,14,13,12,11,10,9] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[1,9,10,2] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[2,10,11,3] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[3,11,12,4] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[4,12,13,5] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[5,13,14,6] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[6,14,15,7] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[7,15,16,8] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[8,16,9,1] + },{ + "color":10, + "uvs":[0.78125,0.125,0.75,0.09375,0.75,0.03125,0.78125,0,0.84375,0,0.875,0.03125,0.875,0.09375,0.84375,0.125], + "vertex_ids":[17,18,19,20,21,22,23,24] + },{ + "color":10, + "uvs":[0.3125,0.4375,0.34375,0.40625,0.40625,0.40625,0.4375,0.4375,0.4375,0.5,0.40625,0.53125,0.34375,0.53125,0.3125,0.5], + "vertex_ids":[32,31,30,29,28,27,26,25] + },{ + "color":10, + "uvs":[0.6875,0.25,0.9375,0.25,0.9375,0.34375,0.6875,0.34375], + "vertex_ids":[17,25,26,18] + },{ + "color":10, + "uvs":[0.6875,0.25,0.9375,0.25,0.9375,0.34375,0.6875,0.34375], + "vertex_ids":[18,26,27,19] + },{ + "color":10, + "uvs":[0.6875,0.25,0.9375,0.25,0.9375,0.34375,0.6875,0.34375], + "vertex_ids":[19,27,28,20] + },{ + "color":10, + "uvs":[0.6875,0.25,0.9375,0.25,0.9375,0.34375,0.6875,0.34375], + "vertex_ids":[20,28,29,21] + },{ + "color":10, + "uvs":[0.6875,0.25,0.9375,0.25,0.9375,0.34375,0.6875,0.34375], + "vertex_ids":[21,29,30,22] + },{ + "color":10, + "uvs":[0.6875,0.25,0.9375,0.25,0.9375,0.34375,0.6875,0.34375], + "vertex_ids":[22,30,31,23] + },{ + "color":10, + "uvs":[0.6875,0.25,0.9375,0.25,0.9375,0.34375,0.6875,0.34375], + "vertex_ids":[23,31,32,24] + },{ + "color":10, + "uvs":[0.6875,0.25,0.9375,0.25,0.9375,0.34375,0.6875,0.34375], + "vertex_ids":[24,32,25,17] + },{ + "color":10, + "uvs":[0.5,0.75,0.46875,0.71875,0.46875,0.65625,0.5,0.625,0.5625,0.625,0.59375,0.65625,0.59375,0.71875,0.5625,0.75], + "vertex_ids":[33,33,34,35,36,37,38,38] + },{ + "color":10, + "uvs":[0.5,0.75,0.46875,0.71875,0.46875,0.65625,0.5,0.625,0.5625,0.625,0.59375,0.65625,0.59375,0.71875,0.5625,0.75], + "vertex_ids":[44,44,43,42,41,40,39,39] + },{ + "color":10, + "uvs":[0.59375,0.625,0.59375,0.75,0.46875,0.75,0.46875,0.625], + "vertex_ids":[33,39,39,33] + },{ + "color":10, + "uvs":[0.59375,0.625,0.59375,0.75,0.46875,0.75,0.46875,0.625], + "vertex_ids":[33,39,40,34] + },{ + "color":10, + "uvs":[0.59375,0.625,0.59375,0.75,0.46875,0.75,0.46875,0.625], + "vertex_ids":[34,40,41,35] + },{ + "color":10, + "uvs":[0.59375,0.625,0.59375,0.75,0.46875,0.75,0.46875,0.625], + "vertex_ids":[35,41,42,36] + },{ + "color":10, + "uvs":[0.59375,0.625,0.59375,0.75,0.46875,0.75,0.46875,0.625], + "vertex_ids":[36,42,43,37] + },{ + "color":10, + "uvs":[0.59375,0.625,0.59375,0.75,0.46875,0.75,0.46875,0.625], + "vertex_ids":[37,43,44,38] + },{ + "color":10, + "uvs":[0.59375,0.625,0.59375,0.75,0.46875,0.75,0.46875,0.625], + "vertex_ids":[38,44,44,38] + },{ + "color":10, + "uvs":[0.59375,0.625,0.59375,0.75,0.46875,0.75,0.46875,0.625], + "vertex_ids":[45,46,47,48] + },{ + "color":10, + "uvs":[0.59375,0.625,0.59375,0.75,0.46875,0.75,0.46875,0.625], + "vertex_ids":[45,38,44,46] + },{ + "color":10, + "uvs":[0.59375,0.625,0.59375,0.75,0.46875,0.75,0.46875,0.625], + "vertex_ids":[46,44,39,47] + },{ + "color":10, + "uvs":[0.59375,0.625,0.59375,0.75,0.46875,0.75,0.46875,0.625], + "vertex_ids":[47,39,33,48] + },{ + "color":10, + "uvs":[0.59375,0.625,0.59375,0.75,0.46875,0.75,0.46875,0.625], + "vertex_ids":[48,33,38,45] + },{ + "color":11, + "uvs":[0.4609375,0.625,0.5859375,0.625,0.5859375,0.75,0.4609375,0.75], + "vertex_ids":[49,50,51,52] + },{ + "color":11, + "uvs":[0.46875,0.625,0.59375,0.625,0.59375,0.75,0.46875,0.75], + "vertex_ids":[57,58,59,60] + },{ + "color":11, + "uvs":[0.59375,0.625,0.59375,0.75,0.46875,0.75,0.46875,0.625], + "vertex_ids":[53,54,50,49] + },{ + "color":11, + "uvs":[0.46875,0.6171875,0.59375,0.6171875,0.59375,0.7421875,0.46875,0.7421875], + "vertex_ids":[53,49,52,56] + },{ + "color":11, + "uvs":[0.46875,0.625,0.59375,0.625,0.59375,0.75,0.46875,0.75], + "vertex_ids":[50,54,55,51] + },{ + "color":11, + "uvs":[0.5859375,0.625,0.5859375,0.75,0.4609375,0.75,0.4609375,0.625], + "vertex_ids":[52,51,55,56] + },{ + "color":11, + "uvs":[0.46875,0.625,0.59375,0.625,0.59375,0.75,0.46875,0.75], + "vertex_ids":[57,54,53,58] + },{ + "color":11, + "uvs":[0.46875,0.625,0.59375,0.625,0.59375,0.75,0.46875,0.75], + "vertex_ids":[58,53,56,59] + },{ + "color":11, + "uvs":[0.46875,0.625,0.59375,0.625,0.59375,0.75,0.46875,0.75], + "vertex_ids":[59,56,55,60] + },{ + "color":11, + "uvs":[0.46875,0.625,0.59375,0.625,0.59375,0.75,0.46875,0.75], + "vertex_ids":[61,62,63,64] + },{ + "color":11, + "uvs":[0.46875,0.625,0.59375,0.625,0.59375,0.75,0.46875,0.75], + "vertex_ids":[61,60,55,62] + },{ + "color":11, + "uvs":[0.46875,0.625,0.59375,0.625,0.59375,0.75,0.46875,0.75], + "vertex_ids":[62,55,54,63] + },{ + "color":11, + "uvs":[0.46875,0.625,0.59375,0.625,0.59375,0.75,0.46875,0.75], + "vertex_ids":[63,54,57,64] + },{ + "color":11, + "uvs":[0.46875,0.625,0.59375,0.625,0.59375,0.75,0.46875,0.75], + "vertex_ids":[65,66,67,68] + },{ + "color":11, + "uvs":[0.46875,0.625,0.59375,0.625,0.59375,0.75,0.46875,0.75], + "vertex_ids":[65,64,57,66] + },{ + "color":11, + "uvs":[0.46875,0.625,0.59375,0.625,0.59375,0.75,0.46875,0.75], + "vertex_ids":[66,57,60,67] + },{ + "color":11, + "uvs":[0.46875,0.625,0.59375,0.625,0.59375,0.75,0.46875,0.75], + "vertex_ids":[67,60,61,68] + },{ + "color":11, + "uvs":[0.46875,0.625,0.59375,0.625,0.59375,0.75,0.46875,0.75], + "vertex_ids":[69,70,71,72] + },{ + "color":11, + "uvs":[0.46875,0.625,0.59375,0.625,0.59375,0.75,0.46875,0.75], + "vertex_ids":[69,68,61,70] + },{ + "color":11, + "uvs":[0.46875,0.625,0.59375,0.625,0.59375,0.75,0.46875,0.75], + "vertex_ids":[70,61,64,71] + },{ + "color":11, + "uvs":[0.46875,0.625,0.59375,0.625,0.59375,0.75,0.46875,0.75], + "vertex_ids":[71,64,65,72] + },{ + "color":11, + "uvs":[0.46875,0.625,0.59375,0.625,0.59375,0.75,0.46875,0.75], + "vertex_ids":[73,74,75,76] + },{ + "color":11, + "uvs":[0.46875,0.625,0.59375,0.625,0.59375,0.75,0.46875,0.75], + "vertex_ids":[73,72,65,74] + },{ + "color":11, + "uvs":[0.46875,0.625,0.59375,0.625,0.59375,0.75,0.46875,0.75], + "vertex_ids":[74,65,68,75] + },{ + "color":11, + "uvs":[0.46875,0.625,0.59375,0.625,0.59375,0.75,0.46875,0.75], + "vertex_ids":[75,68,69,76] + },{ + "color":11, + "uvs":[0.46875,0.625,0.59375,0.625,0.59375,0.75,0.46875,0.75], + "vertex_ids":[76,69,72,73] + },{ + "color":11, + "uvs":[0.4609375,0.625,0.5859375,0.625,0.5859375,0.75,0.4609375,0.75], + "vertex_ids":[77,78,79,80] + },{ + "color":11, + "uvs":[0.46875,0.625,0.59375,0.625,0.59375,0.75,0.46875,0.75], + "vertex_ids":[82,81,84,83] + },{ + "color":11, + "uvs":[0.59375,0.625,0.59375,0.75,0.46875,0.75,0.46875,0.625], + "vertex_ids":[81,82,78,77] + },{ + "color":11, + "uvs":[0.46875,0.6171875,0.59375,0.6171875,0.59375,0.7421875,0.46875,0.7421875], + "vertex_ids":[81,77,80,84] + },{ + "color":11, + "uvs":[0.46875,0.625,0.59375,0.625,0.59375,0.75,0.46875,0.75], + "vertex_ids":[78,82,83,79] + },{ + "color":11, + "uvs":[0.5859375,0.625,0.5859375,0.75,0.4609375,0.75,0.4609375,0.625], + "vertex_ids":[80,79,83,84] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[85,86,87,88] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[90,89,92,91] + },{ + "color":11, + "uvs":[0.5,0,0.5,0.125,0.375,0.125,0.375,0], + "vertex_ids":[89,90,86,85] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[89,85,88,92] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[86,90,91,87] + },{ + "color":11, + "uvs":[0.5,0,0.5,0.125,0.375,0.125,0.375,0], + "vertex_ids":[88,87,91,92] + },{ + "color":10, + "uvs":[0.78125,0.125,0.75,0.09375,0.75,0.03125,0.78125,0,0.84375,0,0.875,0.03125,0.875,0.09375,0.84375,0.125], + "vertex_ids":[93,93,94,95,96,97,98,98] + },{ + "color":10, + "uvs":[0.78125,0.125,0.75,0.09375,0.75,0.03125,0.78125,0,0.84375,0,0.875,0.03125,0.875,0.09375,0.84375,0.125], + "vertex_ids":[104,104,103,102,101,100,99,99] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[93,99,99,93] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[93,99,100,94] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[94,100,101,95] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[95,101,102,96] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[96,102,103,97] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[97,103,104,98] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[98,104,104,98] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[109,110,111,112] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[105,98,104,106] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[106,104,99,107] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[107,99,93,108] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[108,93,98,105] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[109,105,106,110] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[110,106,107,111] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[111,107,108,112] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[112,108,105,109] + },{ + "color":10, + "uvs":[0.5,0.75,0.46875,0.71875,0.46875,0.65625,0.5,0.625,0.5625,0.625,0.59375,0.65625,0.59375,0.71875,0.5625,0.75], + "vertex_ids":[113,114,115,116,117,118,119,120] + },{ + "color":10, + "uvs":[0.5,0.75,0.46875,0.71875,0.46875,0.65625,0.5,0.625,0.5625,0.625,0.59375,0.65625,0.59375,0.71875,0.5625,0.75], + "vertex_ids":[128,127,126,125,124,123,122,121] + },{ + "color":10, + "uvs":[0.59375,0.625,0.59375,0.75,0.46875,0.75,0.46875,0.625], + "vertex_ids":[113,121,122,114] + },{ + "color":10, + "uvs":[0.59375,0.625,0.59375,0.75,0.46875,0.75,0.46875,0.625], + "vertex_ids":[114,122,123,115] + },{ + "color":10, + "uvs":[0.59375,0.625,0.59375,0.75,0.46875,0.75,0.46875,0.625], + "vertex_ids":[115,123,124,116] + },{ + "color":10, + "uvs":[0.59375,0.625,0.59375,0.75,0.46875,0.75,0.46875,0.625], + "vertex_ids":[116,124,125,117] + },{ + "color":10, + "uvs":[0.5625,0.625,0.5625,0.75,0.4375,0.75,0.4375,0.625], + "vertex_ids":[117,125,126,118] + },{ + "color":10, + "uvs":[0.59375,0.625,0.59375,0.75,0.46875,0.75,0.46875,0.625], + "vertex_ids":[118,126,127,119] + },{ + "color":10, + "uvs":[0.59375,0.625,0.59375,0.75,0.46875,0.75,0.46875,0.625], + "vertex_ids":[119,127,128,120] + },{ + "color":10, + "uvs":[0.59375,0.625,0.59375,0.75,0.46875,0.75,0.46875,0.625], + "vertex_ids":[120,128,121,113] + },{ + "color":10, + "uvs":[0.5,0.75,0.46875,0.71875,0.46875,0.65625,0.5,0.625,0.5625,0.625,0.59375,0.65625,0.59375,0.71875,0.5625,0.75], + "vertex_ids":[129,130,131,132,133,134,135,136] + },{ + "color":10, + "uvs":[0.5,0.75,0.46875,0.71875,0.46875,0.65625,0.5,0.625,0.5625,0.625,0.59375,0.65625,0.59375,0.71875,0.5625,0.75], + "vertex_ids":[144,143,142,141,140,139,138,137] + },{ + "color":10, + "uvs":[0.59375,0.625,0.59375,0.75,0.46875,0.75,0.46875,0.625], + "vertex_ids":[129,137,138,130] + },{ + "color":10, + "uvs":[0.59375,0.625,0.59375,0.75,0.46875,0.75,0.46875,0.625], + "vertex_ids":[130,138,139,131] + },{ + "color":10, + "uvs":[0.59375,0.625,0.59375,0.75,0.46875,0.75,0.46875,0.625], + "vertex_ids":[131,139,140,132] + },{ + "color":10, + "uvs":[0.59375,0.625,0.59375,0.75,0.46875,0.75,0.46875,0.625], + "vertex_ids":[132,140,141,133] + },{ + "color":10, + "uvs":[0.5625,0.625,0.5625,0.75,0.4375,0.75,0.4375,0.625], + "vertex_ids":[133,141,142,134] + },{ + "color":10, + "uvs":[0.59375,0.625,0.59375,0.75,0.46875,0.75,0.46875,0.625], + "vertex_ids":[134,142,143,135] + },{ + "color":10, + "uvs":[0.59375,0.625,0.59375,0.75,0.46875,0.75,0.46875,0.625], + "vertex_ids":[135,143,144,136] + },{ + "color":10, + "uvs":[0.59375,0.625,0.59375,0.75,0.46875,0.75,0.46875,0.625], + "vertex_ids":[136,144,137,129] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.65625,0.75,0.65625,0.6875,0.6875,0.65625,0.75,0.65625,0.78125,0.6875,0.78125,0.75,0.75,0.78125], + "vertex_ids":[169,170,171,172,173,174,175,176] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.65625,0.75,0.65625,0.6875,0.6875,0.65625,0.75,0.65625,0.78125,0.6875,0.78125,0.75,0.75,0.78125], + "vertex_ids":[161,162,163,164,165,166,167,168] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[145,153,154,146] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[146,154,155,147] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[147,155,156,148] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[148,156,157,149] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[149,157,158,150] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[150,158,159,151] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[151,159,160,152] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[152,160,153,145] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[161,160,159,162] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[162,159,158,163] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[163,158,157,164] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[164,157,156,165] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[165,156,155,166] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[166,155,154,167] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[167,154,153,168] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[168,153,160,161] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[169,145,146,170] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[170,146,147,171] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[171,147,148,172] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[172,148,149,173] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[173,149,150,174] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[174,150,151,175] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[175,151,152,176] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[176,152,145,169] + },{ + "color":10, + "uvs":[0.5,0.75,0.46875,0.71875,0.46875,0.65625,0.5,0.625,0.5625,0.625,0.59375,0.65625,0.59375,0.71875,0.5625,0.75], + "vertex_ids":[177,178,179,180,181,182,183,184] + },{ + "color":10, + "uvs":[0.5,0.75,0.46875,0.71875,0.46875,0.65625,0.5,0.625,0.5625,0.625,0.59375,0.65625,0.59375,0.71875,0.5625,0.75], + "vertex_ids":[192,191,190,189,188,187,186,185] + },{ + "color":10, + "uvs":[0.59375,0.625,0.59375,0.75,0.46875,0.75,0.46875,0.625], + "vertex_ids":[177,185,186,178] + },{ + "color":10, + "uvs":[0.59375,0.625,0.59375,0.75,0.46875,0.75,0.46875,0.625], + "vertex_ids":[178,186,187,179] + },{ + "color":10, + "uvs":[0.59375,0.625,0.59375,0.75,0.46875,0.75,0.46875,0.625], + "vertex_ids":[179,187,188,180] + },{ + "color":10, + "uvs":[0.59375,0.625,0.59375,0.75,0.46875,0.75,0.46875,0.625], + "vertex_ids":[180,188,189,181] + },{ + "color":10, + "uvs":[0.5625,0.625,0.5625,0.75,0.4375,0.75,0.4375,0.625], + "vertex_ids":[181,189,190,182] + },{ + "color":10, + "uvs":[0.59375,0.625,0.59375,0.75,0.46875,0.75,0.46875,0.625], + "vertex_ids":[182,190,191,183] + },{ + "color":10, + "uvs":[0.59375,0.625,0.59375,0.75,0.46875,0.75,0.46875,0.625], + "vertex_ids":[183,191,192,184] + },{ + "color":10, + "uvs":[0.59375,0.625,0.59375,0.75,0.46875,0.75,0.46875,0.625], + "vertex_ids":[184,192,185,177] + }] + }, + "locked":true, + "transform":{ + "scale":{ + "x":1.25, + "y":1.25, + "z":1.25 + }, + "pos":{ + "x":0, + "y":-0.671875, + "z":2.1484375 + }, + "rot":{ + "x":-0.26179938779915, + "y":-0, + "z":0 + } + } + },{ + "ghost":false, + "open":true, + "children":[], + "visible":true, + "name":"rod.1", + "motions":{ + "tracks":[[],[],[],[]] + }, + "mesh":{ + "vertices":[0.125,3.75,-0.375,0.125,-0.25,-0.375,-0.125,-0.25,-0.375,-0.125,3.75,-0.375,0.125,3.75,-0.125,0.125,-0.25,-0.125,-0.125,-0.25,-0.125,-0.125,3.75,-0.125,0.125,4,-0.125,0.125,4,-0.375,-0.125,4,-0.375,-0.125,4,-0.125,0.125,4,-0.125,0.125,3.75,-0.125,0.125,3.75,-0.375,0.125,4,-0.375], + "name":"cube....15", + "faces":[{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[1,2,3,4] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[6,5,8,7] + },{ + "color":11, + "uvs":[0.53125,0.65625,0.53125,0.78125,0.40625,0.78125,0.40625,0.65625], + "vertex_ids":[5,6,2,1] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[9,10,11,12] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[2,6,7,3] + },{ + "color":11, + "uvs":[0.5,0.65625,0.5,0.78125,0.375,0.78125,0.375,0.65625], + "vertex_ids":[4,3,7,8] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[13,14,15,16] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[10,1,4,11] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[11,4,8,12] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[12,8,5,9] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[13,9,5,14] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[14,5,1,15] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[15,1,10,16] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[16,10,9,13] + }] + }, + "locked":true, + "transform":{ + "scale":{ + "x":1, + "y":1, + "z":1 + }, + "pos":{ + "x":0, + "y":-0.1796875, + "z":-1.4296875 + }, + "rot":{ + "x":0, + "y":-0, + "z":0 + } + } + },{ + "ghost":false, + "open":false, + "children":[], + "visible":true, + "name":"rod.2", + "motions":{ + "tracks":[[],[],[],[]] + }, + "mesh":{ + "vertices":[0.125,1.75,-0.125,0.125,-2.5,-0.125,-0.125,-2.5,-0.125,-0.125,1.75,-0.125,0.125,1.75,0.125,0.125,-2.5,0.125,-0.125,-2.5,0.125,-0.125,1.75,0.125,0.125,2,0.125,0.125,2,-0.125,-0.125,2,-0.125,-0.125,2,0.125,0.125,2,0.125,0.125,1.75,0.125,0.125,1.75,-0.125,0.125,2,-0.125], + "name":"cube....16", + "faces":[{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[1,2,3,4] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[6,5,8,7] + },{ + "color":11, + "uvs":[0.53125,0.65625,0.53125,0.78125,0.40625,0.78125,0.40625,0.65625], + "vertex_ids":[5,6,2,1] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[9,10,11,12] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[2,6,7,3] + },{ + "color":11, + "uvs":[0.5,0.65625,0.5,0.78125,0.375,0.78125,0.375,0.65625], + "vertex_ids":[4,3,7,8] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[13,14,15,16] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[10,1,4,11] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[11,4,8,12] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[12,8,5,9] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[13,9,5,14] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[14,5,1,15] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[15,1,10,16] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[16,10,9,13] + }] + }, + "locked":true, + "transform":{ + "scale":{ + "x":1, + "y":1, + "z":1 + }, + "pos":{ + "x":0, + "y":1.0859375, + "z":2.3203125 + }, + "rot":{ + "x":0, + "y":-0, + "z":0 + } + } + }], + "visible":true, + "name":"blasters", + "motions":{ + "tracks":[[],[],[],[]] + }, + "folder":true, + "locked":true, + "transform":{ + "scale":{ + "x":1, + "y":1, + "z":1 + }, + "pos":{ + "x":0, + "y":0, + "z":0 + }, + "rot":{ + "x":0, + "y":0, + "z":0 + } + } + },{ + "ghost":false, + "open":false, + "children":[{ + "ghost":false, + "open":false, + "children":[], + "visible":true, + "name":"BUCKET", + "motions":{ + "tracks":[[],[],[],[]] + }, + "mesh":{ + "vertices":[-1.5,5.2423020600259,1.5363355460553,-1.5,4.9923020600259,1.5363355460553,1.5,4.9923020600259,1.5363355460553,1.5,5.2423020600259,1.5363355460553,-1.75,5.2423020600259,1.2049820172039,-1.75,4.8572481116375,1.2049820172039,1.75,4.8572481116375,1.2049820172039,1.75,5.2423020600259,1.2049820172039,0.9921875,5.6251145600259,-2.890625,0.9921875,5.1251145600259,-2.890625,-1.0078125,5.1251145600259,-2.890625,-1.0078125,5.6251145600259,-2.890625,1.2421875,5.6251145600259,-2.390625,1.2421875,5.1251145600259,-2.390625,-1.2578125,5.1251145600259,-2.390625,-1.2578125,5.6251145600259,-2.390625,0.5,3.75,-2.25,0.5,3.25,-2.25,-0.5,3.25,-2.25,-0.5,3.75,-2.25,0.5,3.75,-1.75,0.5,3.25,-1.75,-0.5,3.25,-1.75,-0.5,3.75,-1.75,1,3.75,-1.75,1,3.25,-1.75,1,3.25,-2.25,1,3.75,-2.25,1.75,3,-0.75,1.25,3,-0.75,1.25,2.5,-0.75,1.75,2.5,-0.75,1.75,3,0.75,1.25,3,0.75,1.25,2.5,0.75,1.75,2.5,0.75,-1,3.75,-2.25,-1,3.25,-2.25,-1,3.25,-1.75,-1,3.75,-1.75,-1.75,2.5,-0.75,-1.25,2.5,-0.75,-1.25,3,-0.75,-1.75,3,-0.75,-1.75,2.5,0.75,-1.25,2.5,0.75,-1.25,3,0.75,-1.75,3,0.75,1.75,3.25,1.2049820172039,1.25,3.25,1.2049820172039,1.25,2.75,1.2049820172039,1.75,2.75,1.2049820172039,-1.75,2.75,1.2049820172039,-1.25,2.75,1.2049820172039,-1.25,3.25,1.2049820172039,-1.75,3.25,1.2049820172039,1.75,3.75,1,1.75,3.75,0.5,1.25,3.75,0.5,1.25,3.75,1,-1.25,3.75,1,-1.25,3.75,0.5,-1.75,3.75,0.5,-1.75,3.75,1,1.75,4.25,1,1.75,4.25,0.5,1.25,4.25,0.5,1.25,4.25,1,-1.25,4.25,1,-1.25,4.25,0.5,-1.75,4.25,0.5,-1.75,4.25,1,1.75,4.5,0.1064897758278,1.75,4.25,-0.3935102241722,1.25,4.25,-0.3935102241722,1.25,4.5,0.1064897758278,-1.25,4.5,0.1064897758278,-1.25,4.25,-0.3935102241722,-1.75,4.25,-0.3935102241722,-1.75,4.5,0.1064897758278,-1.25,4.75,-0.1435102241722,-1.25,4.75,-0.6435102241722,-1.75,4.75,-0.6435102241722,-1.75,4.75,-0.1435102241722,1.75,4.75,-0.1435102241722,1.75,4.75,-0.6435102241722,1.25,4.75,-0.6435102241722,1.25,4.75,-0.1435102241722,1.75,5.1561640799806,-0.33118206421104,1.75,5.25,-0.6435102241722,1.25,5.25,-0.6435102241722,1.25,5.1561640799806,-0.33118206421104,-1.25,5.1561640799806,-0.33118206421104,-1.25,5.25,-0.6435102241722,-1.75,5.25,-0.6435102241722,-1.75,5.1561640799806,-0.33118206421104,1.75,5.25,-1.6435102241722,1.75,4.75,-1.6435102241722,1.25,4.75,-1.6435102241722,1.25,5.25,-1.6435102241722,-1.25,5.25,-1.6435102241722,-1.25,4.75,-1.6435102241722,-1.75,4.75,-1.6435102241722,-1.75,5.25,-1.6435102241722,1.25,5.6251145600259,-2.3935102241722,1.25,5.1251145600259,-2.3935102241722,0.75,5.1251145600259,-2.3935102241722,0.75,5.6251145600259,-2.3935102241722,-0.75,5.6251145600259,-2.3935102241722,-0.75,5.1251145600259,-2.3935102241722,-1.25,5.1251145600259,-2.3935102241722,-1.25,5.6251145600259,-2.3935102241722,1.75,4.8649460516116,1.2049820172039,1.75,4.75,0.5,1.25,4.75,0.5,1.25,4.8649460516116,1.2049820172039,-1.25,4.8649460516116,1.2049820172039,-1.25,4.75,0.5,-1.75,4.75,0.5,-1.75,4.8649460516116,1.2049820172039,1.75,5.25,1.2049820172039,1.75,5.25,0.75,1.25,5.25,0.75,1.25,5.25,1.2049820172039,-1.25,5.25,1.2049820172039,-1.25,5.25,0.75,-1.75,5.25,0.75,-1.75,5.25,1.2049820172039,1.5,5.125,-1.125,0.75,5.125,-1.875,-0.75,5.125,-1.875,-1.5,5.125,-1.125,-1.5,5.5,0.375,-0.75,5.875,1.125,0.75,5.875,1.125,1.5,5.5,0.375,1.125,2.5,-0.375,0.375,2.5,-1.125,-0.375,2.5,-1.125,-1.125,2.5,-0.375,-1.125,2.5,0.75,-0.375,2.5,1.5,0.375,2.5,1.5,1.125,2.5,0.75], + "name":"BUCKET", + "faces":[{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[1,2,3,4] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[6,5,8,7] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[5,6,2,1] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[5,1,4,8] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[2,6,7,3] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[4,3,7,8] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[9,10,11,12] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[14,13,16,15] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[13,14,10,9] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[13,9,12,16] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[10,14,15,11] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[12,11,15,16] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[17,18,19,20] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[22,21,24,23] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[25,26,27,28] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[21,17,20,24] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[18,22,23,19] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[37,38,39,40] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[49,50,51,52] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[26,22,18,27] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[27,18,17,28] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[28,17,21,25] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[29,25,21,30] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[30,21,22,31] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[31,22,26,32] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[32,26,25,29] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[33,29,30,34] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[34,30,31,35] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[35,31,32,36] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[36,32,29,33] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[37,20,19,38] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[38,19,23,39] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[53,54,55,56] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[40,24,20,37] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[41,39,23,42] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[42,23,24,43] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[43,24,40,44] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[44,40,39,41] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[45,41,42,46] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[46,42,43,47] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[47,43,44,48] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[48,44,41,45] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[121,122,123,124] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[50,34,35,51] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[51,35,36,52] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[52,36,33,49] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[53,45,46,54] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[54,46,47,55] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[125,126,127,128] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[56,48,45,53] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[57,49,33,58] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[58,33,34,59] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[59,34,50,60] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[60,50,49,57] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[61,55,47,62] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[62,47,48,63] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[63,48,56,64] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[64,56,55,61] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[65,57,58,66] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[89,90,91,92] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[67,59,60,68] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[68,60,57,65] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[69,61,62,70] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[93,94,95,96] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[71,63,64,72] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[72,64,61,69] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[73,66,58,74] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[74,58,59,75] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[75,59,67,76] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[76,67,66,73] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[77,70,62,78] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[78,62,63,79] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[79,63,71,80] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[80,71,70,77] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[81,77,78,82] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[82,78,79,83] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[83,79,80,84] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[84,80,77,81] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[85,73,74,86] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[86,74,75,87] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[87,75,76,88] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[88,76,73,85] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[89,85,86,90] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[105,106,107,108] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[91,87,88,92] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[92,88,85,89] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[93,81,82,94] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[109,110,111,112] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[95,83,84,96] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[96,84,81,93] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[97,90,86,98] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[98,86,87,99] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[99,87,91,100] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[100,91,90,97] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[101,94,82,102] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[102,82,83,103] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[103,83,95,104] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[104,95,94,101] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[105,97,98,106] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[106,98,99,107] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[107,99,100,108] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[108,100,97,105] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[109,101,102,110] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[110,102,103,111] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[111,103,104,112] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[112,104,101,109] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[113,65,66,114] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[114,66,67,115] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[115,67,68,116] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[116,68,65,113] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[117,69,70,118] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[118,70,71,119] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[119,71,72,120] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[120,72,69,117] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[121,113,114,122] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[122,114,115,123] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[123,115,116,124] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[124,116,113,121] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[125,117,118,126] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[126,118,119,127] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[127,119,120,128] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[128,120,117,125] + },{ + "color":10, + "uvs":[0.78125,0.125,0.75,0.09375,0.75,0.03125,0.78125,0,0.84375,0,0.875,0.03125,0.875,0.09375,0.84375,0.125], + "vertex_ids":[129,130,131,132,133,134,135,136] + },{ + "color":10, + "uvs":[0.78125,0.125,0.75,0.09375,0.75,0.03125,0.78125,0,0.84375,0,0.875,0.03125,0.875,0.09375,0.84375,0.125], + "vertex_ids":[144,143,142,141,140,139,138,137] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[129,137,138,130] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[130,138,139,131] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[131,139,140,132] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[132,140,141,133] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[133,141,142,134] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[134,142,143,135] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[135,143,144,136] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[136,144,137,129] + }] + }, + "locked":true, + "transform":{ + "scale":{ + "x":1, + "y":1, + "z":1 + }, + "pos":{ + "x":0, + "y":0.4453125, + "z":-2 + }, + "rot":{ + "x":0.5235987755983, + "y":-0, + "z":0 + } + } + },{ + "ghost":false, + "open":true, + "children":[], + "visible":true, + "name":"rod.1", + "motions":{ + "tracks":[[],[],[],[]] + }, + "mesh":{ + "vertices":[0.125,3.75,-0.125,0.125,-1,-0.125,-0.125,-1,-0.125,-0.125,3.75,-0.125,0.125,3.75,0.125,0.125,-1,0.125,-0.125,-1,0.125,-0.125,3.75,0.125], + "name":"cube..20", + "faces":[{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[1,2,3,4] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[6,5,8,7] + },{ + "color":11, + "uvs":[0.53125,0.65625,0.53125,0.78125,0.40625,0.78125,0.40625,0.65625], + "vertex_ids":[5,6,2,1] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[5,1,4,8] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[2,6,7,3] + },{ + "color":11, + "uvs":[0.5,0.65625,0.5,0.78125,0.375,0.78125,0.375,0.65625], + "vertex_ids":[4,3,7,8] + }] + }, + "locked":true, + "transform":{ + "scale":{ + "x":1, + "y":1, + "z":1 + }, + "pos":{ + "x":0, + "y":0.375, + "z":1.2109375 + }, + "rot":{ + "x":0, + "y":-0, + "z":0 + } + } + },{ + "ghost":false, + "open":false, + "children":[], + "visible":true, + "name":"rod.2", + "motions":{ + "tracks":[[],[],[],[]] + }, + "mesh":{ + "vertices":[0.125,1.75,0.125,0.125,-3.25,0.125,-0.125,-3.25,0.125,-0.125,1.75,0.125,0.125,1.75,0.375,0.125,-3.25,0.375,-0.125,-3.25,0.375,-0.125,1.75,0.375], + "name":"cube..19", + "faces":[{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[1,2,3,4] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[6,5,8,7] + },{ + "color":11, + "uvs":[0.53125,0.65625,0.53125,0.78125,0.40625,0.78125,0.40625,0.65625], + "vertex_ids":[5,6,2,1] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[5,1,4,8] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[2,6,7,3] + },{ + "color":11, + "uvs":[0.5,0.65625,0.5,0.78125,0.375,0.78125,0.375,0.65625], + "vertex_ids":[4,3,7,8] + }] + }, + "locked":true, + "transform":{ + "scale":{ + "x":1, + "y":1, + "z":1 + }, + "pos":{ + "x":0, + "y":1.7265625, + "z":-1.4609375 + }, + "rot":{ + "x":0, + "y":-0, + "z":0 + } + } + }], + "visible":true, + "name":"sloshers", + "motions":{ + "tracks":[[],[],[],[]] + }, + "folder":true, + "locked":true, + "transform":{ + "scale":{ + "x":1, + "y":1, + "z":1 + }, + "pos":{ + "x":0, + "y":0, + "z":0 + }, + "rot":{ + "x":0, + "y":0, + "z":0 + } + } + },{ + "ghost":false, + "open":false, + "children":[{ + "ghost":false, + "open":false, + "children":[], + "visible":true, + "name":"ihatethisweapon", + "motions":{ + "tracks":[[],[],[],[]] + }, + "mesh":{ + "vertices":[-0.53033008588991,4.0732233047034,0,-0.53033008588991,4.4267766952966,0,-0.17677669529664,4.7803300858899,0,0.17677669529664,4.7803300858899,0,0.53033008588991,4.4267766952966,0,0.53033008588991,4.0732233047034,5.5511151231258e-17,0.17677669529664,3.7196699141101,5.5511151231258e-17,-0.17677669529664,3.7196699141101,0,-0.70710678118655,4.1464466094067,0.5,-0.70710678118655,4.6035533905933,0.5,-0.35355339059327,5.2777513695322,0.67677669529664,0.35355339059327,5.2777513695322,0.67677669529664,0.70710678118655,4.6035533905933,0.5,0.70710678118655,4.1464466094067,0.5,0.35355339059327,3.7928932188135,0.5,-0.35355339059327,3.7928932188135,0.5,-0.53161944406877,3.5428932188135,1.25,0.51363595743765,3.5428932188135,1.25,0.95710678118655,3.8964466094067,1.25,0.95710678118657,5.0303300858899,1.4267766952966,0.51363595743768,5.4267766952967,1.4267766952966,-0.53161944406878,5.4267766952966,1.4267766952966,-0.95710678118657,5.0303300858899,1.4267766952966,-0.95710678118655,3.8964466094067,1.25,-0.75000000000001,3.0428932188134,2,0.76363595743764,3.0428932188135,2,1.2071067811865,3.8232233047034,2.1767766952966,1.2071067811866,4.7803300858899,2.1767766952966,0.76363595743767,5.3838834764832,2.1767766952966,-0.74999999999996,5.3838834764832,2.1767766952966,-1.2071067811866,4.7803300858899,2.1767766952966,-1.2071067811865,3.8232233047034,2.1767766952966,-0.75000000000003,2.5754477364906,2.6583598491581,0.76363595743766,2.5754477364906,2.6583598491581,1.2071067811866,3.3232233047034,3.0851365444548,1.2071067811866,4.0303300858899,3.0851365444548,0.76363595743765,4.9474244137292,2.8986774817008,-0.75,4.9474244137292,2.8986774817008,-1.2071067811866,4.0303300858899,3.0851365444548,-1.2071067811866,3.3232233047034,3.0851365444548,-0.25000000000002,3.1044292557388,3.4082780003883,0.26363595743767,3.1044292557388,3.4082780003883,0.70710678118657,3.2865607489567,3.4928303687509,0.70710678118656,3.8838834764832,3.4708735580189,0.26363595743766,4.1767766952966,3.4708735580189,-0.24999999999999,4.1767766952966,3.4708735580189,-0.70710678118655,3.8838834764832,3.4708735580189,-0.70710678118655,3.2865607489567,3.4928303687509,0.140625,3.25,-1.5,0.140625,2.75,-1.5,-0.109375,2.75,-1.5,-0.109375,3.25,-1.5,0.140625,3.3862065712945,-1.25,0.140625,2.8862065712945,-1.25,-0.109375,2.8862065712945,-1.25,-0.109375,3.3862065712945,-1.25,0.140625,3.046875,-0.984375,0.140625,3.5859375,-1.0234375,-0.109375,3.5859375,-1.0234375,-0.109375,3.046875,-0.984375,0.140625,4,-1.296875,0.140625,4,-1.546875,-0.109375,4,-1.546875,-0.109375,4,-1.296875,0.140625,3.2059493969791,-0.75,0.140625,3.515625,-0.765625,-0.109375,3.515625,-0.765625,-0.109375,3.2059493969791,-0.75,0.140625,3.46875,-0.3828125,0.140625,3.7578125,-0.4609375,-0.109375,3.7578125,-0.4609375,-0.109375,3.46875,-0.3828125,0.140625,3.625,-0.21875,0.140625,3.7582565162426,-0.16282146789418,-0.109375,3.7582565162426,-0.16282146789418,-0.109375,3.625,-0.21875,0.140625,4.3862065712945,0,0.140625,4.1362065712945,-0.25,-0.109375,4.1362065712945,-0.25,-0.109375,4.3862065712945,0,0.140625,4.25,-4.5,0.140625,3.5,-4.5,-0.109375,3.5,-4.5,-0.109375,4.25,-4.5,0.140625,4.25,-4,0.140625,3.5,-4,-0.109375,3.5,-4,-0.109375,4.25,-4,0.140625,3.25,-3.25,0.140625,4,-3.25,-0.109375,4,-3.25,-0.109375,3.25,-3.25,0.140625,3,-2.75,0.140625,3.705590286937,-2.8060700782555,-0.109375,3.705590286937,-2.8060700782555,-0.109375,3,-2.75,0.140625,2.75,-2.5,0.140625,3.25,-2.5,-0.109375,3.25,-2.5,-0.109375,2.75,-2.5,0.3671875,4.3515625,-5.5,0.3671875,3.3515625,-5.5,-0.3828125,3.3515625,-5.5,-0.3828125,4.3515625,-5.5,0.3671875,4.3515625,-4.5,0.3671875,3.3515625,-4.5,-0.3828125,3.3515625,-4.5,-0.3828125,4.3515625,-4.5,0.25,3.25,-2.5,0.25,2.75,-2.5,-0.25,2.75,-2.5,-0.25,3.25,-2.5,0.25,3.25,-1.5,0.25,2.75,-1.5,-0.25,2.75,-1.5,-0.25,3.25,-1.5,0.14644660940675,3.7196699141101,-0.75,-0.20710678118653,3.7196699141101,-0.75,-0.56066017177981,4.0732233047034,-0.75,-0.56066017177983,4.4267766952966,-0.75,-0.20710678118657,4.7803300858899,-0.75,0.14644660940671,4.7803300858899,-0.75,0.49999999999999,4.4267766952967,-0.75,0.50000000000001,4.0732233047034,-0.75,0.14644660940673,3.9696699141101,-0.25,-0.20710678118654,3.9696699141101,-0.25,-0.31066017177981,4.0732233047034,-0.25,-0.31066017177983,4.4267766952966,-0.25,-0.20710678118656,4.5303300858899,-0.25,0.14644660940671,4.5303300858899,-0.25,0.24999999999999,4.4267766952967,-0.25,0.25,4.0732233047034,-0.25,0.24329414861153,3.8728223749053,-1.25,-0.30395432039133,3.8728223749053,-1.25,-0.4075077109846,3.9763757654986,-1.25,-0.40750771098462,4.5236242345014,-1.25,-0.30395432039136,4.6271776250947,-1.25,0.24329414861151,4.6271776250947,-1.25,0.34684753920478,4.5236242345015,-1.25,0.3468475392048,3.9763757654986,-1.25,0.20387827153559,3.9122382519813,-1.5,-0.26453844331538,3.9122382519813,-1.5,-0.36809183390865,4.0157916425745,-1.5,-0.36809183390867,4.4842083574255,-1.5,-0.2645384433154,4.5877617480188,-1.5,0.20387827153556,4.5877617480188,-1.5,0.30743166212883,4.4842083574255,-1.5,0.30743166212886,4.0157916425745,-1.5,0.047667553299269,4.0684489702176,-2,-0.10832772507907,4.0684489702176,-2,-0.21188111567234,4.1720023608108,-2,-0.21188111567235,4.3279976391892,-2,-0.10832772507908,4.4315510297824,-2,0.047667553299256,4.4315510297825,-2,0.15122094389253,4.3279976391892,-2,0.15122094389254,4.1720023608108,-2,0.13258252147249,3.8522524355826,-0.25,-0.13258252147246,3.8522524355826,-0.25,-0.39774756441743,4.1174174785275,-0.25,-0.39774756441744,4.3825825214725,-0.25,-0.13258252147249,4.6477475644174,-0.25,0.13258252147246,4.6477475644174,-0.25,0.39774756441743,4.3825825214725,-0.25,0.39774756441744,4.1174174785275,-0.25,0.13258252147249,3.8522524355826,0.0028104614102893,-0.13258252147246,3.8522524355826,0.0028104614102887,-0.39774756441743,4.1174174785275,0.0028104614102887,-0.39774756441744,4.3825825214725,0.0028104614102893,-0.13258252147249,4.6477475644174,0.0028104614102907,0.13258252147246,4.6477475644174,0.0028104614102913,0.39774756441743,4.3825825214725,0.0028104614102913,0.39774756441744,4.1174174785275,0.0028104614102907], + "name":"ihatethisweapon", + "faces":[{ + "color":10, + "uvs":[0.6875,0.78125,0.65625,0.75,0.65625,0.6875,0.6875,0.65625,0.75,0.65625,0.78125,0.6875,0.78125,0.75,0.75,0.78125], + "vertex_ids":[1,2,3,4,5,6,7,8] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.65625,0.75,0.65625,0.6875,0.6875,0.65625,0.75,0.65625,0.78125,0.6875,0.78125,0.75,0.75,0.78125], + "vertex_ids":[41,42,43,44,45,46,47,48] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[1,9,10,2] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[2,10,11,3] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[3,11,12,4] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[4,12,13,5] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[5,13,14,6] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[6,14,15,7] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[7,15,16,8] + },{ + "color":10, + "uvs":[0.78125,0.65625,0.78125,0.78125,0.65625,0.78125,0.65625,0.65625], + "vertex_ids":[8,16,9,1] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[17,16,15,18] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[18,15,14,19] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[19,14,13,20] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[20,13,12,21] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[21,12,11,22] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[22,11,10,23] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[23,10,9,24] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[24,9,16,17] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[25,17,18,26] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[26,18,19,27] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[27,19,20,28] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[28,20,21,29] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[29,21,22,30] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[30,22,23,31] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[31,23,24,32] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[32,24,17,25] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[33,25,26,34] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[34,26,27,35] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[35,27,28,36] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[36,28,29,37] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[37,29,30,38] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[38,30,31,39] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[39,31,32,40] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[40,32,25,33] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[41,33,34,42] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[42,34,35,43] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[43,35,36,44] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[44,36,37,45] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[45,37,38,46] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[46,38,39,47] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[47,39,40,48] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.75,0.78125,0.75,0.84375,0.6875,0.84375], + "vertex_ids":[48,40,33,41] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[49,50,51,52] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[73,74,75,76] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[53,54,50,49] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[53,49,52,56] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[50,54,55,51] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[52,51,55,56] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[57,54,53,58] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[61,62,63,64] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[59,56,55,60] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[60,55,54,57] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[61,58,53,62] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[62,53,56,63] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[63,56,59,64] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[64,59,58,61] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[65,57,58,66] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[66,58,59,67] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[67,59,60,68] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[68,60,57,65] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[69,65,66,70] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[70,66,67,71] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[71,67,68,72] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[72,68,65,69] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[73,69,70,74] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[77,78,79,80] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[75,71,72,76] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[76,72,69,73] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[77,74,70,78] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[78,70,71,79] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[79,71,75,80] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[80,75,74,77] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[81,82,83,84] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[97,98,99,100] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[85,86,82,81] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[85,81,84,88] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[82,86,87,83] + },{ + "color":11, + "uvs":[0.96875,0.65625,0.96875,0.78125,0.84375,0.78125,0.84375,0.65625], + "vertex_ids":[84,83,87,88] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[89,86,85,90] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[90,85,88,91] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[91,88,87,92] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[92,87,86,89] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[93,89,90,94] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[94,90,91,95] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[95,91,92,96] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[96,92,89,93] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[97,93,94,98] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[98,94,95,99] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[99,95,96,100] + },{ + "color":11, + "uvs":[0.84375,0.65625,0.96875,0.65625,0.96875,0.78125,0.84375,0.78125], + "vertex_ids":[100,96,93,97] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[101,102,103,104] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[106,105,108,107] + },{ + "color":11, + "uvs":[0.5,0,0.5,0.125,0.375,0.125,0.375,0], + "vertex_ids":[105,106,102,101] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[105,101,104,108] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[102,106,107,103] + },{ + "color":11, + "uvs":[0.5,0,0.5,0.125,0.375,0.125,0.375,0], + "vertex_ids":[104,103,107,108] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[109,110,111,112] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[114,113,116,115] + },{ + "color":11, + "uvs":[0.5,0,0.5,0.125,0.375,0.125,0.375,0], + "vertex_ids":[113,114,110,109] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[113,109,112,116] + },{ + "color":11, + "uvs":[0.375,0,0.5,0,0.5,0.125,0.375,0.125], + "vertex_ids":[110,114,115,111] + },{ + "color":11, + "uvs":[0.5,0,0.5,0.125,0.375,0.125,0.375,0], + "vertex_ids":[112,111,115,116] + },{ + "color":10, + "uvs":[0.6875,0.78125,0.65625,0.75,0.65625,0.6875,0.6875,0.65625,0.75,0.65625,0.78125,0.6875,0.78125,0.75,0.75,0.78125], + "vertex_ids":[149,150,151,152,153,154,155,156] + },{ + "color":10, + "uvs":[0.78125,0.125,0.75,0.09375,0.75,0.03125,0.78125,0,0.84375,0,0.875,0.03125,0.875,0.09375,0.84375,0.125], + "vertex_ids":[132,131,130,129,128,127,126,125] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[117,125,126,118] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[118,126,127,119] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[119,127,128,120] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[120,128,129,121] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[121,129,130,122] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[122,130,131,123] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[123,131,132,124] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[124,132,125,117] + },{ + "color":10, + "uvs":[0.6875,0.65625,0.75,0.65625,0.75,0.71875,0.6875,0.71875], + "vertex_ids":[133,117,118,134] + },{ + "color":10, + "uvs":[0.71875,0.6640625,0.78125,0.6640625,0.78125,0.7265625,0.71875,0.7265625], + "vertex_ids":[134,118,119,135] + },{ + "color":10, + "uvs":[0.6875,0.65625,0.75,0.65625,0.75,0.71875,0.6875,0.71875], + "vertex_ids":[135,119,120,136] + },{ + "color":10, + "uvs":[0.71875,0.65625,0.78125,0.65625,0.78125,0.71875,0.71875,0.71875], + "vertex_ids":[136,120,121,137] + },{ + "color":10, + "uvs":[0.71875,0.65625,0.78125,0.65625,0.78125,0.71875,0.71875,0.71875], + "vertex_ids":[137,121,122,138] + },{ + "color":10, + "uvs":[0.6875,0.65625,0.75,0.65625,0.75,0.71875,0.6875,0.71875], + "vertex_ids":[138,122,123,139] + },{ + "color":10, + "uvs":[0.6875,0.65625,0.75,0.65625,0.75,0.71875,0.6875,0.71875], + "vertex_ids":[139,123,124,140] + },{ + "color":10, + "uvs":[0.71875,0.65625,0.78125,0.65625,0.78125,0.71875,0.71875,0.71875], + "vertex_ids":[140,124,117,133] + },{ + "color":10, + "uvs":[0.875,0.65625,0.9375,0.65625,0.9375,0.71875,0.875,0.71875], + "vertex_ids":[141,133,134,142] + },{ + "color":10, + "uvs":[0.875,0.65625,0.9375,0.65625,0.9375,0.71875,0.875,0.71875], + "vertex_ids":[142,134,135,143] + },{ + "color":10, + "uvs":[0.875,0.6484375,0.9375,0.6484375,0.9375,0.7109375,0.875,0.7109375], + "vertex_ids":[143,135,136,144] + },{ + "color":10, + "uvs":[0.875,0.65625,0.9375,0.65625,0.9375,0.71875,0.875,0.71875], + "vertex_ids":[144,136,137,145] + },{ + "color":10, + "uvs":[0.90625,0.6875,0.96875,0.6875,0.96875,0.75,0.90625,0.75], + "vertex_ids":[145,137,138,146] + },{ + "color":10, + "uvs":[0.875,0.65625,0.9375,0.65625,0.9375,0.71875,0.875,0.71875], + "vertex_ids":[146,138,139,147] + },{ + "color":10, + "uvs":[0.875,0.65625,0.9375,0.65625,0.9375,0.71875,0.875,0.71875], + "vertex_ids":[147,139,140,148] + },{ + "color":10, + "uvs":[0.875,0.65625,0.9375,0.65625,0.9375,0.71875,0.875,0.71875], + "vertex_ids":[148,140,133,141] + },{ + "color":10, + "uvs":[0.6875,0.65625,0.75,0.65625,0.75,0.71875,0.6875,0.71875], + "vertex_ids":[149,141,142,150] + },{ + "color":10, + "uvs":[0.6875,0.65625,0.75,0.65625,0.75,0.71875,0.6875,0.71875], + "vertex_ids":[150,142,143,151] + },{ + "color":10, + "uvs":[0.6875,0.65625,0.75,0.65625,0.75,0.71875,0.6875,0.71875], + "vertex_ids":[151,143,144,152] + },{ + "color":10, + "uvs":[0.6953125,0.65625,0.7578125,0.65625,0.7578125,0.71875,0.6953125,0.71875], + "vertex_ids":[152,144,145,153] + },{ + "color":10, + "uvs":[0.6953125,0.65625,0.7578125,0.65625,0.7578125,0.71875,0.6953125,0.71875], + "vertex_ids":[153,145,146,154] + },{ + "color":10, + "uvs":[0.6875,0.6875,0.75,0.6875,0.75,0.75,0.6875,0.75], + "vertex_ids":[154,146,147,155] + },{ + "color":10, + "uvs":[0.6875,0.65625,0.75,0.65625,0.75,0.71875,0.6875,0.71875], + "vertex_ids":[155,147,148,156] + },{ + "color":10, + "uvs":[0.6875,0.65625,0.75,0.65625,0.75,0.71875,0.6875,0.71875], + "vertex_ids":[156,148,141,149] + },{ + "color":10, + "uvs":[0.78125,0.125,0.75,0.09375,0.75,0.03125,0.78125,0,0.84375,0,0.875,0.03125,0.875,0.09375,0.84375,0.125], + "vertex_ids":[157,158,159,160,161,162,163,164] + },{ + "color":10, + "uvs":[0.78125,0.125,0.75,0.09375,0.75,0.03125,0.78125,0,0.84375,0,0.875,0.03125,0.875,0.09375,0.84375,0.125], + "vertex_ids":[172,171,170,169,168,167,166,165] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[157,165,166,158] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[158,166,167,159] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[159,167,168,160] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[160,168,169,161] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[161,169,170,162] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[162,170,171,163] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[163,171,172,164] + },{ + "color":10, + "uvs":[0.875,0,0.875,0.125,0.75,0.125,0.75,0], + "vertex_ids":[164,172,165,157] + }] + }, + "locked":true, + "transform":{ + "scale":{ + "x":1, + "y":1, + "z":1 + }, + "pos":{ + "x":0, + "y":3.25, + "z":3.5 + }, + "rot":{ + "x":-0.78539816339745, + "y":-0, + "z":0 + } + } + },{ + "ghost":false, + "open":true, + "children":[], + "visible":true, + "name":"rod.1", + "motions":{ + "tracks":[[],[],[],[]] + }, + "mesh":{ + "vertices":[0.125,3.75,-0.125,0.125,-1,-0.125,-0.125,-1,-0.125,-0.125,3.75,-0.125,0.125,3.75,0.125,0.125,-1,0.125,-0.125,-1,0.125,-0.125,3.75,0.125], + "name":"cube...21", + "faces":[{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[1,2,3,4] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[6,5,8,7] + },{ + "color":11, + "uvs":[0.53125,0.65625,0.53125,0.78125,0.40625,0.78125,0.40625,0.65625], + "vertex_ids":[5,6,2,1] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[5,1,4,8] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[2,6,7,3] + },{ + "color":11, + "uvs":[0.5,0.65625,0.5,0.78125,0.375,0.78125,0.375,0.65625], + "vertex_ids":[4,3,7,8] + }] + }, + "locked":true, + "transform":{ + "scale":{ + "x":1, + "y":1, + "z":1 + }, + "pos":{ + "x":0, + "y":-0.5, + "z":-1.75 + }, + "rot":{ + "x":0, + "y":-0, + "z":0 + } + } + },{ + "ghost":false, + "open":false, + "children":[], + "visible":true, + "name":"rod.2", + "motions":{ + "tracks":[[],[],[],[]] + }, + "mesh":{ + "vertices":[0.125,3,0.125,0.125,-3.25,0.125,-0.125,-3.25,0.125,-0.125,3,0.125,0.125,3,0.375,0.125,-3.25,0.375,-0.125,-3.25,0.375,-0.125,3,0.375], + "name":"cube...20", + "faces":[{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[1,2,3,4] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[6,5,8,7] + },{ + "color":11, + "uvs":[0.53125,0.65625,0.53125,0.78125,0.40625,0.78125,0.40625,0.65625], + "vertex_ids":[5,6,2,1] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[5,1,4,8] + },{ + "color":11, + "uvs":[0.40625,0.625,0.53125,0.625,0.53125,0.75,0.40625,0.75], + "vertex_ids":[2,6,7,3] + },{ + "color":11, + "uvs":[0.5,0.65625,0.5,0.78125,0.375,0.78125,0.375,0.65625], + "vertex_ids":[4,3,7,8] + }] + }, + "locked":true, + "transform":{ + "scale":{ + "x":1, + "y":1, + "z":1 + }, + "pos":{ + "x":0, + "y":4.25, + "z":1.25 + }, + "rot":{ + "x":0, + "y":-0, + "z":0 + } + } + }], + "visible":true, + "name":"brushes", + "motions":{ + "tracks":[[],[],[],[]] + }, + "folder":true, + "locked":true, + "transform":{ + "scale":{ + "x":1, + "y":1, + "z":1 + }, + "pos":{ + "x":0, + "y":0, + "z":0 + }, + "rot":{ + "x":0, + "y":0, + "z":0 + } + } + }], + "visible":true, + "name":"root", + "motions":{ + "tracks":[[],[],[],[]] + }, + "locked":false, + "transform":{ + "scale":{ + "x":1, + "y":1, + "z":1 + }, + "pos":{ + "x":0, + "y":0, + "z":0 + }, + "rot":{ + "x":0, + "y":0, + "z":0 + } + } + } +} \ No newline at end of file diff --git a/app/features/trophies/loaders/trophies.$id.server.ts b/app/features/trophies/loaders/trophies.$id.server.ts index d100635b6..447a894cd 100644 --- a/app/features/trophies/loaders/trophies.$id.server.ts +++ b/app/features/trophies/loaders/trophies.$id.server.ts @@ -1,15 +1,10 @@ import type { LoaderFunctionArgs } from "react-router"; -import { getUser } from "~/features/auth/core/user.server"; import { notFoundIfNullish, parseParams } from "~/utils/remix.server"; import { idObject } from "~/utils/schema"; +import * as XpTrophy from "../core/XpTrophy"; import * as TrophyRepository from "../TrophyRepository.server"; -import { canAccessTrophies } from "../trophies-utils"; export const loader = async ({ params }: LoaderFunctionArgs) => { - if (!canAccessTrophies(getUser())) { - throw new Response(null, { status: 404 }); - } - const { id } = parseParams({ params, schema: idObject, @@ -20,8 +15,17 @@ export const loader = async ({ params }: LoaderFunctionArgs) => { TrophyRepository.findTournamentsByTrophyId(id), ]); + const xpVariant = XpTrophy.parseCode(trophy.code); + return { trophy, tournaments, + xpWeapons: xpVariant + ? await TrophyRepository.findXpWeaponCountsById({ + trophyId: id, + weaponIds: XpTrophy.categoryWeaponIds(xpVariant.category), + milestone: xpVariant.milestone, + }) + : null, }; }; diff --git a/app/features/trophies/loaders/trophies.new.server.test.ts b/app/features/trophies/loaders/trophies.new.server.test.ts new file mode 100644 index 000000000..11ce3565a --- /dev/null +++ b/app/features/trophies/loaders/trophies.new.server.test.ts @@ -0,0 +1,69 @@ +import { beforeEach, describe, expect, test } from "vitest"; +import { DEV_TEST_ID } from "~/db/seed/constants"; +import * as TrophyFactory from "~/db/seed/factories/TrophyFactory"; +import * as UserFactory from "~/db/seed/factories/UserFactory"; +import { type TestUser, wrappedLoader } from "~/utils/Test"; +import { loader, type NewTrophyLoaderData } from "./trophies.new.server"; + +const newTrophyLoader = wrappedLoader({ loader }); + +const users = UserFactory.pool(); +const managerId = () => users.id(1); +const otherManagerId = () => users.id(2); + +describe("managing trophies", () => { + let managedTrophyId: number; + let otherTrophyId: number; + + beforeEach(async () => { + await UserFactory.createAdmin(); + await users.create(2); + await UserFactory.createDev(); + + managedTrophyId = (await TrophyFactory.create({ managerId: managerId() })) + .id; + otherTrophyId = ( + await TrophyFactory.create({ managerId: otherManagerId() }) + ).id; + }); + + const trophyIds = async ( + user: TestUser, + list: "editableTrophies" | "backfillTrophies", + ) => + (await newTrophyLoader({ user }))[list] + .map((trophy) => trophy.id) + .toSorted((a, b) => a - b); + + test("a manager can edit only the trophies they manage", async () => { + expect(await trophyIds(managerId(), "editableTrophies")).toEqual([ + managedTrophyId, + ]); + }); + + test("a dev can edit every trophy", async () => { + expect(await trophyIds(DEV_TEST_ID, "editableTrophies")).toEqual([ + managedTrophyId, + otherTrophyId, + ]); + }); + + // the admin's override of per-object permissions only applies in production + test("doesn't offer the admin trophies the server would refuse them", async () => { + expect(await trophyIds("admin", "editableTrophies")).toEqual([]); + }); + + test.each([ + { why: "an admin", user: "admin" as const }, + { why: "a dev", user: DEV_TEST_ID }, + ])("$why can backfill every trophy", async ({ user }) => { + expect(await trophyIds(user, "backfillTrophies")).toEqual([ + managedTrophyId, + otherTrophyId, + ]); + }); + + test("a manager can't backfill even their own trophy", async () => { + expect(await trophyIds(managerId(), "backfillTrophies")).toEqual([]); + }); +}); diff --git a/app/features/trophies/loaders/trophies.new.server.ts b/app/features/trophies/loaders/trophies.new.server.ts index 95dfd97a4..ffc2b5a29 100644 --- a/app/features/trophies/loaders/trophies.new.server.ts +++ b/app/features/trophies/loaders/trophies.new.server.ts @@ -1,8 +1,11 @@ import type { LoaderFunctionArgs } from "react-router"; +import * as R from "remeda"; import { requireUser } from "~/features/auth/core/user.server"; +import * as TournamentOrganizationRepository from "~/features/tournament-organization/TournamentOrganizationRepository.server"; +import { hasPermission } from "~/modules/permissions/utils"; import type { SerializeFrom } from "~/utils/remix"; import * as TrophyRepository from "../TrophyRepository.server"; -import { canEditAnyTrophy, canReviewTrophies } from "../trophies-utils"; +import { canBackfillTrophies, canReviewTrophies } from "../trophies-utils"; export type NewTrophyLoaderData = SerializeFrom; @@ -10,17 +13,31 @@ export const loader = async (_args: LoaderFunctionArgs) => { const user = requireUser(); const canReview = canReviewTrophies(user); + const canBackfill = canBackfillTrophies(user); - const [rawItems, ownUnreviewedCount, editableTrophies] = await Promise.all([ + const [rawItems, ownUnreviewedCount, trophies] = await Promise.all([ canReview ? TrophyRepository.allPending() : TrophyRepository.pendingBySubmitter(user.id), TrophyRepository.unreviewedCountBySubmitter(user.id), - canEditAnyTrophy(user) - ? TrophyRepository.findAllForEditing() - : TrophyRepository.findManagedBy(user.id), + TrophyRepository.findAllForEditing(), ]); + const editableTrophies = trophies.filter((trophy) => + hasPermission(trophy, "EDIT", user), + ); + + const backfillTrophies = canBackfill ? trophies : []; + const backfillSeries = ( + await TournamentOrganizationRepository.findAllSeriesByOrganizationIds( + R.unique( + backfillTrophies.flatMap((trophy) => + trophy.organizationId ? [trophy.organizationId] : [], + ), + ), + ) + ).map(({ id, name, organizationId }) => ({ id, name, organizationId })); + const allItems = canReview ? rawItems : rawItems.map(stripReviewerInfo); const isAccepted = (item: (typeof allItems)[number]) => @@ -40,6 +57,8 @@ export const loader = async (_args: LoaderFunctionArgs) => { pendingTrophies, reviewedTrophies, editableTrophies, + backfillTrophies, + backfillSeries, }; }; diff --git a/app/features/trophies/loaders/trophies.server.ts b/app/features/trophies/loaders/trophies.server.ts index 34f94d587..a49cc1a29 100644 --- a/app/features/trophies/loaders/trophies.server.ts +++ b/app/features/trophies/loaders/trophies.server.ts @@ -1,26 +1,30 @@ import { cachified } from "@epic-web/cachified"; -import { getUser } from "~/features/auth/core/user.server"; +import * as R from "remeda"; import { cache, IN_MILLISECONDS, ttl } from "~/utils/cache.server"; +import * as XpTrophy from "../core/XpTrophy"; import * as TrophyRepository from "../TrophyRepository.server"; -import { canAccessTrophies } from "../trophies-utils"; const TROPHIES_CACHE_KEY = "trophies"; export const loader = async () => { - if (!canAccessTrophies(getUser())) { - throw new Response(null, { status: 404 }); - } + const [trophies, xpTrophies] = await Promise.all([ + cachified({ + key: TROPHIES_CACHE_KEY, + cache, + ttl: ttl(IN_MILLISECONDS.TWO_HOURS), + async getFreshValue() { + return TrophyRepository.all(); + }, + }), + TrophyRepository.findAllXp(), + ]); - const trophies = await cachified({ - key: TROPHIES_CACHE_KEY, - cache, - ttl: ttl(IN_MILLISECONDS.TWO_HOURS), - async getFreshValue() { - return TrophyRepository.all(); - }, - }); - - return { trophies }; + return { + trophies, + xpTrophies: R.sortBy(xpTrophies, (trophy) => + XpTrophy.VARIANTS.findIndex((variant) => variant.code === trophy.code), + ), + }; }; export function clearTrophiesCache() { diff --git a/app/features/trophies/routes/trophies.$id.backfill.$seriesId.ts b/app/features/trophies/routes/trophies.$id.backfill.$seriesId.ts new file mode 100644 index 000000000..deb99478f --- /dev/null +++ b/app/features/trophies/routes/trophies.$id.backfill.$seriesId.ts @@ -0,0 +1,37 @@ +import type { LoaderFunctionArgs } from "react-router"; +import * as v from "valibot"; +import { requireUser } from "~/features/auth/core/user.server"; +import type { SerializeFrom } from "~/utils/remix"; +import { notFoundIfNullish, parseParams } from "~/utils/remix.server"; +import { id } from "~/utils/schema"; +import * as TrophyBackfill from "../core/TrophyBackfill.server"; +import * as TrophyRepository from "../TrophyRepository.server"; +import { canBackfillTrophies } from "../trophies-utils"; + +export type TrophyBackfillLoaderData = SerializeFrom; + +export const loader = async ({ params }: LoaderFunctionArgs) => { + if (!canBackfillTrophies(requireUser())) { + throw new Response(null, { status: 403 }); + } + + const { id: trophyId, seriesId } = parseParams({ + params, + schema: v.object({ id, seriesId: id }), + }); + + const trophy = notFoundIfNullish(await TrophyRepository.findById(trophyId)); + + const tournaments = trophy.organizationId + ? await TrophyBackfill.backfillableTournaments({ + organizationId: trophy.organizationId, + seriesId, + }) + : null; + + return { + trophyId, + seriesId, + tournaments: notFoundIfNullish(tournaments), + }; +}; diff --git a/app/features/trophies/routes/trophies.$id.module.css b/app/features/trophies/routes/trophies.$id.module.css index 5563cbf61..ae4acf839 100644 --- a/app/features/trophies/routes/trophies.$id.module.css +++ b/app/features/trophies/routes/trophies.$id.module.css @@ -45,3 +45,23 @@ color: var(--color-text-high); font-size: var(--font-2xs); } + +.weapons { + display: flex; + flex-wrap: wrap; + gap: var(--s-2); + padding: 0; + + & > li { + display: flex; + align-items: center; + gap: var(--s-0-5); + list-style: none; + } +} + +.weaponCount { + color: var(--color-text-high); + font-size: var(--font-xs); + font-weight: var(--weight-semi); +} diff --git a/app/features/trophies/routes/trophies.$id.placements.$userId.test.ts b/app/features/trophies/routes/trophies.$id.placements.$userId.test.ts new file mode 100644 index 000000000..c8b80ce60 --- /dev/null +++ b/app/features/trophies/routes/trophies.$id.placements.$userId.test.ts @@ -0,0 +1,62 @@ +import { beforeEach, describe, expect, test } from "vitest"; +import * as TrophyFactory from "~/db/seed/factories/TrophyFactory"; +import * as UserFactory from "~/db/seed/factories/UserFactory"; +import * as XRankPlacementFactory from "~/db/seed/factories/XRankPlacementFactory"; +import { wrappedLoader } from "~/utils/Test"; +import { + loader, + type TrophyPlacementsLoaderData, +} from "./trophies.$id.placements.$userId"; + +const SPLATTERSHOT = 40; +const SPLAT_CHARGER = 2010; + +const placementsLoader = wrappedLoader({ loader }); + +const users = UserFactory.pool(); +const playerId = () => users.id(1); + +describe("X Power trophy placements", () => { + let shootersTrophyId: number; + + beforeEach(async () => { + await users.create(1); + shootersTrophyId = (await TrophyFactory.createXpTrophies()).find( + (trophy) => trophy.code === "xp-shooters-3000", + )!.id; + + for (const [weaponSplId, power] of [ + [SPLATTERSHOT, 3050], + [SPLAT_CHARGER, 3400], + [SPLATTERSHOT, 3150], + ] as const) { + await XRankPlacementFactory.create({ + playerUserId: playerId(), + weaponSplId, + power, + }); + } + }); + + const load = (trophyId: number) => + placementsLoader({ + params: { id: String(trophyId), userId: String(playerId()) }, + }); + + test("lists the placements with the trophy's weapon category, highest first", async () => { + const { placements } = await load(shootersTrophyId); + + expect( + placements.map((placement) => [placement.weaponSplId, placement.power]), + ).toEqual([ + [SPLATTERSHOT, 3150], + [SPLATTERSHOT, 3050], + ]); + }); + + test("is not found for a tournament trophy", async () => { + const trophy = await TrophyFactory.create(); + + await expect(load(trophy.id)).rejects.toThrow("404"); + }); +}); diff --git a/app/features/trophies/routes/trophies.$id.placements.$userId.ts b/app/features/trophies/routes/trophies.$id.placements.$userId.ts new file mode 100644 index 000000000..6d954144b --- /dev/null +++ b/app/features/trophies/routes/trophies.$id.placements.$userId.ts @@ -0,0 +1,33 @@ +import type { LoaderFunctionArgs } from "react-router"; +import * as v from "valibot"; +import * as XRankPlacementRepository from "~/features/top-search/XRankPlacementRepository.server"; +import type { SerializeFrom } from "~/utils/remix"; +import { parseParams } from "~/utils/remix.server"; +import { id } from "~/utils/schema"; +import * as XpTrophy from "../core/XpTrophy"; +import * as TrophyRepository from "../TrophyRepository.server"; + +export type TrophyPlacementsLoaderData = SerializeFrom; + +const paramsSchema = v.object({ id, userId: id }); + +export const loader = async ({ params }: LoaderFunctionArgs) => { + const { id: trophyId, userId } = parseParams({ + params, + schema: paramsSchema, + }); + + const xpVariant = XpTrophy.parseCode( + await TrophyRepository.findCodeById(trophyId), + ); + if (!xpVariant) { + throw new Response(null, { status: 404 }); + } + + const placements = await XRankPlacementRepository.findPlacementsByUserId( + userId, + { weaponIds: XpTrophy.categoryWeaponIds(xpVariant.category) }, + ); + + return { placements: placements ?? [] }; +}; diff --git a/app/features/trophies/routes/trophies.$id.tournaments.ts b/app/features/trophies/routes/trophies.$id.tournaments.ts index 0360c64d0..c85ac80e5 100644 --- a/app/features/trophies/routes/trophies.$id.tournaments.ts +++ b/app/features/trophies/routes/trophies.$id.tournaments.ts @@ -1,18 +1,12 @@ import type { LoaderFunctionArgs } from "react-router"; -import { getUser } from "~/features/auth/core/user.server"; import type { SerializeFrom } from "~/utils/remix"; import { parseParams } from "~/utils/remix.server"; import { idObject } from "~/utils/schema"; import * as TrophyRepository from "../TrophyRepository.server"; -import { canAccessTrophies } from "../trophies-utils"; export type TrophyTournamentsLoaderData = SerializeFrom; export const loader = async ({ params }: LoaderFunctionArgs) => { - if (!canAccessTrophies(getUser())) { - throw new Response(null, { status: 404 }); - } - const { id } = parseParams({ params, schema: idObject, diff --git a/app/features/trophies/routes/trophies.$id.tsx b/app/features/trophies/routes/trophies.$id.tsx index 2100e0c9f..2a0db6f56 100644 --- a/app/features/trophies/routes/trophies.$id.tsx +++ b/app/features/trophies/routes/trophies.$id.tsx @@ -2,13 +2,14 @@ import clsx from "clsx"; import { Trans, useTranslation } from "react-i18next"; import { Link, type MetaFunction, useLoaderData } from "react-router"; import { Divider } from "~/components/Divider"; +import { WeaponImage } from "~/components/Image"; import { tournamentOrganizationPage } from "~/features/tournament-organization/tournament-organization-urls"; import { metaTags, ogPageImage, type SerializeFrom } from "~/utils/remix"; import { userPage } from "~/utils/urls"; import { TrophyShowcase } from "../components/TrophyShowcase"; import { TrophyTournamentHistory } from "../components/TrophyTournamentHistory"; +import * as XpTrophy from "../core/XpTrophy"; import { loader } from "../loaders/trophies.$id.server"; -import { parseSpecialTrophyCode } from "../trophies-utils"; import styles from "./trophies.$id.module.css"; export { loader }; @@ -33,15 +34,16 @@ export const meta: MetaFunction = (args) => { }; export default function TrophyDetailsPage() { - const { t } = useTranslation(["trophies"]); + const { t } = useTranslation(["trophies", "common"]); const data = useLoaderData(); - const { trophy, tournaments } = data; + const { trophy, tournaments, xpWeapons } = data; - const special = parseSpecialTrophyCode(trophy.code); + const xpVariant = XpTrophy.parseCode(trophy.code); return ( @@ -93,17 +95,41 @@ export default function TrophyDetailsPage() {

) : null} - {special ? ( + {xpVariant ? (

- {special.type === "supporter" - ? t("trophies:special.supporter.description") - : t("trophies:special.xp.description", { - value: special.value, - })} + {t("trophies:special.xp.categoryDescription", { + value: xpVariant.milestone, + category: t( + `common:weapon.category.${XpTrophy.categoryKey(xpVariant.category)}`, + ), + })}

) : null}
- {special ? null : ( + {xpWeapons ? ( + xpWeapons.length > 0 ? ( +
+ + {t("trophies:details.weapons")} + +
    + {xpWeapons.map((weapon) => ( +
  • + + + ×{weapon.ownerCount} + +
  • + ))} +
+
+ ) : null + ) : (
{t("trophies:details.tournamentHistory")} @@ -122,7 +148,7 @@ export default function TrophyDetailsPage() { {t("trophies:details.owners")} {trophy.owners.length > 0 ? ( -
    +
      {trophy.owners.map((owner) => (
    • {owner.username} diff --git a/app/features/trophies/routes/trophies.$id.wins.$userId.ts b/app/features/trophies/routes/trophies.$id.wins.$userId.ts index f843b645a..4e7d4ec8b 100644 --- a/app/features/trophies/routes/trophies.$id.wins.$userId.ts +++ b/app/features/trophies/routes/trophies.$id.wins.$userId.ts @@ -1,23 +1,17 @@ import type { LoaderFunctionArgs } from "react-router"; import * as R from "remeda"; import * as v from "valibot"; -import { getUser } from "~/features/auth/core/user.server"; import * as UserCardRepository from "~/features/user-card/UserCardRepository.server"; import type { SerializeFrom } from "~/utils/remix"; import { parseParams } from "~/utils/remix.server"; import { id } from "~/utils/schema"; import * as TrophyRepository from "../TrophyRepository.server"; -import { canAccessTrophies } from "../trophies-utils"; export type TrophyWinsLoaderData = SerializeFrom; const paramsSchema = v.object({ id, userId: id }); export const loader = async ({ params }: LoaderFunctionArgs) => { - if (!canAccessTrophies(getUser())) { - throw new Response(null, { status: 404 }); - } - const { id: trophyId, userId } = parseParams({ params, schema: paramsSchema, diff --git a/app/features/trophies/routes/trophies.module.css b/app/features/trophies/routes/trophies.module.css index bc2964e85..15601da20 100644 --- a/app/features/trophies/routes/trophies.module.css +++ b/app/features/trophies/routes/trophies.module.css @@ -13,4 +13,23 @@ display: flex; flex-direction: column; gap: var(--s-4); + margin-bottom: var(--s-4); +} + +.xpTrophies { + display: flex; + flex-direction: column; + gap: var(--s-2); +} + +.xpRow { + display: grid; + grid-template-columns: repeat(var(--trophy-grid-columns, auto-fit), 100px); + justify-content: center; + align-items: center; + gap: var(--s-2); + + & > a { + display: block; + } } diff --git a/app/features/trophies/routes/trophies.new.test.ts b/app/features/trophies/routes/trophies.new.test.ts deleted file mode 100644 index ed37635a7..000000000 --- a/app/features/trophies/routes/trophies.new.test.ts +++ /dev/null @@ -1,95 +0,0 @@ -import { beforeEach, describe, expect, test, vi } from "vitest"; -import { REGULAR_USER_TEST_ID } from "~/db/seed/constants"; -import * as TournamentOrganizationFactory from "~/db/seed/factories/TournamentOrganizationFactory"; -import * as TrophyFactory from "~/db/seed/factories/TrophyFactory"; -import * as UserFactory from "~/db/seed/factories/UserFactory"; -import { ADMIN_ID } from "~/features/admin/admin-constants"; -import { decompressFromBase64 } from "~/utils/compression"; -import { wrappedAction, wrappedLoader } from "~/utils/Test"; -import { action } from "../actions/trophies.new.server"; -import { - loader, - type NewTrophyLoaderData, -} from "../loaders/trophies.new.server"; -import * as TrophyRepository from "../TrophyRepository.server"; -import type { trophyFormSchema } from "../trophies-schemas"; - -// remove file once feature is released - -vi.mock("~/features/trophies/trophies-constants", async (importOriginal) => ({ - ...(await importOriginal< - typeof import("~/features/trophies/trophies-constants") - >()), - TROPHIES_RELEASED: false, -})); - -const newTrophyLoader = wrappedLoader({ loader }); -const submitAction = wrappedAction({ - action, - isJsonSubmission: true, -}); - -describe("trophy submissions before release", () => { - beforeEach(async () => { - await UserFactory.createAdmin(); - await UserFactory.createRegular(); - }); - - test("a regular user can open the submission page", async () => { - const data = await newTrophyLoader({ user: "regular" }); - - expect(data.canReview).toBe(false); - expect(data.currentUserId).toBe(REGULAR_USER_TEST_ID); - }); - - test("a regular user can submit a trophy", async () => { - const organization = await TournamentOrganizationFactory.create({ - ownerId: ADMIN_ID, - }); - - const result = await submitAction( - { - _action: "CREATE", - name: "Regular Trophy", - model: decompressFromBase64(TrophyFactory.MODELS[0]) ?? "", - organizationId: organization.id, - description: null, - }, - { user: "regular" }, - ); - - expect(result).toBe(null); - - const pending = - await TrophyRepository.pendingBySubmitter(REGULAR_USER_TEST_ID); - expect(pending.length).toBe(1); - expect(pending[0].name).toBe("Regular Trophy"); - expect(pending[0].creatorId).toBe(REGULAR_USER_TEST_ID); - }); - - test("a submission can name someone else as the creator", async () => { - const organization = await TournamentOrganizationFactory.create({ - ownerId: ADMIN_ID, - }); - const artist = await UserFactory.create(); - - const result = await submitAction( - { - _action: "CREATE", - name: "Commissioned Trophy", - model: decompressFromBase64(TrophyFactory.MODELS[0]) ?? "", - organizationId: organization.id, - creatorId: artist.id, - description: null, - }, - { user: "regular" }, - ); - - expect(result).toBe(null); - - const pending = - await TrophyRepository.pendingBySubmitter(REGULAR_USER_TEST_ID); - expect(pending[0].creatorId).toBe(artist.id); - expect(pending[0].creator?.id).toBe(artist.id); - }); -}); diff --git a/app/features/trophies/routes/trophies.new.tsx b/app/features/trophies/routes/trophies.new.tsx index 10ffbe091..bec03af2c 100644 --- a/app/features/trophies/routes/trophies.new.tsx +++ b/app/features/trophies/routes/trophies.new.tsx @@ -5,6 +5,7 @@ import * as React from "react"; import { Trans, useTranslation } from "react-i18next"; import { Form, Link, type MetaFunction, useLoaderData } from "react-router"; import { Alert } from "~/components/Alert"; +import { Divider } from "~/components/Divider"; import { SendouButton } from "~/components/elements/Button"; import { SendouDialog } from "~/components/elements/Dialog"; import { OrganizationSearch } from "~/components/elements/OrganizationSearch"; @@ -35,6 +36,7 @@ import { } from "~/utils/urls"; import { action } from "../actions/trophies.new.server"; import { Trophy, TrophyContextProvider } from "../components/Trophy"; +import { TrophyBackfill } from "../components/TrophyBackfill"; import { analyzeTrophyModel, mergePeakRenderStats, @@ -54,7 +56,7 @@ import { } from "../trophies-constants"; import { createTrophyFormSchema, - pendingTrophyActionSchema, + trophyActionSchema, updateTrophyFormSchema, } from "../trophies-schemas"; import { @@ -95,10 +97,13 @@ export default function NewTrophyPage() { {t("trophies:new.tabs.upload")} - {t("trophies:new.tabs.update")} + {t("trophies:new.tabs.manage")} {t("trophies:new.tabs.pending")} @@ -118,16 +123,32 @@ export default function NewTrophyPage() { )} - - {data.ownUnreviewedCount >= TROPHY_PENDING_PER_USER_LIMIT ? ( - - {t("trophies:new.form.limitReached", { - limit: TROPHY_PENDING_PER_USER_LIMIT, - })} - - ) : ( - - )} + +
      + {data.editableTrophies.length > 0 ? ( +
      + {t("trophies:new.manage.update")} + {data.ownUnreviewedCount >= TROPHY_PENDING_PER_USER_LIMIT ? ( + + {t("trophies:new.form.limitReached", { + limit: TROPHY_PENDING_PER_USER_LIMIT, + })} + + ) : ( + + )} +
      + ) : null} + {data.backfillTrophies.length > 0 ? ( +
      + {t("trophies:new.manage.backfill")} + +
      + ) : null} +
      @@ -244,7 +265,7 @@ function NewTrophyForm() { ); } -function UpdateTrophyTab() { +function UpdateTrophySection() { const { t } = useTranslation(["trophies"]); const data = useLoaderData(); const [selectedId, setSelectedId] = React.useState(null); @@ -429,30 +450,10 @@ function ModelField({ {error ? {error} : null} {preview.compressedModel ? ( -
      - {(["light", "dark"] as const).map((theme) => ( -
      - - {t(`trophies:new.form.preview.${theme}`)} - - - -
      - ))} -
      +
      ) : null} @@ -460,6 +461,35 @@ function ModelField({ ); } +function TrophyThemePreviews({ + model, + onRenderStats, +}: { + model: string; + onRenderStats: (stats: RenderStats) => void; +}) { + const { t } = useTranslation(["trophies"]); + + return ( +
      + {(["light", "dark"] as const).map((theme) => ( +
      + + {t(`trophies:new.form.preview.${theme}`)} + + + +
      + ))} +
      + ); +} + function buildModelPreview(model: string) { if (!model) return { compressedModel: "", analysis: null }; @@ -667,7 +697,7 @@ function TrophyListRow({ deferred: boolean; }) { const { t } = useTranslation(["trophies", "common"]); - const { submit, state } = useActionSubmit(pendingTrophyActionSchema); + const { submit, state } = useActionSubmit(trophyActionSchema); const isOwner = pending.submitterUserId === currentUserId; const isDeclined = pending.declinedAt !== null; @@ -713,7 +743,18 @@ function TrophyListRow({ onClose={() => setPreviewOpen(false)} showCloseButton > - + + {analysis ? ( + + ) : null}
      @@ -778,48 +819,11 @@ function TrophyListRow({
      {analysis ? ( -
      - TROPHY_MODEL_RECOMMENDED_MAX_DRAW_CALLS, - })} - > - {t("trophies:new.specs.stats.drawCalls", { - value: drawCalls, - })} - - TROPHY_MODEL_RECOMMENDED_MAX_POLYS, - })} - > - {t("trophies:new.specs.stats.polys", { - value: polyCount, - })} - - TROPHY_MODEL_RECOMMENDED_MAX_EFFECTS, - })} - > - {t("trophies:new.specs.stats.effects", { - value: analysis.effectsCount, - })} - - {!analysis.cameraTargetCentered ? ( - - {t("trophies:new.specs.stats.cameraTargetOff")} - - ) : null} - {!analysis.backgroundIsAlpha ? ( - - {t("trophies:new.specs.stats.backgroundNotAlpha")} - - ) : null} -
      + ) : null} {pending.target ? ( @@ -896,11 +900,70 @@ function TrophyListRow({ ); } +function TrophyRenderStats({ + analysis, + drawCalls, + polyCount, + className, +}: { + analysis: TrophyModelAnalysis; + drawCalls: number; + polyCount: number; + className?: string; +}) { + const { t } = useTranslation(["trophies"]); + + return ( +
      + TROPHY_MODEL_RECOMMENDED_MAX_DRAW_CALLS, + })} + > + {t("trophies:new.specs.stats.drawCalls", { + value: drawCalls, + })} + + TROPHY_MODEL_RECOMMENDED_MAX_POLYS, + })} + > + {t("trophies:new.specs.stats.polys", { + value: polyCount, + })} + + TROPHY_MODEL_RECOMMENDED_MAX_EFFECTS, + })} + > + {t("trophies:new.specs.stats.effects", { + value: analysis.effectsCount, + })} + + {!analysis.cameraTargetCentered ? ( + + {t("trophies:new.specs.stats.cameraTargetOff")} + + ) : null} + {!analysis.backgroundIsAlpha ? ( + + {t("trophies:new.specs.stats.backgroundNotAlpha")} + + ) : null} +
      + ); +} + function DeclineButton({ pendingTrophyId }: { pendingTrophyId: number }) { const { t } = useTranslation(["trophies"]); const [isOpen, setIsOpen] = React.useState(false); const [reason, setReason] = React.useState(""); - const { submit, fetcher } = useActionSubmit(pendingTrophyActionSchema); + const { submit, fetcher } = useActionSubmit(trophyActionSchema); const id = React.useId(); React.useEffect(() => { diff --git a/app/features/trophies/routes/trophies.tsx b/app/features/trophies/routes/trophies.tsx index ffad6da75..c15bb907b 100644 --- a/app/features/trophies/routes/trophies.tsx +++ b/app/features/trophies/routes/trophies.tsx @@ -8,6 +8,8 @@ import { Outlet, useLoaderData, } from "react-router"; +import * as R from "remeda"; +import { Divider } from "~/components/Divider"; import { Input } from "~/components/Input"; import { Main } from "~/components/Main"; import type { SendouRouteHandle } from "~/utils/remix.server"; @@ -18,6 +20,7 @@ import { TrophyContextProvider, TrophyGrid, } from "../components/Trophy"; +import * as XpTrophy from "../core/XpTrophy"; import { loader } from "../loaders/trophies.server"; import { hasUpcomingTournamentSoon, @@ -96,6 +99,7 @@ export default function TrophiesPage() {
      +

      {t("trophies:lookingForBadges")}{" "} {t("trophies:viewBadges")} @@ -104,3 +108,58 @@ export default function TrophiesPage() { ); } + +function XpTrophiesSection({ searchValue }: { searchValue: string }) { + const { t } = useTranslation(["trophies", "common"]); + const data = useLoaderData(); + + const filteredTrophies = data.xpTrophies.filter((trophy) => + trophy.name.toLowerCase().includes(searchValue), + ); + const visibleCount = useProgressiveRender( + filteredTrophies.length, + `xp-${searchValue}`, + ); + + if (filteredTrophies.length === 0) return null; + + const rows = Object.values( + R.groupBy( + filteredTrophies.map((trophy, i) => ({ trophy, i })), + ({ trophy }) => XpTrophy.parseCode(trophy.code)?.category ?? "", + ), + ); + + return ( +

      + {t("trophies:xp.title")} + +
      + {rows.map((row) => { + const category = XpTrophy.parseCode(row[0].trophy.code)?.category; + if (!category) return null; + + return ( +
      + {row.map(({ trophy, i }) => ( + + = visibleCount} + /> + + ))} +
      + ); + })} +
      +
      +
      + ); +} diff --git a/app/features/trophies/trophies-constants.ts b/app/features/trophies/trophies-constants.ts index 3bbc7652c..b38f0b018 100644 --- a/app/features/trophies/trophies-constants.ts +++ b/app/features/trophies/trophies-constants.ts @@ -3,7 +3,7 @@ export const TROPHY_NAME_MAX_LENGTH = 32; export const TROPHY_MODEL_MAX_LENGTH = 1024 * 1024; export const TROPHY_MODEL_RECOMMENDED_MAX_DRAW_CALLS = 15; -export const TROPHY_MODEL_RECOMMENDED_MAX_POLYS = 3000; +export const TROPHY_MODEL_RECOMMENDED_MAX_POLYS = 5000; export const TROPHY_MODEL_RECOMMENDED_MAX_EFFECTS = 5; export const TROPHY_APPROVALS_REQUIRED = 3; @@ -18,8 +18,3 @@ export const TROPHY_PENDING_PER_USER_LIMIT = 5; export const SMALL_TROPHIES_PER_DISPLAY_PAGE = 6; export const TROPHY_UPCOMING_HIGHLIGHT_WEEKS = 4; - -export const TROPHIES_RELEASED = false; - -export const SUPPORTER_TROPHY_CODE = "supporter"; -export const XP_TROPHY_CODE_PREFIX = "xp-"; diff --git a/app/features/trophies/trophies-schemas.ts b/app/features/trophies/trophies-schemas.ts index a23c19af3..9168db4c7 100644 --- a/app/features/trophies/trophies-schemas.ts +++ b/app/features/trophies/trophies-schemas.ts @@ -5,7 +5,13 @@ import { textAreaOptional, textField, } from "~/form/fields"; -import { _action, id, superRefine } from "~/utils/schema"; +import { + _action, + id, + preprocess, + safeJSONParse, + superRefine, +} from "~/utils/schema"; import { analyzeTrophyModel } from "./core/model-analysis"; import { TROPHY_DECLINE_REASON_MAX_LENGTH, @@ -86,7 +92,22 @@ export const trophyFormSchema = v.variant("_action", [ updateTrophyFormSchema, ]); -export const pendingTrophyActionSchema = v.union([ +const trophyBackfillAwards = v.pipe( + v.array( + v.object({ + tournamentId: id, + userIds: v.pipe(v.array(id), v.minLength(1), v.maxLength(50)), + }), + ), + v.minLength(1), + v.check( + (awards) => + new Set(awards.map((award) => award.tournamentId)).size === awards.length, + "Duplicate tournament", + ), +); + +export const trophyActionSchema = v.union([ v.object({ _action: _action("DELETE"), pendingTrophyId: id, @@ -105,4 +126,10 @@ export const pendingTrophyActionSchema = v.union([ _action: _action("APPROVE"), pendingTrophyId: id, }), + v.object({ + _action: _action("BACKFILL"), + trophyId: id, + seriesId: id, + awards: preprocess(safeJSONParse, trophyBackfillAwards), + }), ]); diff --git a/app/features/trophies/trophies-utils.test.ts b/app/features/trophies/trophies-utils.test.ts index 36539f5ba..65fa1b1b0 100644 --- a/app/features/trophies/trophies-utils.test.ts +++ b/app/features/trophies/trophies-utils.test.ts @@ -3,7 +3,6 @@ import { beforeEach, describe, expect, test, vi } from "vitest"; import { decompressFromBase64 } from "~/utils/compression"; import { dateToDatabaseTimestamp } from "~/utils/dates"; import { - canAccessTrophies, decompressTrophyModel, hasUpcomingTournamentSoon, } from "./trophies-utils"; @@ -13,12 +12,6 @@ vi.mock("~/utils/compression", () => ({ decompressFromBase64: vi.fn((_compressed: string): string | null => null), })); -// pinned to unreleased so the role gating stays covered whatever the real flag says -vi.mock("./trophies-constants", async (importOriginal) => ({ - ...(await importOriginal()), - TROPHIES_RELEASED: false, -})); - const decompressMock = vi.mocked(decompressFromBase64); const ENTRY_CHARS = 3_500_000; @@ -68,25 +61,6 @@ describe("decompressTrophyModel", () => { }); }); -describe("canAccessTrophies (before release)", () => { - test("true for admin", () => { - expect(canAccessTrophies({ roles: ["ADMIN"] })).toBe(true); - }); - - test("true for QA", () => { - expect(canAccessTrophies({ roles: ["QA"] })).toBe(true); - }); - - test("false for staff", () => { - expect(canAccessTrophies({ roles: ["STAFF"] })).toBe(false); - }); - - test("false for regular and logged out users", () => { - expect(canAccessTrophies({ roles: [] })).toBe(false); - expect(canAccessTrophies(null)).toBe(false); - }); -}); - describe("hasUpcomingTournamentSoon", () => { test("false for a trophy without an upcoming tournament", () => { expect(hasUpcomingTournamentSoon(null)).toBe(false); diff --git a/app/features/trophies/trophies-utils.ts b/app/features/trophies/trophies-utils.ts index 6aa867e64..243bd5187 100644 --- a/app/features/trophies/trophies-utils.ts +++ b/app/features/trophies/trophies-utils.ts @@ -1,41 +1,67 @@ import { addWeeks } from "date-fns"; +import type { RawPicoCAD2File } from "picocad2-web"; import { useEffect, useRef, useState, useSyncExternalStore } from "react"; import type { Role } from "~/modules/permissions/types"; import { compressToBase64, decompressFromBase64 } from "~/utils/compression"; import { databaseTimestampToDate } from "~/utils/dates"; -import { - SUPPORTER_TROPHY_CODE, - TROPHIES_RELEASED, - TROPHY_UPCOMING_HIGHLIGHT_WEEKS, - XP_TROPHY_CODE_PREFIX, -} from "./trophies-constants"; +import * as XpTrophy from "./core/XpTrophy"; +import { TROPHY_UPCOMING_HIGHLIGHT_WEEKS } from "./trophies-constants"; const TERMS_AGREED_SESSION_STORAGE_KEY = "trophyTermsAgreed"; const DECOMPRESSED_MODEL_CACHE_MAX_CHARS = 16 * 1024 * 1024; -type SpecialTrophyKind = { type: "supporter" } | { type: "xp"; value: number }; +let xpTrophyMaster: RawPicoCAD2File | null = null; +let xpTrophyMasterLoading: Promise | null = null; +const xpTrophyMasterListeners = new Set<() => void>(); +const xpTrophyStates = new Map(); -export function parseSpecialTrophyCode( - code: string | null | undefined, -): SpecialTrophyKind | null { - if (!code) return null; - if (code === SUPPORTER_TROPHY_CODE) return { type: "supporter" }; +// Downloads and parses the master file containing ALL XP trophies to create a model file for the requested variant. +// We get an overall smaller file size and better performance with this. +export function useXpTrophyState(variant: XpTrophy.Variant | null) { + const master = useSyncExternalStore( + variant ? subscribeToXpTrophyMaster : subscribeToNothing, + () => xpTrophyMaster, + () => null, + ); + if (!variant || !master) return null; - if (code.startsWith(XP_TROPHY_CODE_PREFIX)) { - const value = Number(code.slice(XP_TROPHY_CODE_PREFIX.length)); - if (Number.isFinite(value)) return { type: "xp", value }; - } + const code = XpTrophy.code(variant); + const cached = xpTrophyStates.get(code); + if (cached) return cached; - return null; + const state = JSON.stringify(XpTrophy.variantState(master, variant)); + xpTrophyStates.set(code, state); + return state; } -/** Feature flag */ -export function canAccessTrophies(user?: { roles: Array } | null) { - if (TROPHIES_RELEASED) return true; +function subscribeToXpTrophyMaster(listener: () => void) { + xpTrophyMasterListeners.add(listener); + + if (!xpTrophyMasterLoading) { + xpTrophyMasterLoading = import("./data/xp-trophies-master.txt?raw") + .then(({ default: raw }) => { + xpTrophyMaster = JSON.parse(raw); + for (const notify of xpTrophyMasterListeners) notify(); + }) + .catch(() => { + xpTrophyMasterLoading = null; + }); + } + + return () => { + xpTrophyMasterListeners.delete(listener); + }; +} + +function subscribeToNothing() { + return () => {}; +} + +export function canBackfillTrophies(user?: { roles: Array } | null) { if (!user) return false; - return user.roles.includes("ADMIN") || user.roles.includes("QA"); + return user.roles.includes("ADMIN") || user.roles.includes("DEV"); } export function canReviewTrophies(user?: { roles: Array } | null) { @@ -44,12 +70,6 @@ export function canReviewTrophies(user?: { roles: Array } | null) { return user.roles.includes("STAFF") || user.roles.includes("QA"); } -export function canEditAnyTrophy(user?: { roles: Array } | null) { - if (!user) return false; - - return user.roles.includes("ADMIN"); -} - export function hasUpcomingTournamentSoon( upcomingTournamentAt: number | null | undefined, ) { diff --git a/app/features/user-page/core/widgets/portfolio-loaders.server.ts b/app/features/user-page/core/widgets/portfolio-loaders.server.ts index b08044747..5bbefa89b 100644 --- a/app/features/user-page/core/widgets/portfolio-loaders.server.ts +++ b/app/features/user-page/core/widgets/portfolio-loaders.server.ts @@ -15,7 +15,6 @@ import * as TeamRepository from "~/features/team/TeamRepository.server"; import * as XRankPlacementRepository from "~/features/top-search/XRankPlacementRepository.server"; import * as TournamentOrganizationRepository from "~/features/tournament-organization/TournamentOrganizationRepository.server"; import * as TrophyRepository from "~/features/trophies/TrophyRepository.server"; -import { canAccessTrophies } from "~/features/trophies/trophies-utils"; import * as UserRepository from "~/features/user-page/UserRepository.server"; import * as VodRepository from "~/features/vods/VodRepository.server"; import { modesShort } from "~/modules/in-game-lists/modes"; @@ -25,8 +24,6 @@ import { cachedUserSQLeaderboardTopData } from "./utils.server"; export const WIDGET_LOADERS = { "trophies-owned": async (userId: number) => { - if (!canAccessTrophies(getUser())) return []; - return TrophyRepository.findByOwnerUserId(userId); }, "badges-owned": async ( diff --git a/app/features/user-page/loaders/u.$identifier.edit.server.ts b/app/features/user-page/loaders/u.$identifier.edit.server.ts index 5ecdcab9a..4eb19f9ea 100644 --- a/app/features/user-page/loaders/u.$identifier.edit.server.ts +++ b/app/features/user-page/loaders/u.$identifier.edit.server.ts @@ -1,7 +1,6 @@ import { redirect } from "react-router"; import { requireUser } from "~/features/auth/core/user.server"; import * as TrophyRepository from "~/features/trophies/TrophyRepository.server"; -import { canAccessTrophies } from "~/features/trophies/trophies-utils"; import * as UserRepository from "~/features/user-page/UserRepository.server"; import { userPageUser } from "~/features/user-page/user-page-context.server"; import { userPage } from "~/utils/urls"; @@ -17,9 +16,9 @@ export const loader = async () => { const friendCodeResult = await UserRepository.findCurrentFriendCodeByUserId( user.id, ); - const ownedTrophies = canAccessTrophies(user) - ? await TrophyRepository.findByOwnerUserIdIncludingHidden(user.id) - : []; + const ownedTrophies = await TrophyRepository.findByOwnerUserIdIncludingHidden( + user.id, + ); return { user: userProfile, diff --git a/app/hooks/useDragToScroll.browser.test.ts b/app/hooks/useDragToScroll.browser.test.ts index 1152bf3ff..5d255f7b5 100644 --- a/app/hooks/useDragToScroll.browser.test.ts +++ b/app/hooks/useDragToScroll.browser.test.ts @@ -43,7 +43,12 @@ function setUpScrollableElement({ scrollSnap = false } = {}) { function mouseDownOn(element: HTMLElement, clientX: number, clientY: number) { element.dispatchEvent( - new MouseEvent("mousedown", { buttons: 1, clientX, clientY }), + new MouseEvent("mousedown", { + buttons: 1, + clientX, + clientY, + bubbles: true, + }), ); } @@ -136,6 +141,43 @@ describe("dragToScroll", () => { expect(onClick).toHaveBeenCalledTimes(1); }); + test.each([ + { why: "popover", overlayTag: "div", overlayAttribute: "popover" }, + { why: "dialog", overlayTag: "dialog", overlayAttribute: null }, + ])( + "ignores drags that start inside a nested $why", + ({ overlayTag, overlayAttribute }) => { + const { element, child } = setUpScrollableElement(); + const overlay = document.createElement(overlayTag); + if (overlayAttribute) overlay.setAttribute(overlayAttribute, "auto"); + const overlayContent = document.createElement("canvas"); + overlay.appendChild(overlayContent); + child.appendChild(overlay); + + mouseDownOn(overlayContent, 50, 50); + mouseMoveTo(20, 40); + mouseUp(); + + expect(element.scrollLeft).toBe(0); + expect(element.scrollTop).toBe(0); + }, + ); + + test("scrolls when the element itself sits inside a dialog", () => { + const dialog = document.createElement("dialog"); + document.body.appendChild(dialog); + cleanupFns.push(() => dialog.remove()); + const { element } = setUpScrollableElement(); + dialog.appendChild(element); + dialog.show(); + + mouseDownOn(element, 50, 50); + mouseMoveTo(20, 40); + mouseUp(); + + expect(element.scrollLeft).toBe(30); + }); + test("stops reacting to the mouse after cleanup", () => { const { element, detach } = setUpScrollableElement(); diff --git a/app/hooks/useDragToScroll.ts b/app/hooks/useDragToScroll.ts index 1f1ee9ff1..ff61a27a0 100644 --- a/app/hooks/useDragToScroll.ts +++ b/app/hooks/useDragToScroll.ts @@ -71,6 +71,7 @@ export function dragToScroll(element: HTMLElement): () => void { const onMouseDown = (event: MouseEvent) => { suppressNextClick = false; if (event.buttons !== 1) return; + if (isInsideNestedOverlay(element, event.target)) return; cancelAnimationFrame(momentumFrame); isMouseDown = true; @@ -181,6 +182,16 @@ export function dragToScroll(element: HTMLElement): () => void { }; } +function isInsideNestedOverlay( + element: HTMLElement, + target: EventTarget | null, +) { + if (!(target instanceof Element)) return false; + + const overlay = target.closest("[popover], dialog"); + return overlay !== null && overlay !== element && element.contains(overlay); +} + function createGrabbingCursorStyle() { const style = document.createElement("style"); style.textContent = "* { cursor: grabbing !important; }"; diff --git a/app/modules/patreon/updater.ts b/app/modules/patreon/updater.ts index 5508b5a14..7408931dc 100644 --- a/app/modules/patreon/updater.ts +++ b/app/modules/patreon/updater.ts @@ -1,7 +1,6 @@ import * as v from "valibot"; import { ServerConfig } from "~/config.server"; import { STAFF_DISCORD_IDS } from "~/features/admin/admin-constants"; -import * as TrophyRepository from "~/features/trophies/TrophyRepository.server"; import * as UserRepository from "~/features/user-page/UserRepository.server"; import { dateToDatabaseTimestamp } from "~/utils/dates"; import { fetchWithTimeout } from "~/utils/fetch"; @@ -47,7 +46,6 @@ export async function updatePatreonData(): Promise { ]; await UserRepository.updatePatronData(patronsWithMods); - await TrophyRepository.syncSpecialTrophies(); } const MAX_RETRIES = 10; diff --git a/app/routes.ts b/app/routes.ts index a5182df00..630fced1c 100644 --- a/app/routes.ts +++ b/app/routes.ts @@ -139,6 +139,14 @@ export default [ "/trophies/:id/tournaments", "features/trophies/routes/trophies.$id.tournaments.ts", ), + route( + "/trophies/:id/placements/:userId", + "features/trophies/routes/trophies.$id.placements.$userId.ts", + ), + route( + "/trophies/:id/backfill/:seriesId", + "features/trophies/routes/trophies.$id.backfill.$seriesId.ts", + ), route("/trophies", "features/trophies/routes/trophies.tsx", [ route(":id", "features/trophies/routes/trophies.$id.tsx"), ]), diff --git a/app/styles/front.module.css b/app/styles/front.module.css index 351a7d9f7..1dca88e47 100644 --- a/app/styles/front.module.css +++ b/app/styles/front.module.css @@ -140,6 +140,7 @@ margin-block-start: -6px; margin-inline-start: -6px; overflow-x: auto; + overflow-y: hidden; } .tournamentCardsViewAllCard { diff --git a/app/utils/kysely.server.ts b/app/utils/kysely.server.ts index 589b97550..6d1b4e856 100644 --- a/app/utils/kysely.server.ts +++ b/app/utils/kysely.server.ts @@ -266,6 +266,15 @@ export function calendarEventStartTime( .whereRef("CalendarEventDate.eventId", "=", "CalendarEvent.id"); } +export function calendarEventNameMatchesSeries(substringMatches: string[]) { + return (eb: ExpressionBuilder) => + eb.or( + substringMatches.map((match) => + eb("CalendarEvent.name", "like", `%${match}%`), + ), + ); +} + /** Subquery counting a tournament's non-placeholder teams. Correlates on `"Tournament"."id"`. */ export function tournamentTeamCount( eb: ExpressionBuilder, diff --git a/app/utils/urls.ts b/app/utils/urls.ts index a32fffe42..d80804c60 100644 --- a/app/utils/urls.ts +++ b/app/utils/urls.ts @@ -241,8 +241,16 @@ export const trophyPage = (trophyId: number) => `${TROPHIES_PAGE}/${trophyId}`; export const trophyWinsPage = (args: { trophyId: number; userId: number }) => `${TROPHIES_PAGE}/${args.trophyId}/wins/${args.userId}`; +export const trophyPlacementsPage = (args: { + trophyId: number; + userId: number; +}) => `${TROPHIES_PAGE}/${args.trophyId}/placements/${args.userId}`; export const trophyTournamentsPage = (trophyId: number) => `${TROPHIES_PAGE}/${trophyId}/tournaments`; +export const trophyBackfillPage = (args: { + trophyId: number; + seriesId: number; +}) => `${TROPHIES_PAGE}/${args.trophyId}/backfill/${args.seriesId}`; export interface UserLinkArgs { discordId: Tables["User"]["discordId"]; diff --git a/e2e/pages/trophies/new-trophy-page.ts b/e2e/pages/trophies/new-trophy-page.ts index 965de65c6..1f47bcfd5 100644 --- a/e2e/pages/trophies/new-trophy-page.ts +++ b/e2e/pages/trophies/new-trophy-page.ts @@ -19,6 +19,7 @@ export class NewTrophyPage { agreeToTermsButton: page.getByRole("button", { name: "I have read and agree", }), + manageTab: page.getByRole("tab", { name: "Manage" }), pendingTab: page.getByRole("tab", { name: "Pending" }), reviewedTab: page.getByRole("tab", { name: "Reviewed" }), }; @@ -61,6 +62,11 @@ export class NewTrophyPage { return submit(this.page); } + async openBackfill() { + await this.locators.manageTab.click(); + return new TrophyBackfillSection(this.page); + } + async openPending() { await this.locators.pendingTab.click(); return new PendingTrophyList(this.page); @@ -103,3 +109,58 @@ class PendingTrophyList { ); } } + +class TrophyBackfillSection { + private readonly page: Page; + readonly locators; + + constructor(page: Page) { + this.page = page; + this.locators = { + trophySelect: page.getByTestId("backfill-trophy-select"), + seriesSelect: page.getByTestId("backfill-series-select"), + awardButton: page.getByTestId("backfill-submit-button"), + }; + } + + async selectTrophy(name: string) { + await this.locators.trophySelect.click(); + await this.page.getByRole("option", { name, exact: true }).click(); + } + + async selectSeries(name: string) { + await this.locators.seriesSelect.click(); + await this.page.getByRole("option", { name, exact: true }).click(); + } + + tournament(name: string) { + return this.page + .getByTestId("backfill-tournament") + .filter({ hasText: name }); + } + + toggleTournament(name: string) { + return this.tournament(name) + .getByRole("switch", { name, exact: true }) + .click({ force: true }); + } + + toggleWinner({ + tournamentName, + username, + }: { + tournamentName: string; + username: string; + }) { + return this.tournament(tournamentName) + .getByRole("switch", { name: username, exact: true }) + .click({ force: true }); + } + + async award() { + await this.locators.awardButton.click(); + await waitForPOSTResponse(this.page, () => + this.page.getByTestId("confirm-button").click(), + ); + } +} diff --git a/e2e/pages/trophies/trophies-page.ts b/e2e/pages/trophies/trophies-page.ts index 04352fac4..6e77f7ae8 100644 --- a/e2e/pages/trophies/trophies-page.ts +++ b/e2e/pages/trophies/trophies-page.ts @@ -13,6 +13,7 @@ export class TrophiesPage { searchInput: page.getByRole("textbox"), // the "Add new" menu links to /trophies/new from every page trophyLinks: page.locator("main").locator("a[href^='/trophies/']"), + xpSection: page.getByTestId("xp-trophies"), }; } @@ -38,10 +39,22 @@ export class TrophiesPage { return this.tile(trophyId).getByTestId("trophy-corner-pill"); } + async openXpTrophy(name: string) { + await this.locators.xpSection + .getByRole("link", { name, exact: true }) + .click(); + return new TrophyDetailsPage(this.page); + } + async openFirst() { await this.locators.trophyLinks.first().click(); return new TrophyDetailsPage(this.page); } + + async gotoTrophy(trophyId: number) { + await navigate({ page: this.page, url: trophyPage(trophyId) }); + return new TrophyDetailsPage(this.page); + } } /** `/trophies/:id` */ @@ -54,9 +67,16 @@ class TrophyDetailsPage { this.locators = { ownersHeading: page.getByText("Owners", { exact: true }), ownerLinks: page.locator("main").locator("a[href^='/u/']"), + weaponCounts: page.getByTestId("trophy-weapons").getByRole("listitem"), }; } + owner(username: string) { + return this.page + .getByTestId("trophy-owners") + .getByRole("link", { name: username, exact: true }); + } + tournamentRow(tournamentId: number) { return this.page.locator("main").locator(`a[href='/to/${tournamentId}']`); } diff --git a/e2e/pages/user/user-page.ts b/e2e/pages/user/user-page.ts index 736d13ebc..fc5a1d1e5 100644 --- a/e2e/pages/user/user-page.ts +++ b/e2e/pages/user/user-page.ts @@ -25,6 +25,10 @@ export class UserPage { vodsTab: page.locator('[data-testid="user-vods-tab"]:visible'), resultsTab: page.locator('[data-testid="user-results-tab"]:visible'), seasonsTournamentResult: page.getByTestId("seasons-tournament-result"), + trophyDisplay: page.getByTestId("trophy-display"), + trophyPlacementRows: page + .getByRole("dialog") + .getByTestId("trophy-placement"), }; } @@ -37,6 +41,20 @@ export class UserPage { await navigate({ page: this.page, url: `/u/${identifier}` }); } + openTrophy(name: string) { + return this.locators.trophyDisplay + .getByRole("button", { name, exact: true }) + .click(); + } + + trophyDivision(trophyName: string, divisionName: string) { + return this.locators.trophyDisplay + .getByRole("button", { name: trophyName, exact: true }) + .getByTestId("trophy-corner-pill") + .getByAltText(divisionName) + .filter({ visible: true }); + } + badgeImage(displayName: string) { return this.page.getByAltText(displayName, { exact: true }); } diff --git a/e2e/trophies.spec.ts b/e2e/trophies.spec.ts index 6ddd88c49..9e6848d26 100644 --- a/e2e/trophies.spec.ts +++ b/e2e/trophies.spec.ts @@ -1,10 +1,9 @@ import { addDays, subDays } from "date-fns"; -import { NZAP_TEST_ID } from "~/db/seed/constants"; +import { NZAP_TEST_DISCORD_ID, NZAP_TEST_ID } from "~/db/seed/constants"; import { ADMIN_DISCORD_ID, ADMIN_ID } from "~/features/admin/admin-constants"; import { TROPHY_APPROVALS_REQUIRED } from "~/features/trophies/trophies-constants"; import { decompressFromBase64 } from "~/utils/compression"; import { dateToDatabaseTimestamp } from "~/utils/dates"; -import { TROPHIES_PAGE } from "~/utils/urls"; import type { Factories } from "./helpers/factories"; import { expect, @@ -26,27 +25,6 @@ const ROSTER_SIZE = 4; const UPCOMING_IN_DAYS = 10; test.describe("Trophies", () => { - test("hides trophies from users without early access", async ({ - page, - factories, - }) => { - await factories.TrophyFactory.create({ name: TROPHY_NAME }); - - await impersonate(page, NZAP_TEST_ID); - - const response = await page.goto(TROPHIES_PAGE); - expect(response?.status()).toBe(404); - - const userPage = new UserPage(page); - await userPage.goto(ADMIN_DISCORD_ID); - await isNotVisible(page.getByTestId("trophy-display")); - - // remove once feature is released - const newTrophy = new NewTrophyPage(page); - await newTrophy.goto(); - await expect(newTrophy.locators.agreeToTermsButton).toBeVisible(); - }); - test("shows trophy wins via user page trophy display", async ({ page, factories, @@ -54,12 +32,14 @@ test.describe("Trophies", () => { test.slow(); const trophy = await factories.TrophyFactory.create({ name: TROPHY_NAME }); - const tournament = await playTrophyTournament(factories, trophy.id); + const tournament = await playTrophyTournament(factories, { + trophyId: trophy.id, + }); await factories.UserFactory.grant(ADMIN_ID, { widgets: [{ id: "trophies-owned" }], }); - await impersonate(page); + await impersonate(page, NZAP_TEST_ID); const userPage = new UserPage(page); await userPage.goto(ADMIN_DISCORD_ID); @@ -95,7 +75,10 @@ test.describe("Trophies", () => { name: "Chris P. Bacon", }); - await playTrophyTournament(factories, trophy.id, organization.id); + await playTrophyTournament(factories, { + trophyId: trophy.id, + organizationId: organization.id, + }); const upcoming = await factories.TournamentFactory.create({ name: `${TROPHY_NAME} 2`, authorId: ADMIN_ID, @@ -106,7 +89,7 @@ test.describe("Trophies", () => { trophyId: trophy.id, }); - await impersonate(page); + await impersonate(page, NZAP_TEST_ID); const trophies = new TrophiesPage(page); await trophies.goto(); @@ -227,13 +210,128 @@ test.describe("Trophies", () => { notifications.notification(`Your trophy ${declinedName} was declined`), ).toBeVisible(); }); + + test("backfills a trophy to the winners of a past tournament", async ({ + page, + factories, + }) => { + test.slow(); + + const seriesName = "Wellstring"; + const organization = await factories.TournamentOrganizationFactory.create( + { name: ORGANIZATION_NAME, ownerId: ADMIN_ID }, + { + series: [ + { name: seriesName, description: null, showLeaderboard: false }, + ], + }, + ); + const trophy = await factories.TrophyFactory.create({ + name: TROPHY_NAME, + organizationId: organization.id, + managerId: ADMIN_ID, + }); + + const awardedName = `${TROPHY_NAME} 1`; + const skippedName = `${TROPHY_NAME} 2`; + const awarded = await playTrophyTournament(factories, { + organizationId: organization.id, + name: awardedName, + }); + const skipped = await playTrophyTournament(factories, { + organizationId: organization.id, + name: skippedName, + }); + + await impersonate(page); + + const newTrophy = new NewTrophyPage(page); + await newTrophy.goto(); + + const backfill = await newTrophy.openBackfill(); + await backfill.selectTrophy(TROPHY_NAME); + await backfill.selectSeries(seriesName); + + await backfill.toggleTournament(awardedName); + await backfill.toggleWinner({ + tournamentName: awardedName, + username: "Sendou", + }); + await backfill.award(); + + // an awarded tournament can't be backfilled again + await isNotVisible(backfill.tournament(awardedName)); + await expect(backfill.tournament(skippedName)).toBeVisible(); + + const details = await new TrophiesPage(page).gotoTrophy(trophy.id); + await expect(details.tournamentRow(awarded.id)).toBeVisible(); + await isNotVisible(details.tournamentRow(skipped.id)); + await expect(details.owner("N-ZAP")).toBeVisible(); + await isNotVisible(details.owner("Sendou")); + }); + + test("awards X Power trophies per weapon category", async ({ + page, + factories, + }) => { + const SPLATTERSHOT = 40; + const SPLASH_O_MATIC = 20; + const SPLAT_CHARGER = 2010; + for (const [weaponSplId, power, region] of [ + [SPLATTERSHOT, 3550, "WEST"], + [SPLATTERSHOT, 3510, "JPN"], + [SPLASH_O_MATIC, 3120, "WEST"], + [SPLAT_CHARGER, 3050, "WEST"], + ] as const) { + await factories.XRankPlacementFactory.create({ + playerUserId: NZAP_TEST_ID, + weaponSplId, + power, + region, + }); + } + await factories.TrophyFactory.createXpTrophies(); + await factories.UserFactory.grant(NZAP_TEST_ID, { + widgets: [{ id: "trophies-owned" }], + }); + + await impersonate(page, NZAP_TEST_ID); + + const trophies = new TrophiesPage(page); + await trophies.goto(); + const details = await trophies.openXpTrophy("3500 X Power Shooters"); + + await expect(details.owner("N-ZAP")).toBeVisible(); + + // the Splash-o-matic placement fell short of 3500 + await expect(details.locators.weaponCounts).toHaveCount(1); + + const userPage = new UserPage(page); + await userPage.goto(NZAP_TEST_DISCORD_ID); + await expect( + userPage.locators.trophyDisplay.getByRole("button"), + ).toHaveCount(2); + + // reached in both divisions, Takoroka is the one shown + await expect( + userPage.trophyDivision("3500 X Power Shooters", "Takoroka"), + ).toBeVisible(); + await expect( + userPage.trophyDivision("3000 X Power Chargers", "Tentatek"), + ).toBeVisible(); + + await userPage.openTrophy("3500 X Power Shooters"); + await expect(userPage.locators.trophyPlacementRows).toHaveCount(3); + }); }); -/** Plays a tournament with the trophy as its prize, awarding it to the winning team. */ async function playTrophyTournament( factories: Factories, - trophyId: number, - organizationId?: number, + { + trophyId, + organizationId, + name = `${TROPHY_NAME} 1`, + }: { trophyId?: number; organizationId?: number; name?: string }, ) { // the top seed wins, so the anchor users are on it and end up owning the trophy const players = await factories.UserFactory.createMany( @@ -246,7 +344,7 @@ async function playTrophyTournament( return factories.TournamentFactory.createPlayed( { - name: `${TROPHY_NAME} 1`, + name, authorId: ADMIN_ID, organizationId, startTimes: [dateToDatabaseTimestamp(subDays(new Date(), 21))], diff --git a/locales/da/trophies.json b/locales/da/trophies.json index eb513dd24..eb90708cb 100644 --- a/locales/da/trophies.json +++ b/locales/da/trophies.json @@ -9,10 +9,11 @@ "details.noOwners": "", "details.tournamentHistory": "", "details.noTournamentHistory": "", + "details.weapons": "", "details.upcoming": "", "display.viewTrophyPage": "", - "special.supporter.description": "", - "special.xp.description": "", + "special.xp.categoryDescription": "", + "xp.title": "", "new.form.limitReached": "", "new.form.preview.light": "", "new.form.preview.dark": "", @@ -47,7 +48,7 @@ "new.terms.preApproval": "", "new.terms.agree": "", "new.tabs.upload": "", - "new.tabs.update": "", + "new.tabs.manage": "", "new.tabs.pending": "", "new.tabs.reviewed": "", "new.update.selectLabel": "", @@ -55,6 +56,21 @@ "new.update.editing": "", "new.update.before": "", "new.update.after": "", + "new.manage.update": "", + "new.manage.backfill": "", + "new.backfill.explanation": "", + "new.backfill.warning": "", + "new.backfill.trophyLabel": "", + "new.backfill.seriesLabel": "", + "new.backfill.noTrophies": "", + "new.backfill.noTournaments": "", + "new.backfill.selected_one": "", + "new.backfill.selected_other": "", + "new.backfill.noPlayersSelected": "", + "new.backfill.submit": "", + "new.backfill.confirm.heading_one": "", + "new.backfill.confirm.heading_other": "", + "new.backfill.confirm.description": "", "new.pending.empty": "", "new.pending.notFromManager": "", "new.pending.approve": "", diff --git a/locales/de/trophies.json b/locales/de/trophies.json index eb513dd24..eb90708cb 100644 --- a/locales/de/trophies.json +++ b/locales/de/trophies.json @@ -9,10 +9,11 @@ "details.noOwners": "", "details.tournamentHistory": "", "details.noTournamentHistory": "", + "details.weapons": "", "details.upcoming": "", "display.viewTrophyPage": "", - "special.supporter.description": "", - "special.xp.description": "", + "special.xp.categoryDescription": "", + "xp.title": "", "new.form.limitReached": "", "new.form.preview.light": "", "new.form.preview.dark": "", @@ -47,7 +48,7 @@ "new.terms.preApproval": "", "new.terms.agree": "", "new.tabs.upload": "", - "new.tabs.update": "", + "new.tabs.manage": "", "new.tabs.pending": "", "new.tabs.reviewed": "", "new.update.selectLabel": "", @@ -55,6 +56,21 @@ "new.update.editing": "", "new.update.before": "", "new.update.after": "", + "new.manage.update": "", + "new.manage.backfill": "", + "new.backfill.explanation": "", + "new.backfill.warning": "", + "new.backfill.trophyLabel": "", + "new.backfill.seriesLabel": "", + "new.backfill.noTrophies": "", + "new.backfill.noTournaments": "", + "new.backfill.selected_one": "", + "new.backfill.selected_other": "", + "new.backfill.noPlayersSelected": "", + "new.backfill.submit": "", + "new.backfill.confirm.heading_one": "", + "new.backfill.confirm.heading_other": "", + "new.backfill.confirm.description": "", "new.pending.empty": "", "new.pending.notFromManager": "", "new.pending.approve": "", diff --git a/locales/en/trophies.json b/locales/en/trophies.json index 26005b172..a3f2079a3 100644 --- a/locales/en/trophies.json +++ b/locales/en/trophies.json @@ -9,10 +9,11 @@ "details.noOwners": "No owners yet", "details.tournamentHistory": "Tournaments", "details.noTournamentHistory": "No tournament history", + "details.weapons": "Weapons", "details.upcoming": "Upcoming", "display.viewTrophyPage": "View trophy page", - "special.supporter.description": "Awarded for supporting sendou.ink", - "special.xp.description": "Awarded for reaching {{value}} X Power", + "special.xp.categoryDescription": "Awarded for reaching {{value}} X Power with {{category}}", + "xp.title": "X Power trophies", "new.form.limitReached": "You have reached the limit of {{limit}} pending trophies. Delete or wait for an existing submission to be reviewed before submitting another.", "new.form.preview.light": "Light mode", "new.form.preview.dark": "Dark mode", @@ -47,7 +48,7 @@ "new.terms.preApproval": "If you are unsure if your tournament is eligible, feel free to acquire a pre-approval by creating a pre-approval request in the <1>Discord server.", "new.terms.agree": "I have read and agree", "new.tabs.upload": "Upload", - "new.tabs.update": "Update", + "new.tabs.manage": "Manage", "new.tabs.pending": "Pending", "new.tabs.reviewed": "Reviewed", "new.update.selectLabel": "Trophy to update", @@ -55,6 +56,21 @@ "new.update.editing": "Editing existing trophy", "new.update.before": "Before", "new.update.after": "After", + "new.manage.update": "Update", + "new.manage.backfill": "Backfill", + "new.backfill.explanation": "Award a trophy to the winners of past tournaments in its series that were held without a trophy. Only the winning team of the top division is shown. Players who did not play a single set are hidden.", + "new.backfill.warning": "Awarding a trophy can not be undone. Trophies can not be taken away once awarded, so double check the tournaments and players you select.", + "new.backfill.trophyLabel": "Trophy to award", + "new.backfill.seriesLabel": "Tournament series", + "new.backfill.noTrophies": "None of your trophies belong to an organization with a tournament series", + "new.backfill.noTournaments": "Every past tournament of this series already has a trophy", + "new.backfill.selected_one": "{{count}} tournament selected ({{playerCount}} players)", + "new.backfill.selected_other": "{{count}} tournaments selected ({{playerCount}} players)", + "new.backfill.noPlayersSelected": "Select at least one player for every selected tournament", + "new.backfill.submit": "Award trophy", + "new.backfill.confirm.heading_one": "Award {{trophyName}} to {{playerCount}} players for {{count}} tournament?", + "new.backfill.confirm.heading_other": "Award {{trophyName}} to {{playerCount}} players for {{count}} tournaments?", + "new.backfill.confirm.description": "This can not be undone. Trophies can not be taken away once awarded.", "new.pending.empty": "No pending trophies", "new.pending.notFromManager": "Not submitted by the trophy's manager", "new.pending.approve": "Approve", diff --git a/locales/es-ES/trophies.json b/locales/es-ES/trophies.json index 974c95279..f110ffc2f 100644 --- a/locales/es-ES/trophies.json +++ b/locales/es-ES/trophies.json @@ -9,10 +9,11 @@ "details.noOwners": "Sin propietarios todavía", "details.tournamentHistory": "Torneos", "details.noTournamentHistory": "Sin historial de torneos", + "details.weapons": "", "details.upcoming": "Próximos", "display.viewTrophyPage": "Ver página del trofeo", - "special.supporter.description": "Otorgado por apoyar a sendou.ink", - "special.xp.description": "Otorgado por alcanzar {{value}} de Energía X", + "special.xp.categoryDescription": "", + "xp.title": "", "new.form.limitReached": "Has alcanzado el límite de {{limit}} trofeos pendientes. Borra o espera a que se revise un envío existente antes de enviar otro.", "new.form.preview.light": "Modo claro", "new.form.preview.dark": "Modo oscuro", @@ -47,7 +48,7 @@ "new.terms.preApproval": "Si no tienes claro si tu torneo cumple los requisitos, no dudes en conseguir una preaprobación creando una solicitud en el <1>servidor de Discord.", "new.terms.agree": "He leído y acepto", "new.tabs.upload": "Subir", - "new.tabs.update": "Actualizar", + "new.tabs.manage": "", "new.tabs.pending": "Pendientes", "new.tabs.reviewed": "Revisados", "new.update.selectLabel": "Trofeo a actualizar", @@ -55,6 +56,23 @@ "new.update.editing": "Editando trofeo existente", "new.update.before": "Antes", "new.update.after": "Después", + "new.manage.update": "Actualizar", + "new.manage.backfill": "", + "new.backfill.explanation": "", + "new.backfill.warning": "", + "new.backfill.trophyLabel": "", + "new.backfill.seriesLabel": "", + "new.backfill.noTrophies": "", + "new.backfill.noTournaments": "", + "new.backfill.selected_one": "", + "new.backfill.selected_many": "", + "new.backfill.selected_other": "", + "new.backfill.noPlayersSelected": "", + "new.backfill.submit": "", + "new.backfill.confirm.heading_one": "", + "new.backfill.confirm.heading_many": "", + "new.backfill.confirm.heading_other": "", + "new.backfill.confirm.description": "", "new.pending.empty": "No hay trofeos pendientes", "new.pending.notFromManager": "No ha sido enviado por el gestor del trofeo", "new.pending.approve": "Aprobar", diff --git a/locales/es-US/trophies.json b/locales/es-US/trophies.json index e114eb62e..db2fd9e89 100644 --- a/locales/es-US/trophies.json +++ b/locales/es-US/trophies.json @@ -9,10 +9,11 @@ "details.noOwners": "Sin propietarios todavía", "details.tournamentHistory": "Torneos", "details.noTournamentHistory": "Sin historial de torneos", + "details.weapons": "", "details.upcoming": "Próximos", "display.viewTrophyPage": "Ver página del trofeo", - "special.supporter.description": "Otorgado por apoyar a sendou.ink", - "special.xp.description": "Otorgado por alcanzar {{value}} de Energía X", + "special.xp.categoryDescription": "", + "xp.title": "", "new.form.limitReached": "Has alcanzado el límite de {{limit}} trofeos pendientes. Borra o espera a que se revise un envío existente antes de enviar otro.", "new.form.preview.light": "Modo claro", "new.form.preview.dark": "Modo oscuro", @@ -47,7 +48,7 @@ "new.terms.preApproval": "Si no tienes claro si tu torneo cumple los requisitos, no dudes en conseguir una preaprobación creando una solicitud en el <1>servidor de Discord.", "new.terms.agree": "He leído y acepto", "new.tabs.upload": "Subir", - "new.tabs.update": "Actualizar", + "new.tabs.manage": "", "new.tabs.pending": "Pendientes", "new.tabs.reviewed": "Revisados", "new.update.selectLabel": "Trofeo a actualizar", @@ -55,6 +56,23 @@ "new.update.editing": "Editando trofeo existente", "new.update.before": "Antes", "new.update.after": "Después", + "new.manage.update": "Actualizar", + "new.manage.backfill": "", + "new.backfill.explanation": "", + "new.backfill.warning": "", + "new.backfill.trophyLabel": "", + "new.backfill.seriesLabel": "", + "new.backfill.noTrophies": "", + "new.backfill.noTournaments": "", + "new.backfill.selected_one": "", + "new.backfill.selected_many": "", + "new.backfill.selected_other": "", + "new.backfill.noPlayersSelected": "", + "new.backfill.submit": "", + "new.backfill.confirm.heading_one": "", + "new.backfill.confirm.heading_many": "", + "new.backfill.confirm.heading_other": "", + "new.backfill.confirm.description": "", "new.pending.empty": "No hay trofeos pendientes", "new.pending.notFromManager": "No ha sido enviado por el gestor del trofeo", "new.pending.approve": "Aprobar", diff --git a/locales/fr-CA/trophies.json b/locales/fr-CA/trophies.json index eb513dd24..41a33b90c 100644 --- a/locales/fr-CA/trophies.json +++ b/locales/fr-CA/trophies.json @@ -9,10 +9,11 @@ "details.noOwners": "", "details.tournamentHistory": "", "details.noTournamentHistory": "", + "details.weapons": "", "details.upcoming": "", "display.viewTrophyPage": "", - "special.supporter.description": "", - "special.xp.description": "", + "special.xp.categoryDescription": "", + "xp.title": "", "new.form.limitReached": "", "new.form.preview.light": "", "new.form.preview.dark": "", @@ -47,7 +48,7 @@ "new.terms.preApproval": "", "new.terms.agree": "", "new.tabs.upload": "", - "new.tabs.update": "", + "new.tabs.manage": "", "new.tabs.pending": "", "new.tabs.reviewed": "", "new.update.selectLabel": "", @@ -55,6 +56,23 @@ "new.update.editing": "", "new.update.before": "", "new.update.after": "", + "new.manage.update": "", + "new.manage.backfill": "", + "new.backfill.explanation": "", + "new.backfill.warning": "", + "new.backfill.trophyLabel": "", + "new.backfill.seriesLabel": "", + "new.backfill.noTrophies": "", + "new.backfill.noTournaments": "", + "new.backfill.selected_one": "", + "new.backfill.selected_many": "", + "new.backfill.selected_other": "", + "new.backfill.noPlayersSelected": "", + "new.backfill.submit": "", + "new.backfill.confirm.heading_one": "", + "new.backfill.confirm.heading_many": "", + "new.backfill.confirm.heading_other": "", + "new.backfill.confirm.description": "", "new.pending.empty": "", "new.pending.notFromManager": "", "new.pending.approve": "", diff --git a/locales/fr-EU/trophies.json b/locales/fr-EU/trophies.json index eb513dd24..41a33b90c 100644 --- a/locales/fr-EU/trophies.json +++ b/locales/fr-EU/trophies.json @@ -9,10 +9,11 @@ "details.noOwners": "", "details.tournamentHistory": "", "details.noTournamentHistory": "", + "details.weapons": "", "details.upcoming": "", "display.viewTrophyPage": "", - "special.supporter.description": "", - "special.xp.description": "", + "special.xp.categoryDescription": "", + "xp.title": "", "new.form.limitReached": "", "new.form.preview.light": "", "new.form.preview.dark": "", @@ -47,7 +48,7 @@ "new.terms.preApproval": "", "new.terms.agree": "", "new.tabs.upload": "", - "new.tabs.update": "", + "new.tabs.manage": "", "new.tabs.pending": "", "new.tabs.reviewed": "", "new.update.selectLabel": "", @@ -55,6 +56,23 @@ "new.update.editing": "", "new.update.before": "", "new.update.after": "", + "new.manage.update": "", + "new.manage.backfill": "", + "new.backfill.explanation": "", + "new.backfill.warning": "", + "new.backfill.trophyLabel": "", + "new.backfill.seriesLabel": "", + "new.backfill.noTrophies": "", + "new.backfill.noTournaments": "", + "new.backfill.selected_one": "", + "new.backfill.selected_many": "", + "new.backfill.selected_other": "", + "new.backfill.noPlayersSelected": "", + "new.backfill.submit": "", + "new.backfill.confirm.heading_one": "", + "new.backfill.confirm.heading_many": "", + "new.backfill.confirm.heading_other": "", + "new.backfill.confirm.description": "", "new.pending.empty": "", "new.pending.notFromManager": "", "new.pending.approve": "", diff --git a/locales/he/trophies.json b/locales/he/trophies.json index eb513dd24..1ec91f766 100644 --- a/locales/he/trophies.json +++ b/locales/he/trophies.json @@ -9,10 +9,11 @@ "details.noOwners": "", "details.tournamentHistory": "", "details.noTournamentHistory": "", + "details.weapons": "", "details.upcoming": "", "display.viewTrophyPage": "", - "special.supporter.description": "", - "special.xp.description": "", + "special.xp.categoryDescription": "", + "xp.title": "", "new.form.limitReached": "", "new.form.preview.light": "", "new.form.preview.dark": "", @@ -47,7 +48,7 @@ "new.terms.preApproval": "", "new.terms.agree": "", "new.tabs.upload": "", - "new.tabs.update": "", + "new.tabs.manage": "", "new.tabs.pending": "", "new.tabs.reviewed": "", "new.update.selectLabel": "", @@ -55,6 +56,23 @@ "new.update.editing": "", "new.update.before": "", "new.update.after": "", + "new.manage.update": "", + "new.manage.backfill": "", + "new.backfill.explanation": "", + "new.backfill.warning": "", + "new.backfill.trophyLabel": "", + "new.backfill.seriesLabel": "", + "new.backfill.noTrophies": "", + "new.backfill.noTournaments": "", + "new.backfill.selected_one": "", + "new.backfill.selected_two": "", + "new.backfill.selected_other": "", + "new.backfill.noPlayersSelected": "", + "new.backfill.submit": "", + "new.backfill.confirm.heading_one": "", + "new.backfill.confirm.heading_two": "", + "new.backfill.confirm.heading_other": "", + "new.backfill.confirm.description": "", "new.pending.empty": "", "new.pending.notFromManager": "", "new.pending.approve": "", diff --git a/locales/it/trophies.json b/locales/it/trophies.json index eb513dd24..41a33b90c 100644 --- a/locales/it/trophies.json +++ b/locales/it/trophies.json @@ -9,10 +9,11 @@ "details.noOwners": "", "details.tournamentHistory": "", "details.noTournamentHistory": "", + "details.weapons": "", "details.upcoming": "", "display.viewTrophyPage": "", - "special.supporter.description": "", - "special.xp.description": "", + "special.xp.categoryDescription": "", + "xp.title": "", "new.form.limitReached": "", "new.form.preview.light": "", "new.form.preview.dark": "", @@ -47,7 +48,7 @@ "new.terms.preApproval": "", "new.terms.agree": "", "new.tabs.upload": "", - "new.tabs.update": "", + "new.tabs.manage": "", "new.tabs.pending": "", "new.tabs.reviewed": "", "new.update.selectLabel": "", @@ -55,6 +56,23 @@ "new.update.editing": "", "new.update.before": "", "new.update.after": "", + "new.manage.update": "", + "new.manage.backfill": "", + "new.backfill.explanation": "", + "new.backfill.warning": "", + "new.backfill.trophyLabel": "", + "new.backfill.seriesLabel": "", + "new.backfill.noTrophies": "", + "new.backfill.noTournaments": "", + "new.backfill.selected_one": "", + "new.backfill.selected_many": "", + "new.backfill.selected_other": "", + "new.backfill.noPlayersSelected": "", + "new.backfill.submit": "", + "new.backfill.confirm.heading_one": "", + "new.backfill.confirm.heading_many": "", + "new.backfill.confirm.heading_other": "", + "new.backfill.confirm.description": "", "new.pending.empty": "", "new.pending.notFromManager": "", "new.pending.approve": "", diff --git a/locales/ja/trophies.json b/locales/ja/trophies.json index eb513dd24..d2d09003b 100644 --- a/locales/ja/trophies.json +++ b/locales/ja/trophies.json @@ -9,10 +9,11 @@ "details.noOwners": "", "details.tournamentHistory": "", "details.noTournamentHistory": "", + "details.weapons": "", "details.upcoming": "", "display.viewTrophyPage": "", - "special.supporter.description": "", - "special.xp.description": "", + "special.xp.categoryDescription": "", + "xp.title": "", "new.form.limitReached": "", "new.form.preview.light": "", "new.form.preview.dark": "", @@ -47,7 +48,7 @@ "new.terms.preApproval": "", "new.terms.agree": "", "new.tabs.upload": "", - "new.tabs.update": "", + "new.tabs.manage": "", "new.tabs.pending": "", "new.tabs.reviewed": "", "new.update.selectLabel": "", @@ -55,6 +56,17 @@ "new.update.editing": "", "new.update.before": "", "new.update.after": "", + "new.manage.update": "", + "new.manage.backfill": "", + "new.backfill.explanation": "", + "new.backfill.warning": "", + "new.backfill.trophyLabel": "", + "new.backfill.seriesLabel": "", + "new.backfill.noTrophies": "", + "new.backfill.noTournaments": "", + "new.backfill.noPlayersSelected": "", + "new.backfill.submit": "", + "new.backfill.confirm.description": "", "new.pending.empty": "", "new.pending.notFromManager": "", "new.pending.approve": "", diff --git a/locales/ko/trophies.json b/locales/ko/trophies.json index eb513dd24..d2d09003b 100644 --- a/locales/ko/trophies.json +++ b/locales/ko/trophies.json @@ -9,10 +9,11 @@ "details.noOwners": "", "details.tournamentHistory": "", "details.noTournamentHistory": "", + "details.weapons": "", "details.upcoming": "", "display.viewTrophyPage": "", - "special.supporter.description": "", - "special.xp.description": "", + "special.xp.categoryDescription": "", + "xp.title": "", "new.form.limitReached": "", "new.form.preview.light": "", "new.form.preview.dark": "", @@ -47,7 +48,7 @@ "new.terms.preApproval": "", "new.terms.agree": "", "new.tabs.upload": "", - "new.tabs.update": "", + "new.tabs.manage": "", "new.tabs.pending": "", "new.tabs.reviewed": "", "new.update.selectLabel": "", @@ -55,6 +56,17 @@ "new.update.editing": "", "new.update.before": "", "new.update.after": "", + "new.manage.update": "", + "new.manage.backfill": "", + "new.backfill.explanation": "", + "new.backfill.warning": "", + "new.backfill.trophyLabel": "", + "new.backfill.seriesLabel": "", + "new.backfill.noTrophies": "", + "new.backfill.noTournaments": "", + "new.backfill.noPlayersSelected": "", + "new.backfill.submit": "", + "new.backfill.confirm.description": "", "new.pending.empty": "", "new.pending.notFromManager": "", "new.pending.approve": "", diff --git a/locales/nl/trophies.json b/locales/nl/trophies.json index eb513dd24..eb90708cb 100644 --- a/locales/nl/trophies.json +++ b/locales/nl/trophies.json @@ -9,10 +9,11 @@ "details.noOwners": "", "details.tournamentHistory": "", "details.noTournamentHistory": "", + "details.weapons": "", "details.upcoming": "", "display.viewTrophyPage": "", - "special.supporter.description": "", - "special.xp.description": "", + "special.xp.categoryDescription": "", + "xp.title": "", "new.form.limitReached": "", "new.form.preview.light": "", "new.form.preview.dark": "", @@ -47,7 +48,7 @@ "new.terms.preApproval": "", "new.terms.agree": "", "new.tabs.upload": "", - "new.tabs.update": "", + "new.tabs.manage": "", "new.tabs.pending": "", "new.tabs.reviewed": "", "new.update.selectLabel": "", @@ -55,6 +56,21 @@ "new.update.editing": "", "new.update.before": "", "new.update.after": "", + "new.manage.update": "", + "new.manage.backfill": "", + "new.backfill.explanation": "", + "new.backfill.warning": "", + "new.backfill.trophyLabel": "", + "new.backfill.seriesLabel": "", + "new.backfill.noTrophies": "", + "new.backfill.noTournaments": "", + "new.backfill.selected_one": "", + "new.backfill.selected_other": "", + "new.backfill.noPlayersSelected": "", + "new.backfill.submit": "", + "new.backfill.confirm.heading_one": "", + "new.backfill.confirm.heading_other": "", + "new.backfill.confirm.description": "", "new.pending.empty": "", "new.pending.notFromManager": "", "new.pending.approve": "", diff --git a/locales/pl/trophies.json b/locales/pl/trophies.json index eb513dd24..4d598bbc1 100644 --- a/locales/pl/trophies.json +++ b/locales/pl/trophies.json @@ -9,10 +9,11 @@ "details.noOwners": "", "details.tournamentHistory": "", "details.noTournamentHistory": "", + "details.weapons": "", "details.upcoming": "", "display.viewTrophyPage": "", - "special.supporter.description": "", - "special.xp.description": "", + "special.xp.categoryDescription": "", + "xp.title": "", "new.form.limitReached": "", "new.form.preview.light": "", "new.form.preview.dark": "", @@ -47,7 +48,7 @@ "new.terms.preApproval": "", "new.terms.agree": "", "new.tabs.upload": "", - "new.tabs.update": "", + "new.tabs.manage": "", "new.tabs.pending": "", "new.tabs.reviewed": "", "new.update.selectLabel": "", @@ -55,6 +56,25 @@ "new.update.editing": "", "new.update.before": "", "new.update.after": "", + "new.manage.update": "", + "new.manage.backfill": "", + "new.backfill.explanation": "", + "new.backfill.warning": "", + "new.backfill.trophyLabel": "", + "new.backfill.seriesLabel": "", + "new.backfill.noTrophies": "", + "new.backfill.noTournaments": "", + "new.backfill.selected_one": "", + "new.backfill.selected_few": "", + "new.backfill.selected_many": "", + "new.backfill.selected_other": "", + "new.backfill.noPlayersSelected": "", + "new.backfill.submit": "", + "new.backfill.confirm.heading_one": "", + "new.backfill.confirm.heading_few": "", + "new.backfill.confirm.heading_many": "", + "new.backfill.confirm.heading_other": "", + "new.backfill.confirm.description": "", "new.pending.empty": "", "new.pending.notFromManager": "", "new.pending.approve": "", diff --git a/locales/pt-BR/trophies.json b/locales/pt-BR/trophies.json index eb513dd24..41a33b90c 100644 --- a/locales/pt-BR/trophies.json +++ b/locales/pt-BR/trophies.json @@ -9,10 +9,11 @@ "details.noOwners": "", "details.tournamentHistory": "", "details.noTournamentHistory": "", + "details.weapons": "", "details.upcoming": "", "display.viewTrophyPage": "", - "special.supporter.description": "", - "special.xp.description": "", + "special.xp.categoryDescription": "", + "xp.title": "", "new.form.limitReached": "", "new.form.preview.light": "", "new.form.preview.dark": "", @@ -47,7 +48,7 @@ "new.terms.preApproval": "", "new.terms.agree": "", "new.tabs.upload": "", - "new.tabs.update": "", + "new.tabs.manage": "", "new.tabs.pending": "", "new.tabs.reviewed": "", "new.update.selectLabel": "", @@ -55,6 +56,23 @@ "new.update.editing": "", "new.update.before": "", "new.update.after": "", + "new.manage.update": "", + "new.manage.backfill": "", + "new.backfill.explanation": "", + "new.backfill.warning": "", + "new.backfill.trophyLabel": "", + "new.backfill.seriesLabel": "", + "new.backfill.noTrophies": "", + "new.backfill.noTournaments": "", + "new.backfill.selected_one": "", + "new.backfill.selected_many": "", + "new.backfill.selected_other": "", + "new.backfill.noPlayersSelected": "", + "new.backfill.submit": "", + "new.backfill.confirm.heading_one": "", + "new.backfill.confirm.heading_many": "", + "new.backfill.confirm.heading_other": "", + "new.backfill.confirm.description": "", "new.pending.empty": "", "new.pending.notFromManager": "", "new.pending.approve": "", diff --git a/locales/ru/trophies.json b/locales/ru/trophies.json index eb513dd24..4d598bbc1 100644 --- a/locales/ru/trophies.json +++ b/locales/ru/trophies.json @@ -9,10 +9,11 @@ "details.noOwners": "", "details.tournamentHistory": "", "details.noTournamentHistory": "", + "details.weapons": "", "details.upcoming": "", "display.viewTrophyPage": "", - "special.supporter.description": "", - "special.xp.description": "", + "special.xp.categoryDescription": "", + "xp.title": "", "new.form.limitReached": "", "new.form.preview.light": "", "new.form.preview.dark": "", @@ -47,7 +48,7 @@ "new.terms.preApproval": "", "new.terms.agree": "", "new.tabs.upload": "", - "new.tabs.update": "", + "new.tabs.manage": "", "new.tabs.pending": "", "new.tabs.reviewed": "", "new.update.selectLabel": "", @@ -55,6 +56,25 @@ "new.update.editing": "", "new.update.before": "", "new.update.after": "", + "new.manage.update": "", + "new.manage.backfill": "", + "new.backfill.explanation": "", + "new.backfill.warning": "", + "new.backfill.trophyLabel": "", + "new.backfill.seriesLabel": "", + "new.backfill.noTrophies": "", + "new.backfill.noTournaments": "", + "new.backfill.selected_one": "", + "new.backfill.selected_few": "", + "new.backfill.selected_many": "", + "new.backfill.selected_other": "", + "new.backfill.noPlayersSelected": "", + "new.backfill.submit": "", + "new.backfill.confirm.heading_one": "", + "new.backfill.confirm.heading_few": "", + "new.backfill.confirm.heading_many": "", + "new.backfill.confirm.heading_other": "", + "new.backfill.confirm.description": "", "new.pending.empty": "", "new.pending.notFromManager": "", "new.pending.approve": "", diff --git a/locales/zh/trophies.json b/locales/zh/trophies.json index eb513dd24..d2d09003b 100644 --- a/locales/zh/trophies.json +++ b/locales/zh/trophies.json @@ -9,10 +9,11 @@ "details.noOwners": "", "details.tournamentHistory": "", "details.noTournamentHistory": "", + "details.weapons": "", "details.upcoming": "", "display.viewTrophyPage": "", - "special.supporter.description": "", - "special.xp.description": "", + "special.xp.categoryDescription": "", + "xp.title": "", "new.form.limitReached": "", "new.form.preview.light": "", "new.form.preview.dark": "", @@ -47,7 +48,7 @@ "new.terms.preApproval": "", "new.terms.agree": "", "new.tabs.upload": "", - "new.tabs.update": "", + "new.tabs.manage": "", "new.tabs.pending": "", "new.tabs.reviewed": "", "new.update.selectLabel": "", @@ -55,6 +56,17 @@ "new.update.editing": "", "new.update.before": "", "new.update.after": "", + "new.manage.update": "", + "new.manage.backfill": "", + "new.backfill.explanation": "", + "new.backfill.warning": "", + "new.backfill.trophyLabel": "", + "new.backfill.seriesLabel": "", + "new.backfill.noTrophies": "", + "new.backfill.noTournaments": "", + "new.backfill.noPlayersSelected": "", + "new.backfill.submit": "", + "new.backfill.confirm.description": "", "new.pending.empty": "", "new.pending.notFromManager": "", "new.pending.approve": "", diff --git a/migrations/20260930203031-xp-trophies.ts b/migrations/20260930203031-xp-trophies.ts new file mode 100644 index 000000000..527bf4eba --- /dev/null +++ b/migrations/20260930203031-xp-trophies.ts @@ -0,0 +1,135 @@ +import type { Kysely } from "kysely"; + +const WEAPON_IDS_BY_CATEGORY: Record = { + shooters: [ + 0, 1, 10, 11, 20, 21, 22, 30, 31, 32, 40, 41, 42, 45, 46, 47, 48, 50, 51, + 60, 61, 70, 71, 72, 80, 81, 82, 90, 91, 92, 100, 101, 300, 301, 302, 310, + 311, 312, 400, 401, + ], + blasters: [ + 200, 201, 205, 210, 211, 212, 220, 221, 230, 231, 240, 241, 250, 251, 252, + 260, 261, + ], + rollers: [ + 1000, 1001, 1002, 1010, 1011, 1015, 1020, 1021, 1022, 1030, 1031, 1040, + 1041, 1042, + ], + brushes: [1100, 1101, 1110, 1111, 1112, 1115, 1120, 1121, 1122], + chargers: [ + 2000, 2001, 2010, 2011, 2012, 2015, 2020, 2021, 2022, 2030, 2031, 2040, + 2041, 2050, 2051, 2060, 2061, 2070, 2071, + ], + sloshers: [ + 3000, 3001, 3005, 3010, 3011, 3012, 3020, 3021, 3030, 3031, 3040, 3041, + 3050, 3051, 3052, + ], + splatlings: [ + 4000, 4001, 4002, 4010, 4011, 4015, 4020, 4021, 4022, 4030, 4031, 4040, + 4041, 4050, 4051, + ], + dualies: [ + 5000, 5001, 5002, 5010, 5015, 5011, 5012, 5020, 5021, 5030, 5031, 5032, + 5040, 5041, 5050, 5051, + ], + brellas: [6000, 6001, 6005, 6010, 6011, 6012, 6020, 6021, 6022, 6030, 6031], + stringers: [7010, 7011, 7012, 7015, 7020, 7021, 7022, 7030, 7031], + splatanas: [8000, 8001, 8002, 8005, 8010, 8011, 8012, 8020, 8021], +}; + +const MILESTONES_DESC = [4000, 3500, 3200, 3000]; +const OWNER_INSERT_BATCH_SIZE = 1000; + +export async function up(db: Kysely): Promise { + await db.transaction().execute(async (trx) => { + const placeholderIds = ( + await trx + .selectFrom("Trophy") + .select("id") + .where("code", "like", "xp-%") + .execute() + ).map((row) => row.id); + + if (placeholderIds.length > 0) { + await trx + .deleteFrom("SpecialTrophyOwner") + .where("trophyId", "in", placeholderIds) + .execute(); + await trx + .deleteFrom("Trophy") + .where("id", "in", placeholderIds) + .execute(); + } + + const trophies = await trx + .insertInto("Trophy") + .values( + Object.keys(WEAPON_IDS_BY_CATEGORY).flatMap((category) => + MILESTONES_DESC.toReversed().map((milestone) => ({ + name: `${milestone} X Power ${category.charAt(0).toUpperCase()}${category.slice(1)}`, + model: "", + code: `xp-${category}-${milestone}`, + })), + ), + ) + .returning(["id", "code"]) + .execute(); + const trophyIdByCode = new Map( + trophies.map((trophy) => [trophy.code, trophy.id]), + ); + + const categoryByWeaponId = new Map( + Object.entries(WEAPON_IDS_BY_CATEGORY).flatMap(([category, weaponIds]) => + weaponIds.map((weaponId) => [weaponId, category] as const), + ), + ); + + const peaks = await trx + .selectFrom("XRankPlacement") + .innerJoin( + "SplatoonPlayer", + "SplatoonPlayer.id", + "XRankPlacement.playerId", + ) + .select(({ fn }) => [ + "SplatoonPlayer.userId", + "XRankPlacement.weaponSplId", + fn.max("XRankPlacement.power").as("power"), + ]) + .where("SplatoonPlayer.userId", "is not", null) + .groupBy(["SplatoonPlayer.userId", "XRankPlacement.weaponSplId"]) + .execute(); + + const peakByUserCategory = new Map< + string, + { userId: number; category: string; power: number } + >(); + for (const { userId, weaponSplId, power } of peaks) { + const category = categoryByWeaponId.get(weaponSplId); + if (!category) continue; + + const key = `${userId}-${category}`; + const existing = peakByUserCategory.get(key); + if (!existing || power > existing.power) { + peakByUserCategory.set(key, { userId, category, power }); + } + } + + const createdAt = Math.floor(Date.now() / 1000); + const owners = [...peakByUserCategory.values()].flatMap( + ({ userId, category, power }) => { + const milestone = MILESTONES_DESC.find((value) => power >= value); + if (!milestone) return []; + + const trophyId = trophyIdByCode.get(`xp-${category}-${milestone}`); + return trophyId ? [{ trophyId, userId, createdAt }] : []; + }, + ); + + for (let i = 0; i < owners.length; i += OWNER_INSERT_BATCH_SIZE) { + await trx + .insertInto("SpecialTrophyOwner") + .values(owners.slice(i, i + OWNER_INSERT_BATCH_SIZE)) + .execute(); + } + }); +} diff --git a/package.json b/package.json index c1e72aa7c..6f91bbb28 100644 --- a/package.json +++ b/package.json @@ -88,7 +88,7 @@ "nprogress": "0.2.0", "openskill": "5.0.1", "p-limit": "7.3.2", - "picocad2-web": "2.0.3", + "picocad2-web": "2.0.4", "qrcode.react": "4.2.0", "react": "19.3.0", "react-dom": "19.3.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f0c74cacc..ddd61595a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -115,8 +115,8 @@ importers: specifier: 7.3.2 version: 7.3.2 picocad2-web: - specifier: 2.0.3 - version: 2.0.3 + specifier: 2.0.4 + version: 2.0.4 qrcode.react: specifier: 4.2.0 version: 4.2.0(react@19.3.0) @@ -3694,8 +3694,8 @@ packages: pathe@2.0.3: resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} - picocad2-web@2.0.3: - resolution: {integrity: sha512-IaUTXiNwH1Ji4U5J57AiHm+unKmKEwV3UH9ab47qqlAcDRSThdt3mE7uzKnH/J0MXhuSRU9lfAdh6nuRHA+b9Q==} + picocad2-web@2.0.4: + resolution: {integrity: sha512-HhFMM5PLfQyDb7rSTkfNZ2/2sqS54JqhYwJFHFMnZnvkvvd2DaAeu9Xl8k5t4gH/EcU+ks6ykhFudL6jRdkpdw==} engines: {node: '>=18.0.0'} picocolors@1.1.1: @@ -7887,7 +7887,7 @@ snapshots: pathe@2.0.3: {} - picocad2-web@2.0.3: + picocad2-web@2.0.4: dependencies: gl-matrix: 3.4.4 twgl.js: 7.0.0 diff --git a/scripts/placements/index.ts b/scripts/placements/index.ts index a9b5ea408..cc03643d2 100644 --- a/scripts/placements/index.ts +++ b/scripts/placements/index.ts @@ -2,6 +2,7 @@ import * as v from "valibot"; import * as BadgeRepository from "~/features/badges/BadgeRepository.server"; import * as BuildRepository from "~/features/builds/BuildRepository.server"; import * as XRankPlacementRepository from "~/features/top-search/XRankPlacementRepository.server"; +import * as TrophyRepository from "~/features/trophies/TrophyRepository.server"; import type { MainWeaponId } from "~/modules/in-game-lists/types"; import { mainWeaponIds } from "~/modules/in-game-lists/weapon-ids"; import { invariant } from "~/utils/invariant"; @@ -53,6 +54,7 @@ async function main() { await XRankPlacementRepository.insertMany(placements); await XRankPlacementRepository.refreshAllPeakXp(); await BadgeRepository.syncXPBadges(); + await TrophyRepository.syncSpecialTrophies(); await BuildRepository.recalculateAllSortValues(); await XRankPlacementRepository.refreshTenStarWeapons(); logger.info(`done reading in ${placements.length} placements`);