function editor_traceEditorHelp()
	-- trace("")

	if animatePanel.open then
		return
	end

	if not editor.helpEnabled then
		return
	end

	if not ctx.isAnim then
		trace("hold middle mouse or hit tab to wasdqe walk")
		trace("alt + middle mouse to orbit")
		if editor.debug.trace_info then
			trace()
		end
	end

	trace("")
	trace("space drag     - pan")
  trace("alt drag       - orbit")
  trace("tab            - toggle wasd mode")
  trace("middle click   - hold wasd mode")
	trace("cmd return     - play")
	trace("cmd shft enter - play from default cam")
	trace("escape         - resume editing")
	trace("cmd escape     - exit editor")
	trace("cmd +/=/0      - zoom in/out/reset")
	trace("scroll(+shift) - zoom/track in/out")
	trace("scroll         - change FOV")
	-- trace("alt +/=/0      - resolution up/down/reset")
	trace("cmd S          - save")
	trace("cmd A          - select all")
	trace("cmd shift N    - new file in seperate tab")
	trace("cmd shift []   - change tabs")
	trace("esc / return   - exit / enter view")
	trace("C 1-9.         - reset camera")
	trace("shift C 1-9    - set camera")
	trace("cmd O          - toggle ortho")
	trace("V 1-9.         - reset viewport")
	trace("shift V 1-9    - set viewport")
	trace("R              - reset transform")
	trace("cmd P          - prerender")
	trace("cmd G          - toggle grid")
	--trace("cmd T          - toggle tracking")
	--trace("cmd I          - toggle level info")
	--trace("cmd 9          - reset cam to 0,0")
	trace("cmd R          - reload source")
	trace("cmd(+shift) Z  - undo(redo)")
	trace("shift+click    - select multiple")
	trace("P              - open plan")
	trace("G              - open gallery")
	if pathsPanel.open then
		trace("hit N for new path point")
	end

	trace("")
end

function editor_traceAnimationHelp(panel)
	if not editor.helpEnabled then
		return
	end

	if not ctx.isAnim then
		-- trace("cmd return  - save and exit to level")
		trace("alt esc     - exit symbol")
		trace("tilde       - toggle anim mode")
		trace("")
	end

	if panel.l.type == "drawing" then
		trace("Drawing:")
		trace(" B           - brush tool")
		trace(" P/X         - pen tool")
		-- trace(" Z,X,C       - pen tool (rough, line, note)")
		-- trace("   + shift     -> convert to")
		trace(" E           - eraser")
		-- trace(" D           - toggle draw")
		trace(" F           - fill bucket tool")
		trace(" L           - lasso select tool")
		trace(" V           - move/select/transform tool")
		trace("   + shift (while scaling) - lock ratio")
		trace("   + alt   (while scaling) - lock side(s)")
		trace(" [ / ]       - change brush/pen size")
		trace("               or stroke edit falloff")
		trace(" alt         - color eyedrop")
		trace("   + r click - color picker")
		trace(" hold space  - pan")
		trace("   + shift   - zoom")
		trace(" cmd +/-/0   - zoom in/out/reset")
		trace(" alt +/-/0   - resolution up/down/reset")
		trace(" backspace   - clear frame contents")
		trace("   + cmd     - delete frame")
		trace("   + alt     - remove frame")
		trace("   + shift   - clear transform")
		trace(" cmd G       - add selection to gallery")
		trace(" G           - open gallery")

	-- trace(" cmd P     - prune frame")
	-- trace(" cmd J     - toggle frame bounds")
	else
		trace(" M      - toggle mesh edit")
		trace("cmd W      - toggle wireframe")
	end

	trace("")

	if panel.l.remodel then
		trace("-Mesh Editing:(")
		trace(" 1/2/3    - selection type")
		trace(" 4        - toggle see through")
		trace(" 5        - togle orbit mode")
		trace(" 6        - togle render mode")
		trace("")
		trace(" cmd A    - (de)select all")
		trace(" alt A    - invert selection")
		trace(" L        - lasso select")
		trace(" C        - circle select")
		trace("")
		trace(" R        - rotate")
		trace(" S        - scale")
		trace(" G        - grab/move")
		trace("   -> (shift)X/Y/Z to lock (plane)axis")
		trace("       + shift to lock plane")
		trace("")
		trace(" F        - flatten")
		trace(" D        - dissolve")
		trace(" I        - inset")
		trace(" K        - knife")
		trace(" T        - triangulate")
		trace(" M        - merge")
		trace(" E        - extrude")
		trace(" alt E    - extrude along normals")
		trace(" shift E  - extrude individual faces")
		trace("")
		trace("  while RSG-ing")
		trace("      scroll to change proportional")
		trace("      editing falloff")
		trace("")
		trace("cmd c       - copy geometry")
		trace("cmd v       - paste geometry")
	else
		trace("Timeline:")
		trace(" Q           - new blank frame")
		trace(" shift Q     - duplicate frame")
		trace(" K           - mark key")
		trace(" S           - split frame")
		trace(" 1 / 2       - prev/next frame")
		trace("     + shift - scrub frames")
		trace("     + alt   - prev/next key")
		trace("     + cmd   - up/down layer")
		trace(" 3 / 4       - shorten/extend frame")
		trace("     + shift - move frame")
		trace("     (can be swapped in view settings)")
		trace(" delete      - delete frame")
		trace("   + alt     - remove frame")
		trace(" 5           - toggle solo layer")
		trace(" up / down   - change layers")
		trace(" left/right  - step fwd/back")
		trace("     + shift - scrub frames ")
		trace(" O           - toggle onion skin")
		trace(" , / .       - toggle onion sides")
		-- trace("     + shift - toggle onion types")
		trace(" tap space   - play from/return to")
		trace(" cmd return  - play from start")
		trace(" esc         - stop on current frame")
		trace(" cmd L       - new layer of current type")
		trace("")

		trace("Other:")
		trace(" cmd S       - save animation")
		trace(" shift []    - change cuts")
		trace(" cmd shift []- change tabs")
		trace(" cmd shift N - new file in seperate tab")
		trace(" cmd E       - export cut")
		trace(" cmd shift E - export full animation")
		trace(" cmd X,C,V   - cut,copy,paste selection")
		trace("     + shift - cut,copy,paste frame(s)")
		trace(" cmd R       - reset symbol transform")
		trace(" cmd T       - toggle tween")
		trace(" cmd B       - toggle full timeline")
		trace(" cmd(shift)Z - undo(redo) ")

		trace("")

		trace("Tips:")
		trace(" right click the top of the timeline")
		trace("   -> quick scrub bar")
		trace(" drag the bottom of the timeline")
		trace("   -> pan timeline")
	end

	--trace("     +alt   - paste inline")
	-- trace("        click and drag inbetween ")
	-- trace("        tweened frames to ease")

	--trace("cmd B       - toggle background")
	trace(" click cut name  - switch/add/rename cuts")
	trace(" dragon drop audio or images to add")
	if panel.animation.source then
		trace(" click audio name to mute")
	end
	trace(" try right clicking stuff for more options")

	trace("")
end

function editor_traceAnimationUndos(panel)
	if not config.traceUndoHistory then
		return
	end
	trace("Undo History:")
	for i = 0, #panel.undos, 1 do
		local undo = panel.undos[i]
		local str = string.format(
			" %s %i %s ",
			i == (#panel.undos - panel.undoPos) and ">" or " ",
			i,
			undo and undo.action or ""
		)
		if undo then
			if undo.preLength then
				str = str .. string.format(" (l: %i -> %i) ", undo.preLength, undo.postLength)
			end
			if undo.strokesAdded then
				str = str .. string.format("+%i -%i", #undo.strokesAdded, #undo.strokesRemoved)
			end
			if undo.source then
				str = str .. string.format("+%i -%i", lume.count(undo.source), lume.count(undo.dest))
			end
			if undo.selection and undo.selection.count then
				str = str .. " n:" .. tostring(undo.selection.count)
			end
		end
		-- ,""-- ,tostring(undo and undo.selection and undo.selection.strokes and #undo.selection.strokes or "no strokes")
		trace(str)
	end
	trace("")
end

function editor_editorKeys()
	local cam = editor.viewport.camera
	
	if input_keyPressed("escape") then
		editor_closeContextMenu()
		editor_closePanel(galleryPanel)
		planPanel.open = false
	end

	-- if namer.closing then
	--  editor_closeContextMenu()
	--  namer.closing = false
	-- end

	if input_keyPressed("p") then
		editor.refreshSelection = true
		delayedCall(function()
			editor.refreshSelection = false
		end, 0.1)
		if cmdDown then
			engine.renderSelection = not engine.renderSelection
		else
			if ctx.isAnim then
			else
				if animatePanel.anims then
					animatePanel.open = not animatePanel.open
					if not animatePanel.open then
						mouse_setVisible(true)
						editor.currentTool = "Select"
						scene_deleteEntity(animatePanel.transformer)
					else
						editor_updateFrameTransformer(animatePanel)
						animatePanel.changed = true
					end
					lume.clear(editor.selectedEntities)
				else
					if not input_keyDown("space") then
						planPanel.open = not planPanel.open
						if planPanel.open then
							plan_open()
						end
					end
				end
			end
		end
	end

	if contextMenu.open or namer.enabled then
		return
	end

	if input_keyPressed("backspace") then
		if editor.state == "Cutting" then
			floors_removeWallCuts(room[pathsPanel.cutTarget[1]][pathsPanel.cutTarget[2]], pathsPanel.cutPoint)
		end
	end

	if altDown and input_keyPressed("v") then
		ctx.viewport.room.lighting.vct.showVoxels = not ctx.viewport.room.lighting.vct.showVoxels
	end

	-- GRID
	if input_keyPressed("g") then
		if cmdDown then
      editor.sphereMesh = newSphereMesh(10)
			editor.gridEnabled = not editor.gridEnabled
		elseif cmdDown then
		elseif not lfs.isFused() then
			print("floatpanel")
			galleryPanel.width = 350
			editor_floatPanel(galleryPanel)
		end
	end

	if cmdDown then
		engine_tabKeys()

		if not animatePanel.open and shiftDown and input_keyPressed("escape") then
			engine_exit()
		end

		-- FOCAL LENGTH
		if shiftDown then
			if input_keyPressed("-") then
				cam.focalL = cam.focalL - 0.05
			end
			if input_keyPressed("=") then
				cam.focalL = cam.focalL + 0.05
			end
			if input_keyPressed("0") then
				cam.focalL = 0
			end
		elseif not altDown then
			-- ZOOM
			local function getZoomPercent(soom)
				return soom ^ 8
			end
			if input_keyPressed("-") then
				scene_tween(cam, { soom = mc(0.81, cam.soom + 0.05, 1.22) }, 0.2, "easeOut", 1)
				editor_tempTip(string.format("Zoom Out")) --: %f%%" ,getZoomPercent(cam.soom+0.05)))
			end
			if input_keyPressed("=") then
				scene_tween(cam, { soom = mc(0.81, cam.soom - 0.05, 1.22) }, 0.2, "easeOut", 1)
				editor_tempTip(string.format("Zoom In")) --: %f%%",getZoomPercent(cam.soom-0.05)))
			end
			if input_keyPressed("0") then
				scene_tween(cam, { soom = 1 }, 0.25, "easeOut", 1)
				editor_tempTip("Reset Zoom") --string.format("Zoom: %i%%",getZoomPercent(1)))
			end
		end

		-- RELOAD
		if input_keyPressed("r") then
			-- print(inspect(_G))
			editor_tempTip("reload code...")
			engine_loadSource(true)
			editor.refresh = true
		end

		-- EMPTY LOG
		-- if keypressed("e") then
		--  editor_tempTip("Emptied Log")
		--  toLog={}
		--  logNum=0
		-- end

		-- GFX STATS
		if input_keyPressed("u") then
			gfxStats = not gfxStats
		end

		-- TOGGLE FLAT UI
		if input_keyPressed("9") then
			-- sidebar.flatUI = not sidebar.flatUI
		end
	else
		if input_keyPressed("-") and input_keyPressed("=") then
			if cam.locked then
				scene_tween(cam, { x = 0, y = -2 }, 0.25, "easeOut", 1)
			else
				scene_tween(cam.offset, { x = 0, y = -2 }, 0.25, "easeOut", 1)
			end
		end
	end

	-- SAVE
	if not animatePanel.open then
		if cmdDown and input_keyPressed("s") then
			editor_tempTip("Saved")
			editor.saveStep = 0
			save_project()
		end
	end

	if altDown and input_keyPressed("b") then
		createBoiserieMaps()
	end

	if namer.enabled == false then
		for i = 1, 8, 1 do
			if input_keyPressed(tostring(i)) then
				if input_keyDown("c") then
					if shiftDown then
						editor_setCamera(i)
					else
						editor_resetCamera(i)
					end
				elseif input_keyDown("v") then
					if shiftDown then
						editor_setViewport(i)
					else
						editor_resetViewport(i)
					end
				end
			end
		end
	end

	if cmdDown and input_keyPressed("o") then
		cam.ortho = not cam.ortho
		cam.fov = 0
	end

	if not (animatePanel.open or planPanel.open) then
		if cmdDown then
			--UNDO
			if input_keyRepeat("z") then
				editor_undo()
			end

			-- SAVE
			if input_keyPressed("s") then
				editor_tempTip("Saved")
				editor.saveStep = 0
				save_project()
			end

			-- SLECT ALL
			if input_keyPressed("a") then
				editor_tempTip("Select All")
				editor.selectAll = true
			end

			-- DEPTH
			if input_keyPressed("d") then
				--editor_tempTip("Depth "..((cam.focalL>0) and "Off" or "On"))
				--scene_tween(cam,{focalL=(cam.focalL>0) and 0 or 0.5},0.25,"easeOut",1)
			end

			-- CAMERAS
			if namer.enabled == false and animatePanel.open == false then
				for i = 1, 3 do
					if input_keyPressed(tostring(i)) then
						--room:setCam(i)
					end
				end
			end

			if input_keyPressed("l") then
				cam.locked = not cam.locked
				editor_tempTip("Camera " .. (cam.locked and "Locked" or "Unlocked"))
			end

			-- COPY
			if input_keyPressed("c") then
				editor_tempTip("Copied")
				editor_copyEntities()
			end

			-- PASTE
			if cmdDown and input_keyPressed("v") then
				editor_pasteEntities()
			end

			-- TOGGLE LINES
			if input_keyPressed("l") then
				--editor_toggleLines()
			end

			-- TOGGLE DARKMODE
			if input_keyPressed("8") then
				sidebar.darkMode = not sidebar.darkMode
			end

			if input_keyPressed("return") then
				if not shiftDown then
					editor.keepCamera = true
				end
				editor_playLevel()
				return
			end
		end

		if not cmdDown and editor.stageHovered then
			if input_keyPressed("escape") then
				if pathsPanel.wallCutting then
					pathsPanel.wallCutting = false
				elseif
					not ctx.pageView
					and editor.state == "Normal"
					and not pathsPanel.open
					and not galleryPanel.open
				then
					game_exitRoom()
				end
			end

			if ctx.pageView and not cmdDown and editor.state == "Normal" and input_keyPressed("return") then
				print("try2")

				game_enterRoom()
			end
		end
	end
end

function editor_animationKeys(panel)
	if namer.enabled or mouse_getRelativeMode() then
		return
	end

	if not cmdDown then
		if input_keyPressed("escape") then
			editor_dropSelection(panel)
		end
		if input_keyPressed("return") then
			editor_dropSelection(panel)
		end
	end
	-- SAVE ANIMATION
	if cmdDown and not altDown then
		if input_keyPressed("s") then
			save_animation(panel)
		end
		-- if not ctx.isAnim and keypressed("return") then
		--  editor_saveGraphics(panel)
		--  editor_closeAnimatePanel(panel)
		--  mouse_setVisible(true)
		-- end
	end

	-- TOGGLE ONION SKIN
	local onionToggled = false
	if input_keyPressed("o") then
		editor_tempTip("Onion Skin " .. (panel.onion.enabled and "Disabled" or "Enabled"))
		panel.onion.enabled = not panel.onion.enabled
		panel.sudoForceRestroke = true
		onionToggled = true
	elseif input_keyPressed(",") then
		editor_tempTip("Prev Skin " .. (panel.onion.before.enabled and "Disabled" or "Enabled"))
		panel.onion.before.enabled = not panel.onion.before.enabled
		onionToggled = true
	elseif input_keyPressed(".") then
		editor_tempTip("Next Skin " .. (panel.onion.after.enabled and "Disabled" or "Enabled"))
		panel.onion.after.enabled = not panel.onion.after.enabled
		onionToggled = true
	end

	-- TOGGLE FRAMEBOUNDS
	if cmdDown and input_keyPressed("j") then
		-- panel.frameBounds = not panel.frameBounds
	end

	-- BOTTOM TOGGLE
	if cmdDown and input_keyPressed("b") then
		panel.fullWidth = not panel.fullWidth
		--panel.bottom=not panel.bottom
		--editor_checkTimelineDocked(panel)
	end

	-- BACKGROUND TOGGLE
	if cmdDown and input_keyPressed("b") then
		--panel.backing = not panel.backing
	end

	-- NEW ANIMATION
	-- if cmdDown and shiftDown and keypressed("n") then
	--  editor_newAnimation()
	-- end

	-- PLAY ANIMATION
	if input_keyTapped("space") and not panel.panned and not panel.clickedCanvas then
		editor_playAnimation()
		-- editor_setToolTip(tip,{temp=true,time=time or 1.5})
	end
	if not input_keyDown("space") and not panel.clickedCanvas then
		panel.panned = false
	end
	if input_keyPressed("return") then
		if cmdDown then
			panel.scrollPos = 0
			editor_playAnimation(nil, 1)
		end
	end

	-- EXIT
	if altDown and input_keyPressed("escape") then
		print("ESCAPEEEEEE SYMBOL")
		if panel.playing then
			panel.playing = false
		else
			if ctx.isAnim then
			else
				input_clearKeys()
				-- namer_warning("Exit without saving",function()
				-- if panel.newImage then
				--   editor_deleteImage(panel.instance.key)
				-- end
				panel.close = true
				-- end)
			end
		end
	end
end

function editor_timelineKeys(panel)
	if contextMenu.open or namer.enabled or panel.clickedCanvas or mouse_getRelativeMode() or editor.orbiting then
		return
	end

	-- KEY COMMANDS

	if input_keyPressed("escape") then
		timeline_deselectRegion()
	end

	local shortenKey, extendKey, moveLeftKey, moveRightKey
	if panel.frameShift then
		shortenKey, extendKey, moveLeftKey, moveRightKey = "", "", "3", "4"
	else
		shortenKey, extendKey, moveLeftKey, moveRightKey = "3", "4", "", ""
	end
	if shiftDown then
		shortenKey, extendKey, moveLeftKey, moveRightKey = moveLeftKey, moveRightKey, shortenKey, extendKey
	end

	-- print(keypressed("up"))

	if input_keyRepeat("up") or (cmdDown and input_keyRepeat("1")) then -- UP LAYER
		if editor_changeLayer(panel, panel.layer + 1) then
			editor_tempTip("Current Layer: " .. panel.layers[panel.layer].name)
		end
	elseif input_keyRepeat("down") or (cmdDown and input_keyRepeat("2")) then -- DOWN LAYER
		if editor_changeLayer(panel, panel.layer - 1) then
			editor_tempTip("Current Layer: " .. panel.layers[panel.layer].name)
		end
	elseif input_keyPressed("5") then -- SOLO LAYER
		editor_tempTip("Solo " .. (panel.solo > 0 and "Off" or "On"))
		panel.solo = panel.solo > 0 and 0 or panel.layer
	elseif panel.l.remodel then
		for i = 1, 6, 1 do
			if input_keyPressed(tostring(i)) then
				if i > 3 then
					panel[panel.meshViewToggles[i - 3]] = not panel[panel.meshViewToggles[i - 3]]
				else
					editor_selectMeshSelectMode(panel, i)
				end
			end
		end

		if not cmdDown or editor.mouseRelative then
			if not panel.meshTransform or not panel.meshTransform.mode then
				if input_keyPressed("g") then -- GRAB
					editor_startMeshTranslate(panel)
				elseif input_keyPressed("s") and not mouse_isDown(3) then -- SCALE
					editor_startMeshScale(panel)
				elseif input_keyPressed("r") then -- ROTATE
					editor_startMeshRotate(panel)
				end

				if input_keyPressed("i") then -- INSET
					editor_startMeshInset(panel)
				elseif input_keyPressed("e") then -- EXTRUDE
					editor_startMeshExtrude(panel)
				end
			elseif input_anyKeyPressed({ "g", "s", "r", "i", "e" }) then
				editor_stopMeshTransform(panel)
			end

			if input_keyPressed("a") then -- (DE)SELECT ALL
				if altDown then
					editor_invertMeshSelect(panel)
				else
					editor_toggleMeshSelect(panel)
				end
			end
		else
		end
	else
		-- if keypressed("j") then
		--  editor_releaseFrames    (panel)
		-- end
		if input_keyRepeat("1") and not (shiftDown or cmdDown) then -- PREV FRAME
			-- editor_deselectRegion()
			editor_dropSelection(panel)
			timeline_refresh()
			if altDown then
				local nk
				local i = panel.frame
				while not nk do
					i = i == 1 and #panel.frames or i - 1
					local frame = panel.frames[i]
					if frame and frame.isKey then
						nk = i
						break
					end
					if i == panel.frame then
						break
					end
				end
				panel.frame = nk or panel.frame
			else
				panel.frame = editor_getAbsoluteFrame(panel) == panel.currentFrame and panel.frame - 1 or panel.frame
			end
			editor_setAbsoluteFrame(panel)
			editor_tempTip("F " .. panel.frame)
		-- panel.pushUndoState("Change Frame")
		elseif input_keyRepeat("2") and not (shiftDown or cmdDown) then -- NEXT FRAME
			-- editor_deselectRegion(panel)
			editor_dropSelection(panel)
			timeline_refresh()
			if altDown then
				local nk
				for i = 1, #panel.frames, 1 do
					if i ~= panel.frame and panel.frames[i].isKey then
						if not nk then
							nk = i
						end
						if i > panel.frame then
							nk = i
							break
						end
					end
				end
				panel.frame = nk or panel.frame
			else
				panel.frame = panel.frame + 1
			end
			editor_setAbsoluteFrame(panel)
			editor_tempTip("F " .. panel.frame)

		-- panel.pushUndoState("Change Frame")
		elseif input_keyRepeat(shortenKey) then -- SHORTEN FRAME
			if panel.frames[panel.frame].l > 1 then
				timeline_refresh()
				panel.pushUndoState("Shorten")
				if panel.currentFrame == editor_getAbsoluteFrame(panel) + panel.frames[panel.frame].l - 1 then
					panel.currentFrame = panel.currentFrame - 1
				end
				panel.frames[panel.frame].l = panel.frames[panel.frame].l - 1
				panel.pushUndoData({ postLength = panel.f.l })
				panel.frames[panel.frame].lastDrawn = os.time()
				editor_tempTip("Frame Length -1")
			end
		elseif input_keyRepeat(extendKey) then -- LENGTHEN FRAME
			timeline_refresh()
			panel.pushUndoState("Lengthen")
			panel.frames[panel.frame].l = panel.frames[panel.frame].l + 1
			panel.pushUndoData({ postLength = panel.f.l })
			panel.frames[panel.frame].lastDrawn = os.time()
			editor_tempTip("Frame Length +1")
		elseif input_keyRepeat(moveLeftKey) then -- MOVE FRAME LEFT
			if panel.frame > 1 and panel.currentFrame > 2 then
				timeline_refresh()
				panel.pushUndoState("Move Frame")
				timeline_shiftFrameLeft()
				panel.pushUndoData({ dLayer = panel.layer, dFrame = panel.currentFrame, dKey = panel.frame })
			else
			end
		elseif input_keyRepeat(moveRightKey) then -- MOVE FRAME RIGHT
			timeline_refresh()
			if panel.frame == 1 then
			--  panel.pushUndoState("Insert Frame")
			--  editor_addBlankFrame(panel,1,true)
			--  panel.pushUndoData({insertedFrames={ frames={panel.frames[panel.frame]},f=panel.frame,l=panel.l }})
			else
				panel.pushUndoState("Move Frame")
				timeline_shiftFrameRight()
				panel.pushUndoData({ dLayer = panel.layer, dFrame = panel.currentFrame, dKey = panel.frame })
			end
		elseif not shiftDown and input_keyRepeat("q") then -- ADD FRAME
			panel.pushUndoState("Insert Frame")
			editor_addBlankFrame(panel)
			panel.pushUndoData({ insertedFrames = { frames = { panel.frames[panel.frame] }, f = panel.frame, l = panel.l } })
		elseif not cmdDown and input_keyPressed("z") then -- ROUGHS
		-- editor_setPenGroup("rough")
		elseif not cmdDown and input_keyPressed("x") then -- LINES
		-- editor_setPenGroup("line")
		elseif not cmdDown and input_keyPressed("c") then -- NOTES
		-- editor_setPenGroup("note")
		elseif shiftDown and input_keyRepeat("q") then -- DUPLICATE FRAME
			-- for i=1,100,1 do
			panel.pushUndoState("Duplicate Frame")
			table.insert(panel.frames, panel.frame + 1, editor_copyFrame(panel, panel.f))
			panel.frame = panel.frame + 1
			applyTransform(panel.frames[panel.frame])
			editor_setAbsoluteFrame(panel)
			editor_tempTip("Duplicate Frame")
			panel.pushUndoData({ insertedFrames = { frames = { panel.f }, f = panel.frame, l = panel.l } })
			timeline_refresh()
		-- end
		elseif not cmdDown and input_keyPressed("s") then -- SPLIT FRAME
			timeline_deselectRegion()
			if panel.f.l > 1 then
				-- panel.pushUndoState()
				editor_setAbsoluteFrame(panel)
				editor_setKeyFrame(panel)
				local nl = panel.f.l / 2

				panel.pushUndoState("Insert Frame")
				panel.currentFrame = panel.currentFrame + mu(nl)
				editor_addBlankFrame(panel)
				editor_tempTip("Split Frame")
				panel.pushUndoData({ insertedFrames = { frames = { panel.frames[panel.frame] }, f = panel.frame, l = panel.l } })
				panel.f.lastDrawn = os.time()
			end
		elseif not cmdDown and input_keyPressed("k") then -- TOGGLE KEY
			timeline_refresh()
			panel.pushUndoState("Toggle Key")
			panel.f.isKey = not panel.f.isKey
			panel.f.lastDrawn = os.time()
			editor_tempTip("Toggle Key")
		elseif cmdDown and input_keyPressed("p") then -- PRUNE FRAME
			panel.pushUndoState("Prune Frame")
			editor_clipFrame(panel.f)
			editor_tempTip("Clipped Frame")
		elseif input_keyPressed("t") then -- TWEEN FRAME
			panel.pushUndoState("Toggle Tween")
			panel.f.tween = panel.f.tween or {}
			panel.f.tween.enabled = not panel.f.tween.enabled
			editor_tempTip("Tween " .. (panel.f.tween.enabled and "Enabled" or "Disabled"))
			timeline_refresh()

		-- elseif keypressed("y") then  -- BLEND ANIMS
		--  panel.pushUndoState()
		--  panel.f.tween.blend = not panel.f.tween.blend
		--  editor_tempTip("Blend "..(panel.f.tween.blend and "Enabled" or "Disabled"))

		-- elseif keypressed("d") then  -- ORIENT FRAME TO CAMERA --temp
		--  if panel.l.type == "drawing" then
		--    panel.pushUndoState()
		--    panel.f.orientation =  quat.rotate(cam.angle.y,axes.x)
		--    panel.f.orientation = quat.rotate(math.angle(cam.pos.x,cam.pos.z,cam.lookTarg.x,cam.lookTarg.z)-pi/2,axes.y)
		--    applyTransform()
		--    editor_tempTip("Orient Frame")
		--  end
		elseif
			(((altDown or cmdDown) and input_keyRepeat("backspace")) or input_keyRepeat("delete"))
			and #panel.frames > 1
		then -- REMOVE FRAMES
			timeline_refresh()
			if panel.region and panel.region.frames and panel.region.rect then
				panel.pushUndoState("Delete Frames")
				editor_setKeyFrame(panel)
				panel.pushUndoData({ copied = timeline_copyRegion(panel.region) })
				timeline_deleteRegion(panel.region)
				-- panel.frame = editor_getKeyFrame(panel,panel.layer,panel.currentFrame)
				panel.region = nil
				editor_tempTip("Deleted Frames")
				timeline_refresh()
			else
				panel.pushUndoState("Delete Frame")
				local alt
				-- if panel.frameShift then
				-- alt = altDown
				-- else
				alt = not altDown
				-- end
				local ladd = alt and panel.f.l or 0
				table.remove(panel.frames, panel.frame)
				panel.frame = panel.frame - 1
				editor_setAbsoluteFrame(panel)
				panel.frames[panel.frame].l = panel.frames[panel.frame].l + ladd
				panel.frames[panel.frame].lastDrawn = os.time()
				editor_tempTip("Deleted Frame")
			end
		elseif cmdDown and not shiftDown and input_keyPressed("a") then -- SELECT ALL FRAME CONTENTS
			if panel.l.format == "vector" then
				local big = 99999
				panel.selection.shape = { -big, -big, big, -big, big, big, -big, big }
			elseif panel.l.format == "raster" then
				local w, h = panel.root.stageWidth, panel.root.stageHeight
				local x, y = (w - panel.f.w) / 2, -(h - panel.f.h) / 2
				panel.selection.shape = { w + x, 0 + y, w + x, h + y, 0 + x, h + y, 0 + x, 0 + y }
			end
			panel.selection.all = true
			panel.tool = "move"
			editor_selectStrokes(panel)
		elseif not (cmdDown and shiftDown) and input_keyPressed("backspace") then -- CLEAR FRAME
			panel.f.lastDrawn = os.time()
      panel.debugStrokes = {}
			timeline_refresh()
			if panel.region and panel.region.frames then
			-- CLEAR ALL FRAMES IN REGION
			else
				if panel.selection.selected then
					if panel.l.format == "vector" then
						editor_cutStrokeSelection(panel, true)
					end
					panel.selection = {}
				elseif not panel.f.blank then
					panel.pushUndoState("Clear Frame")
					if panel.l.format == "vector" then
						-- panel.clearingFrame        = shiftDown -- temp
						local strokes = panel.f.strokes
						local cleared = false
						if strokes and type(strokes) == "table" then
							if panel.phaseClear then
								for s, stroke in lume.ripairs(strokes) do
									if panel.tool == "fill" then
										if stroke.group == "fill" then
											table.remove(panel.f.strokes, s)
											cleared = true
										end
									elseif stroke.group == panel.pen.group then
										table.remove(panel.f.strokes, s)
										cleared = true
									end
								end
							else
								lume.clear(strokes)
								cleared = true
							end
						end

						editor_refreshStrokes()
						if cleared then
							if #strokes == 0 then
								panel.f.blank = true
							end
						else
							-- panel.frames[panel.frame].strokes   = {}
							editor_wipeFrame(panel, panel.f)
						end
					elseif panel.l.format == "raster" then
						panel.f.blank = true
						local packed = editor_packCanvas(panel.f.canvas)
						if packed then
							packed.canvasBefore, packed.canvas = packed.canvas, nil
							panel.pushUndoData({
								rasterDiff = packed,
							})
						end
						editor_wipeFrame(panel, panel.f)
					end
				end
			end
		elseif input_keyPressed("r") then
			panel.pushUndoState()
			panel.f.position = vec3(0)
			panel.f.scale = vec3(1)
			panel.f.orientation = panel.l.iqm and quat.from_angle_axis(-pi / 2, vec3(1, 0, 0)) or quat(0, 1, 0, 1)
			applyTransform(panel.f)
			panel.changed = true
		elseif cmdDown and (input_keyPressed("c") or input_keyPressed("x")) then -- COPY FRAME
			editor_copyFrameContents(panel, input_keyPressed("x"))
		elseif cmdDown and input_keyPressed("v") then -- PASTE FRAME
			editor_pasteFrameContents(panel)
		elseif cmdDown and not altDown and input_keyPressed("g") then -- ADD TO GALLERY
			if panel.selection.selected then
				editor_cutStrokeSelection(panel)
				local new = load_newSymbol()
				if panel.l.format == "vector" then
					new.animations.default.layers[1].frames[1].strokes = copyStrokes(panel.selection.strokes)
				elseif panel.l.format == "raster" then
					new.animations.default.layers[1].frames[1].canvas = panel.selection.canvas
				end
				table.insert(panel.f.symbols, {
					key = new.key,
					uid = uuid(),
					position = vec3(0),
					scale = vec3(1),
					orientation = quat(0, 0, 1, 1),
				})
				panel.selection = {}
				panel.f.blank = false
				editor_refreshStrokes()
			end
		elseif not shiftDown and cmdDown and input_keyPressed("l") then -- NEW LAYER
			editor_newLayer(panel, panel.layer + 1)
		end

		if shiftDown and (input_keyDown("left")) then -- PREV FRAME
			editor_updateFrame(panel, -1)
		elseif input_keyRepeat("left") or (shiftDown and input_keyRepeat("1")) then
			panel.currentFrame = panel.currentFrame - 1
			editor_loopAnimation(panel)
		end

		if shiftDown and (input_keyDown("right")) then -- NEXT FRAME
			editor_updateFrame(panel)
		elseif input_keyRepeat("right") or (shiftDown and input_keyRepeat("2")) then
			panel.currentFrame = panel.currentFrame + 1
			editor_loopAnimation(panel)
		end

		if shiftDown and input_keyPressed("[") and not cmdDown then
			editor_cycleAnimations(panel, -1)
		elseif shiftDown and input_keyPressed("]") and not cmdDown then
			editor_cycleAnimations(panel, 1)
		end
	end

	if cmdDown and input_keyPressed("d") and not lfs.isFused() then
		panel.debugView = not panel.debugView
	end

	if panel.l.type == "drawing" then -- VECTOR TOGGLE
		if panel.l.format == "vector" then
			-- print(cmdDown , keypressed("r") , panel.debugBrushStroke)
			if cmdDown and input_keyPressed("r") then
				if panel.tool == "brush" and panel.debugBrushStroke then
					print("debugbool", panel.debugBoolean, panel.debugShapes)
					if panel.debugBoolean and panel.debugShapes then
						for s = #panel.f.strokes, 1, -1 do
							table.remove(panel.f.strokes, s)
						end
						for s, shape in ipairs(panel.debugShapes) do
							table.insert(panel.f.strokes, shape)
						end
					end
					bool_lineToFill(panel, panel.debugBrushStroke)
				end
				if (panel.tool == "move" or panel.tool == "select") and panel.debugSelection then
					for s = #panel.f.strokes, 1, -1 do
						if panel.f.strokes[s].debug then
							table.remove(panel.f.strokes, s)
						end
					end
					panel.selection = lume.clone(panel.debugSelection)
					editor_selectStrokes(panel)
				end
				editor_refreshStrokes()
			end
			-- if keyDown("]") then
			--  if shiftDown and not cmdDown then
			--    editor_refreshStrokes()
			--    for s,stroke in pairs(panel.f.strokes) do
			--      if stroke.size then
			--        stroke.size = stroke.size + 0.1
			--      end
			--    end
			--  end
			-- elseif keyDown("[") then
			--  if shiftDown and not cmdDown then
			--    editor_refreshStrokes()
			--    for s,stroke in pairs(panel.f.strokes) do
			--      if stroke.size then
			--        stroke.size = stroke.size - 0.1
			--      end
			--    end
			--  end
			-- end
		end
	else
		if input_keyPressed("w") then -- WIRE FRAME
			panel.pushUndoState()
			panel.l.wireframe = not panel.l.wireframe
			editor_tempTip("Wireframe " .. (panel.l.wireframe and "Enabled" or "Disabled"))
		end
	end

	if input_keyPressed("tab") then
		-- if cam then
		-- print(cam)
		--  for k,v in pairs(cam) do
		--    print(k,v)
		--  end
		-- end
		local cam = ctx.viewport.camera
		print("camera info", cam.pos.x, cam.pos.y, cam.soom, -panel.savedHeight / 2)
		if cam.pos.x == 0 and panel.visible and cam.soom == 1 then
      print("twen1")
			scene_tween(cam.pos, { y = 0 }, 0.2, "easeOut", 1)
		end
		if cam.pos.x == 0 and not panel.visible and cam.soom == 1 then
      print("twen2")
			scene_tween(cam.pos, { y = panel.savedHeight / 2 }, 0.2, "easeOut", 1)
		end
		panel.visible = not panel.visible
	end

	if input_keyPressed("m") and panel.l.type == "model" then
		if not mouse_isDown(3) then -- EDIT MESH
			panel.pushUndoState()
			panel.l.remodel = not panel.l.remodel
			panel.l.updots = true
			editor_tempTip("Mesh edit " .. (panel.l.remodel and "Enabled" or "Disabled"))
			if panel.l.remodel then
				editor_clearBones(panel)
			end
		end
	end

	if ctx.isAnim and cmdDown and input_keyPressed("e") then
		if shiftDown then -- EXPORT
		-- export wholeanim
		else
			-- export cut
			panel.triggerExport = true
		end
	end

	-- if panel.currentFrame~=panel.prevCurrentFrame then
	-- editor_setKeyFrame(panel)
	-- end
end

function editor_cycleAnimations(panel, n)
	local anims = sortBy(panel.anims, "name")
	local v, i = lume.match(anims, function(x)
		return x.key == panel.anim
	end)
	local i2 = i + n
	local switchto = anims[i2 < 1 and #anims or (i2 > #anims and 1 or i2)].key
	editor_switchAnimation(switchto)
end
