Input:
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URLDecoder;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import javax.annotation.PostConstruct;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.ResourceUtils;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.SessionAttribute;
import org.springframework.web.multipart.MultipartFile;
import com.github.pagehelper.util.StringUtil;
import cn.gson.oasys.model.dao.attendcedao.AttendceDao;
import cn.gson.oasys.model.dao.notedao.AttachmentDao;
import cn.gson.oasys.model.dao.plandao.TrafficDao;
import cn.gson.oasys.model.dao.processdao.BursementDao;
import cn.gson.oasys.model.dao.processdao.DetailsBurseDao;
import cn.gson.oasys.model.dao.processdao.EvectionDao;
import cn.gson.oasys.model.dao.processdao.EvectionMoneyDao;
import cn.gson.oasys.model.dao.processdao.HolidayDao;
import cn.gson.oasys.model.dao.processdao.OvertimeDao;
import cn.gson.oasys.model.dao.processdao.ProcessListDao;
import cn.gson.oasys.model.dao.processdao.RegularDao;
import cn.gson.oasys.model.dao.processdao.ResignDao;
import cn.gson.oasys.model.dao.processdao.ReviewedDao;
import cn.gson.oasys.model.dao.processdao.StayDao;
import cn.gson.oasys.model.dao.processdao.SubjectDao;
import cn.gson.oasys.model.dao.system.StatusDao;
import cn.gson.oasys.model.dao.system.TypeDao;
import cn.gson.oasys.model.dao.user.UserDao;
import cn.gson.oasys.model.entity.attendce.Attends;
import cn.gson.oasys.model.entity.note.Attachment;
import cn.gson.oasys.model.entity.process.AubUser;
import cn.gson.oasys.model.entity.process.Bursement;
import cn.gson.oasys.model.entity.process.DetailsBurse;
import cn.gson.oasys.model.entity.process.Evection;
import cn.gson.oasys.model.entity.process.EvectionMoney;
import cn.gson.oasys.model.entity.process.Holiday;
import cn.gson.oasys.model.entity.process.Overtime;
import cn.gson.oasys.model.entity.process.ProcessList;
import cn.gson.oasys.model.entity.process.Regular;
import cn.gson.oasys.model.entity.process.Resign;
import cn.gson.oasys.model.entity.process.Reviewed;
import cn.gson.oasys.model.entity.process.Stay;
import cn.gson.oasys.model.entity.process.Subject;
import cn.gson.oasys.model.entity.process.Traffic;
import cn.gson.oasys.model.entity.system.SystemStatusList;
import cn.gson.oasys.model.entity.system.SystemTypeList;
import cn.gson.oasys.model.entity.user.User;
import cn.gson.oasys.services.process.ProcessService;

Context:
src/main/java/cn/gson/oasys/controller/process/ProcedureController.java
							traffic.setUser(u);
							traffic.setEvection(eve);

						}
						List<Stay> mm=eve.getStay();
						for (Stay stay : mm) {
							allmoney+=stay.getStayMoney()*stay.getDay();
							User u=udao.findByUserName(stay.getNameuser());
							stay.setUser(u);
							stay.setEvemoney(eve);
						}

						eve.setMoney(allmoney);
						//set主表
						ProcessList pro=eve.getProId();
						System.out.println(pro+"mmmmmm");
						proservice.index5(pro, val, lu, filePath,shen.getUserName());
						emdao.save(eve);
						//存审核表
						proservice.index7(shen, pro);
					}else{
						return "common/proce";
					}

				return "redirect:/flowmanage";

	}
	//出差申请
	@RequestMapping("evection")
	public String evection(Model model, @SessionAttribute("userId") Long userId,HttpServletRequest request,
			@RequestParam(value = "page", defaultValue = "0") int page,
			@RequestParam(value = "size", defaultValue = "10") int size){
		//查找类型
		List<SystemTypeList> outtype=tydao.findByTypeModel("aoa_evection");
		proservice.index6(model, userId, page, size);
		model.addAttribute("outtype", outtype);
		return "process/evection";
	}
	/**
	 * 出差申请表单接收
	 * @param model
	 * @param session
	 * @param request
	 * @param page
	 * @param size
	 * @return
	 * @throws IOException
	 * @throws IllegalStateException
	 */
	@RequestMapping("evec")
	public String evec(@RequestParam("filePath")MultipartFile filePath,HttpServletRequest req,@Valid Evection eve,BindingResult br,
			@SessionAttribute("userId") Long userId) throws IllegalStateException, IOException{
		User lu=udao.findOne(userId);//申请人
		User shen=udao.findByUserName(eve.getNameuser());//审核人
		Long roleid=lu.getRole().getRoleId();//申请人角色id
		Long fatherid=lu.getFatherId();//申请人父id
		Long userid=shen.getUserId();//审核人userid
		String val=req.getParameter("val");
		if(roleid>=3L && Objects.equals(fatherid, userid)){
			//set主表
			ProcessList pro=eve.getProId();
			proservice.index5(pro, val, lu, filePath,shen.getUserName());
			edao.save(eve);
			//存审核表
			proservice.index7(shen, pro);
		}else{
			return "common/proce";
		}

		return "redirect:/xinxeng";
	}
	//加班申请
		@RequestMapping("overtime")
		public String overtime(Model model, @SessionAttribute("userId") Long userId,HttpServletRequest request,
				@RequestParam(value = "page", defaultValue = "0") int page,
				@RequestParam(value = "size", defaultValue = "10") int size){
			//查找类型
			List<SystemTypeList> overtype=tydao.findByTypeModel("aoa_overtime");
			proservice.index6(model, userId, page, size);
			model.addAttribute("overtype", overtype);
			return "process/overtime";
		}
	/**
	 * 加班申请接收
	 * @param model
	 * @param session
	 * @param request
	 * @param page
	 * @param size
	 * @return
	 */
		@RequestMapping("over")
		public String over(HttpServletRequest req,@Valid Overtime eve,BindingResult br,
				@SessionAttribute("userId") Long userId) throws IllegalStateException, IOException{
			User lu=udao.findOne(userId);//申请人
			User shen=udao.findByUserName(eve.getNameuser());//审核人
			Long roleid=lu.getRole().getRoleId();//申请人角色id
			Long fatherid=lu.getFatherId();//申请人父id
			Long userid=shen.getUserId();//审核人userid
			String val=req.getParameter("val");
			if(roleid>=3L && Objects.equals(fatherid, userid)){
				//set主表
				ProcessList pro=eve.getProId();
				proservice.index8(pro, val, lu,shen.getUserName());
				odao.save(eve);
				//存审核表
				proservice.index7(shen, pro);
			}else{
				return "common/proce";
			}

			return "redirect:/xinxeng";

		}
	//请假申请
	@RequestMapping("holiday")
	public String holiday(Model model, @SessionAttribute("userId") Long userId,HttpServletRequest request,
			@RequestParam(value = "page", defaultValue = "0") int page,
			@RequestParam(value = "size", defaultValue = "10") int size){
		//查找类型

src/main/java/cn/gson/oasys/model/dao/system/StatusDao.java
@Repository
public interface StatusDao extends PagingAndSortingRepository<SystemStatusList, Long>{

	//根据模块名和名字查找到唯一对象
	SystemStatusList findByStatusModelAndStatusName(String statusModel,String statusName);

	//根据模块名查找到状态集合
	List<SystemStatusList> findByStatusModel(String statusModel);

	List<SystemStatusList> findByStatusNameLikeOrStatusModelLike(String name,String name2);

	@Query("select sl.statusName from SystemStatusList sl where sl.statusId=:id")
	String findname(@Param("id")Long id);

	@Query("select sl.statusColor from SystemStatusList sl where sl.statusId=:id")
	String findcolor(@Param("id")Long id);

}

src/main/java/cn/gson/oasys/model/dao/processdao/HolidayDao.java
public interface HolidayDao extends PagingAndSortingRepository<Holiday, Long>{

	Holiday findByProId(ProcessList pro);

}

src/main/java/cn/gson/oasys/model/entity/process/Traffic.java
@Entity
@Table(name="aoa_traffic")
//交通费用明细表
public class Traffic {

	@Id
	@Column(name="traffic_id")
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	private Long trafficId;

	@OneToOne
	@JoinColumn(name="user_name")
	private User user;//出差人员

	@Column(name="depart_time")
	private Date departTime;//出发时间

	@Column(name="depart_name")
	private String departName;//出发城市

	@Column(name="reach_name")
	private String reachName;//到达城市

	@Column(name="traffic_name")
	private String trafficName;//交通工具

	@Column(name="seat_type")
	private String seatType;//座位类型

	@Column(name="traffic_money")
	private Double trafficMoney;//交通标准

	@ManyToOne()
	@JoinColumn(name="evection_id")
	private  EvectionMoney  evection;

	@Transient
	private String username;

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public Long getTrafficId() {
		return trafficId;
	}

	public void setTrafficId(Long trafficId) {
		this.trafficId = trafficId;
	}

	public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}

	public Date getDepartTime() {
		return departTime;
	}

	public void setDepartTime(Date departTime) {
		this.departTime = departTime;
	}

	public String getDepartName() {
		return departName;
	}

	public void setDepartName(String departName) {
		this.departName = departName;
	}

	public String getReachName() {
		return reachName;
	}

	public void setReachName(String reachName) {
		this.reachName = reachName;
	}

	public String getTrafficName() {
		return trafficName;
	}

	public void setTrafficName(String trafficName) {
		this.trafficName = trafficName;
	}

	public String getSeatType() {
		return seatType;
	}

	public void setSeatType(String seatType) {
		this.seatType = seatType;
	}

	public Double getTrafficMoney() {
		return trafficMoney;
	}

	public void setTrafficMoney(Double trafficMoney) {
		this.trafficMoney = trafficMoney;
	}

	public EvectionMoney getEvection() {
		return evection;
	}

	public void setEvection(EvectionMoney evection) {
		this.evection = evection;
	}

	@Override
	public String toString() {
		return "Traffic [trafficId=" + trafficId + ", departTime=" + departTime + ", departName=" + departName
				+ ", reachName=" + reachName + ", trafficName=" + trafficName + ", seatType=" + seatType
				+ ", evection=" + evection + ", username=" + username + "]";
	}

}

src/main/java/cn/gson/oasys/model/dao/processdao/DetailsBurseDao.java
public interface DetailsBurseDao extends PagingAndSortingRepository<DetailsBurse, Long>{

	List<DetailsBurse> findByBurs(Bursement bu);
}

src/main/java/cn/gson/oasys/model/dao/processdao/ReviewedDao.java
public interface ReviewedDao extends PagingAndSortingRepository<Reviewed, Long>{

	//根据审核人查找流程
	@Query("select new cn.gson.oasys.model.entity.process.AubUser(pro.processId,pro.typeNmae,pro.deeply,pro.processName,pro.userId.userName,pro.applyTime,rev.statusId) "
			+ "from ProcessList as pro,Reviewed as rev where rev.proId.processId=pro.processId and rev.userId=?1 and rev.del=?2 order by rev.statusId")
	Page<AubUser> findByUserIdOrderByStatusId(User user,Boolean bo,Pageable pa);

	//根据申请人和审核人查找流程
	@Query("select new cn.gson.oasys.model.entity.process.AubUser(pro.processId,pro.typeNmae,pro.deeply,pro.processName,pro.userId.userName,pro.applyTime,rev.statusId) "
			+ "from ProcessList as pro,Reviewed as rev where rev.proId.processId=pro.processId and rev.userId=?1 and pro.userId=?2 and rev.del=?3 order by rev.statusId")
	Page<AubUser> findprocesslist(User user,User u,Boolean bo,Pageable pa);

	//根据状态和审核人查找流程
	@Query("select new cn.gson.oasys.model.entity.process.AubUser(pro.processId,pro.typeNmae,pro.deeply,pro.processName,pro.userId.userName,pro.applyTime,rev.statusId) "
			+ "from ProcessList as pro,Reviewed as rev where rev.proId.processId=pro.processId and rev.userId=?1 and rev.statusId=?2 and rev.del=?3 order by rev.statusId")
	Page<AubUser> findbystatusprocesslist(User user,Long statusid,Boolean bo,Pageable pa);

	//根据类型名和审核人查找流程
	@Query("select new cn.gson.oasys.model.entity.process.AubUser(pro.processId,pro.typeNmae,pro.deeply,pro.processName,pro.userId.userName,pro.applyTime,rev.statusId) "
			+ "from ProcessList as pro,Reviewed as rev where rev.proId.processId=pro.processId and rev.userId=?1 and pro.typeNmae=?2 and rev.del=?3 order by rev.statusId")
	Page<AubUser> findbytypenameprocesslist(User user,String typename,Boolean bo,Pageable pa);

	//根据标题和审核人查找流程
	@Query("select new cn.gson.oasys.model.entity.process.AubUser(pro.processId,pro.typeNmae,pro.deeply,pro.processName,pro.userId.userName,pro.applyTime,rev.statusId) "
			+ "from ProcessList as pro,Reviewed as rev where rev.proId.processId=pro.processId and rev.userId=?1 and pro.processName like %?2% and rev.del=?3 order by rev.statusId")
	Page<AubUser> findbyprocessnameprocesslist(User user,String processname,Boolean bo,Pageable pa);

	List<Reviewed> findByReviewedTimeNotNullAndProId(ProcessList pro);

	@Query(" select re from Reviewed as re where re.proId.processId=?1 and re.userId=?2")
	Reviewed findByProIdAndUserId(Long pro,User u);

}

src/main/java/cn/gson/oasys/model/entity/process/Resign.java
@Table
@Entity(name="aoa_resign")
//离职表
public class Resign {

	@Id
	@Column(name="resign_id")
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	private Long resignId;

	private String suggest;//申请人的意见及建议

	@Column(name="is_finish")
	private Boolean finish=false;//是否还有费用报销未完成

	@OneToOne
	@JoinColumn(name="hand_user")
	private User  handUser; //工作交接人员

	private String nofinish;//未完成事宜

	@Column(name="financial_advice")
	private String financialAdvice;//财务部意见及说明

	@Column(name="personnel_advice")
	private String personnelAdvice;//人事部意见及说明

	@Column(name="manager_advice")
	private String managerAdvice;//经理意见及说明

	@OneToOne(cascade=CascadeType.ALL)
	@JoinColumn(name="pro_id")
	private ProcessList proId;

	@Transient
	private String nameuser;//审核人员

	@Transient
	private String handuser;//交接人员

	public String getManagerAdvice() {
		return managerAdvice;
	}

	public void setManagerAdvice(String managerAdvice) {
		this.managerAdvice = managerAdvice;
	}

	public String getNameuser() {
		return nameuser;
	}

	public void setNameuser(String nameuser) {
		this.nameuser = nameuser;
	}

	public String getHanduser() {
		return handuser;
	}

	public void setHanduser(String handuser) {
		this.handuser = handuser;
	}

	public ProcessList getProId() {
		return proId;
	}

	public void setProId(ProcessList proId) {
		this.proId = proId;
	}

	public Long getResignId() {
		return resignId;
	}

	public void setResignId(Long resignId) {
		this.resignId = resignId;
	}

	public String getSuggest() {
		return suggest;
	}

	public void setSuggest(String suggest) {
		this.suggest = suggest;
	}

	public Boolean getFinish() {
		return finish;
	}

	public void setFinish(Boolean finish) {
		this.finish = finish;
	}

	public User getHandUser() {
		return handUser;
	}

	public void setHandUser(User handUser) {
		this.handUser = handUser;
	}

	public String getNofinish() {
		return nofinish;
	}

	public void setNofinish(String nofinish) {
		this.nofinish = nofinish;
	}

	public String getFinancialAdvice() {
		return financialAdvice;
	}

	public void setFinancialAdvice(String financialAdvice) {
		this.financialAdvice = financialAdvice;
	}

	public String getPersonnelAdvice() {
		return personnelAdvice;
	}

	public void setPersonnelAdvice(String personnelAdvice) {
		this.personnelAdvice = personnelAdvice;
	}

	@Override
	public String toString() {
		return "Resign [resignId=" + resignId + ", suggest=" + suggest + ", finish=" + finish + ", handUser=" + handUser
				+ ", nofinish=" + nofinish + ", financialAdvice=" + financialAdvice + ", personnelAdvice="
				+ personnelAdvice + ", managerAdvice=" + managerAdvice + ", nameuser=" + nameuser + ", handuser="
				+ handuser + "]";
	}

}

src/main/java/cn/gson/oasys/model/dao/processdao/StayDao.java
public interface StayDao extends PagingAndSortingRepository<Stay, Long>{

	List<Stay> findByEvemoney(EvectionMoney money);
}

src/main/java/cn/gson/oasys/services/process/ProcessService.java
@Service
@Transactional
public class ProcessService {
	@Autowired
	private UserDao udao;
	@Autowired
	private DeptDao ddao;
	@Autowired
	private RoleDao rdao;
	@Autowired
	private PositionDao pdao;
	@Autowired
	private SubjectDao sudao;
	@Autowired
	private StatusDao sdao;
	@Autowired
	private TypeDao tydao;
	@Autowired
	private ReviewedDao redao;
	@Autowired
	private AttachmentDao AttDao;
	@Autowired
	private BursementDao budao;
	@Autowired
	private MailServices mservice;
	@Autowired
	private ProcessListDao prodao;
	 /**
     * 汉语中数字大写
     */
  private static final String[] CN_UPPER_NUMBER = { "零", "壹", "贰", "叁", "肆",
            "伍", "陆", "柒", "捌", "玖" };
   /**
    * 汉语中货币单位大写，这样的设计类似于占位符
     */
   private static final String[] CN_UPPER_MONETRAY_UNIT = { "分", "角", "元",
           "拾", "佰", "仟", "万", "拾", "佰", "仟", "亿", "拾", "佰", "仟", "兆", "拾",
           "佰", "仟" };
   /**
     * 特殊字符：整
    */
  private static final String CN_FULL = "整";
 /**
     * 特殊字符：负
    */
  private static final String CN_NEGATIVE = "负";
  /**
     * 金额的精度，默认值为2
    */
  private static final int MONEY_PRECISION = 2;
  /**
     * 特殊字符：零元整
    */
  private static final String CN_ZEOR_FULL = "零元" + CN_FULL;

	/**
	 * 写文件 方法
	 *
	 * @param response
	 * @param file
	 * @throws IOException
	 */
	public void writefile(HttpServletResponse response, File file) {
		ServletOutputStream sos = null;
		FileInputStream aa = null;
		try {
			aa = new FileInputStream(file);
			sos = response.getOutputStream();
			// 读取文件问字节码
			byte[] data = new byte[(int) file.length()];
			IOUtils.readFully(aa, data);
			// 将文件流输出到浏览器
			IOUtils.write(data, sos);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
			try {
				sos.close();
				aa.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

	}
  /**
   * 用户封装
   * @param user
   * @param page
   * @param size
   * @param val
   * @return
   */
	public void user(int page,int size,Model model){
		Pageable pa=new PageRequest(page, size);
		//查看用户并分页
		Page<User> pageuser=udao.findAll(pa);
		List<User> userlist=pageuser.getContent();
		// 查询部门表
		Iterable<Dept> deptlist = ddao.findAll();
		// 查职位表
		Iterable<Position> poslist = pdao.findAll();
		model.addAttribute("page", pageuser);
		model.addAttribute("emplist", userlist);
		model.addAttribute("deptlist", deptlist);
		model.addAttribute("poslist", poslist);
		model.addAttribute("url", "names");
	}

	public Page<AubUser> index(User user,int page,int size,String val,Model model){
		Pageable pa=new PageRequest(page, size);
		Page<AubUser> pagelist=null;
		Page<AubUser> pagelist2=null;
		List<Order> orders = new ArrayList<>();
		User  u=udao.findByUserName(val);//找用户
		SystemStatusList status=sdao.findByStatusModelAndStatusName("aoa_process_list", val);
		if(StringUtil.isEmpty(val)){
			orders.add(new Order(Direction.DESC, "applyTime"));
			Sort sort = new Sort(orders);
			pa=new PageRequest(page, size,sort);
			pagelist=redao.findByUserIdOrderByStatusId(user,false, pa);
		}else if(!Objects.isNull(u)){
			pagelist=redao.findprocesslist(user,u,false,pa);
			model.addAttribute("sort", "&val="+val);
		}else if(!Objects.isNull(status)){
			pagelist=redao.findbystatusprocesslist(user,status.getStatusId(),false,pa);
			model.addAttribute("sort", "&val="+val);
		}else{
			pagelist2=redao.findbytypenameprocesslist(user, val,false, pa);
			if(!pagelist2.hasContent()){
				pagelist2=redao.findbyprocessnameprocesslist(user, val,false, pa);
			}
			model.addAttribute("sort", "&val="+val);
			return pagelist2;
		}
		return pagelist;
	}

	public List<Map<String,Object>> index2(Page<AubUser> page,User user){
		List<Map<String, Object>> list = new ArrayList<>();
		List<AubUser> prolist=page.getContent();
		for (int i = 0; i < prolist.size(); i++) {
			String harryname=tydao.findname(prolist.get(i).getDeeply());
			SystemStatusList status=sdao.findOne(prolist.get(i).getStatusId());
			Map<String, Object> result=new HashMap<>();
			result.put("typename", prolist.get(i).getTypeNmae());
			result.put("title", prolist.get(i).getProcessName());
			result.put("pushuser", prolist.get(i).getUserName());
			result.put("applytime",  prolist.get(i).getApplyTime());
			result.put("harry", harryname);
			result.put("statusname", status.getStatusName());
			result.put("statuscolor", status.getStatusColor());
			result.put("proid", prolist.get(i).getProcessId());
			list.add(result);

		}
		return list;
	}
	/**
	 * 审核人封装
	 */
	public List<Map<String,Object>> index4(ProcessList process){
		List<Map<String,Object>> relist=new ArrayList<>();
		List<Reviewed> revie=redao.findByReviewedTimeNotNullAndProId(process);
		for (int i = 0; i <revie.size(); i++) {
			Map<String, Object> result=new HashMap<>();
			User u=udao.findOne(revie.get(i).getUserId().getUserId());
			Position po=pdao.findOne(u.getPosition().getId());
			SystemStatusList status=sdao.findOne(revie.get(i).getStatusId());
			result.put("poname", po.getName());
			result.put("username", u.getUserName());
			result.put("retime",revie.get(i).getReviewedTime());
			result.put("restatus",status.getStatusName());
			result.put("statuscolor",status.getStatusColor());
			result.put("des", revie.get(i).getAdvice());
			result.put("img",u.getImgPath());
			result.put("positionid",u.getPosition().getId());
			relist.add(result);
		}
		return relist;
	}
	/**
	 * process数据封装
	 */

	public Map<String,Object> index3(String name,User user,String typename,ProcessList process){
		System.out.println(name);
		Map<String,Object> result=new HashMap<>();
		String harryname=tydao.findname(process.getDeeply());
		result.put("proId", process.getProcessId());
		result.put("harryname", harryname);
		result.put("processName", process.getProcessName());
		result.put("processDescribe",process.getProcessDescribe());
		if(("审核").equals(name)){
			result.put("username", process.getUserId().getUserName());//提单人员
			result.put("deptname", ddao.findname(process.getUserId().getDept().getDeptId()));//部门
		}else if(("申请").equals(name)){
			result.put("username", user.getUserName());
			result.put("deptname", ddao.findname(process.getUserId().getDept().getDeptId()));
		}
		result.put("applytime", process.getApplyTime());
		if(!Objects.isNull(process.getProFileid())){
			result.put("file", process.getProFileid());
		}else{
			result.put("file", "file");
		}
		result.put("name", name);
		result.put("typename", process.getTypeNmae());
		result.put("startime", process.getStartTime());
		result.put("endtime", process.getEndTime());
		result.put("tianshu", process.getProcseeDays());
		result.put("statusid", process.getStatusId());
		if( process.getProFileid()!=null){
		   result.put("filepath", process.getProFileid().getAttachmentPath());
			if(process.getProFileid().getAttachmentType().startsWith("image")){
				result.put("filetype", "img");
			}else{
				result.put("filetype", "appli");
			}
		}
		return result;
	}
	/**
	 * 公用
	 */
	public void  index6(Model model,Long id,int page,int size){
		User lu=udao.findOne(id);//申请人
		Pageable pa=new PageRequest(page, size);
		List<SystemTypeList> harrylist=tydao.findByTypeModel("aoa_process_list");
		//查看用户并分页
		Page<User> pageuser=udao.findAll(pa);
		List<User> userlist=pageuser.getContent();
		// 查询部门表
		Iterable<Dept> deptlist = ddao.findAll();
		// 查职位表
		Iterable<Position> poslist = pdao.findAll();
		model.addAttribute("page", pageuser);
		model.addAttribute("emplist", userlist);
		model.addAttribute("deptlist", deptlist);
		model.addAttribute("poslist", poslist);
		model.addAttribute("url", "names");
		model.addAttribute("username", lu.getUserName());
		model.addAttribute("harrylist", harrylist);
	}
	/**
	 * 存表
	 * @throws IOException
	 * @throws IllegalStateException
	 */
	public void index5(ProcessList pro,String val,User lu,MultipartFile filePath,String name) throws IllegalStateException, IOException{

		pro.setTypeNmae(val);
		pro.setApplyTime(new Date());
		pro.setUserId(lu);
		pro.setStatusId(23L);
		pro.setShenuser(name);
		Attachment attaid=null;
		if(!StringUtil.isEmpty(filePath.getOriginalFilename())){
			attaid=mservice.upload(filePath, lu);
			attaid.setModel("aoa_bursement");
			AttDao.save(attaid);
			pro.setProFileid(attaid);
		}
	}
	public void index8(ProcessList pro,String val,User lu,String name) {
		pro.setTypeNmae(val);
		pro.setApplyTime(new Date());
		pro.setUserId(lu);
		pro.setStatusId(23L);
		pro.setShenuser(name);
	}
	/**
	 * 存主表
	 */
	public void save(Long proid,User u,Reviewed reviewed,ProcessList pro,User u2){
		Reviewed re=redao.findByProIdAndUserId(proid,u);
		re.setAdvice(reviewed.getAdvice());
		re.setStatusId(reviewed.getStatusId());
		re.setReviewedTime(new Date());
		re.setStatusId(reviewed.getStatusId());
		redao.save(re);

		Reviewed re2=new  Reviewed();
		re2.setProId(pro);
		re2.setUserId(u2);
		re2.setStatusId(23L);
		redao.save(re2);

		pro.getShenuser();
		pro.setShenuser(pro.getShenuser()+";"+u2.getUserName());
		pro.setStatusId(24L);//改变主表的状态
		prodao.save(pro);
	}
	/**
	 * 存审核表
	 */
	public void index7(User reuser,ProcessList pro){
		Reviewed revie=new Reviewed();
		revie.setUserId(reuser);
		revie.setStatusId(23L);
		revie.setProId(pro);
		redao.save(revie);
	}
	/**
	      * 把输入的金额转换为汉语中人民币的大写
	       *
	      * @param numberOfMoney
	      *            输入的金额
	      * @return 对应的汉语大写
	      */
	    public static String number2CNMontrayUnit(BigDecimal numberOfMoney) {
	         StringBuffer sb = new StringBuffer();
	        // -1, 0, or 1 as the value of this BigDecimal is negative, zero, or
	       // positive.
	        int signum = numberOfMoney.signum();
	        // 零元整的情况
	         if (signum == 0) {
	             return CN_ZEOR_FULL;
	       }
	        //这里会进行金额的四舍五入
	         long number = numberOfMoney.movePointRight(MONEY_PRECISION)
	                .setScale(0, 4).abs().longValue();
	        // 得到小数点后两位值
	         long scale = number % 100;
	        int numUnit = 0;
	        int numIndex = 0;
	        boolean getZero = false;
	        // 判断最后两位数，一共有四中情况：00 = 0, 01 = 1, 10, 11
	        if (!(scale > 0)) {
	            numIndex = 2;
	             number = number / 100;
	             getZero = true;
	        }
	        if ((scale > 0) && (!(scale % 10 > 0))) {
	             numIndex = 1;
	            number = number / 10;
	             getZero = true;
	        }
	        int zeroSize = 0;
	        while (true) {
	             if (number <= 0) {
	                break;
	            }
	           // 每次获取到最后一个数
	           numUnit = (int) (number % 10);
	             if (numUnit > 0) {
	                 if ((numIndex == 9) && (zeroSize >= 3)) {
	                     sb.insert(0, CN_UPPER_MONETRAY_UNIT[6]);
	                }
	               if ((numIndex == 13) && (zeroSize >= 3)) {
	                    sb.insert(0, CN_UPPER_MONETRAY_UNIT[10]);
	              }
	                sb.insert(0, CN_UPPER_MONETRAY_UNIT[numIndex]);
	                 sb.insert(0, CN_UPPER_NUMBER[numUnit]);
	                getZero = false;
	                zeroSize = 0;
	            } else {
	                ++zeroSize;
	                if (!(getZero)) {
	                   sb.insert(0, CN_UPPER_NUMBER[numUnit]);
	                }
	               if (numIndex == 2) {
	                   if (number > 0) {
	                        sb.insert(0, CN_UPPER_MONETRAY_UNIT[numIndex]);
	                    }
	                } else if (((numIndex - 2) % 4 == 0) && (number % 1000 > 0)) {
	                    sb.insert(0, CN_UPPER_MONETRAY_UNIT[numIndex]);
	                }
	               getZero = true;
	            }
	             // 让number每次都去掉最后一个数
	             number = number / 10;
	            ++numIndex;
	         }
	        // 如果signum == -1，则说明输入的数字为负数，就在最前面追加特殊字符：负
	         if (signum == -1) {
	            sb.insert(0, CN_NEGATIVE);
	        }
	        // 输入的数字小数点后两位为"00"的情况，则要在最后追加特殊字符：整
	       if (!(scale > 0)) {
	           sb.append(CN_FULL);
	       }
	        return sb.toString();
	    }

	    public static String numbertocn(Double money){
	    	BigDecimal numberOfMoney = new BigDecimal(money);
	        String s = number2CNMontrayUnit(numberOfMoney);
	        System.out.println("你输入的金额为：【"+ money +"】   #--# [" +s.toString()+"]");
	          return s.toString();
	    }

}

Answer: List<SystemTypeList> overtype=tydao.findByTypeModel("aoa_holiday");

<think>
The method holiday begins similarly to evection and overtime: it needs to retrieve the list of system types for holiday requests. The pattern is to call tydao.findByTypeModel with the appropriate type model string and store it in a List variable. For holiday the type model is likely "aoa_holiday" and the variable follows the naming convention used earlier (e.g., outtype, overtype). Therefore the next line should retrieve this list.
</think>
List<SystemTypeList> holtype = tydao.findByTypeModel("aoa_holiday");


Input:
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Animation;
import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.scenes.scene2d.Actor;
import com.senetboom.game.SenetBoom;
import static com.senetboom.game.SenetBoom.*;

Context:
core/src/com/senetboom/game/backend/Stick.java
package com.senetboom.game.backend;

public class Stick {

    private StickRoll[] stickRolls;
    private int stickValue;
    private static float maxTime = 1.5f;
    private static float elapsedTime = 0;

    // every time a new Stick is created, we need to create a new RollingSticks actor and add it to the stage
    // also save the value of the stick in the stickValue variable

    public Stick() {
        // rolling Sticks
        this.stickRolls = new StickRoll[4];
        this.stickValue = 0;
        for (int i = 0; i < 4; i++) {
            this.stickRolls[i] = new StickRoll();
            this.stickValue += this.stickRolls[i].getStickRoll();
        }
        if(stickValue == 0){ // 4 blacks equal value 6
            stickValue = 6;
        }

        // create RollingsSticks actor and add to stage
        RollingSticks rollingSticks = new RollingSticks();
        SenetBoom.stickStage.addActor(rollingSticks);

        // set sticksTumbling to true

core/src/com/senetboom/game/SenetBoom.java
public class SenetBoom extends ApplicationAdapter {

	// for the stage the bot moves a piece on
	public static Group botMovingStage;

	// for the empty tile texture
	public static Texture emptyTexture;

	// for the empty variables (the tiles that are currently moved by a bot)
	public static int emptyVariable;

	// for the possible moves that the bot uses for decision-making
	// Array of int values
	public static ArrayList<Integer> possibleMoves;
	public static int possibleMove;

	// for the batch
	SpriteBatch batch;

	// for the background
	Texture background;

	// for the currentStage
	static Stage currentStage;

	// stage options
	public static boolean showOptions;
	Stage OptionsStage;

	// stage credit
	boolean showCredits;
	Stage CreditsStage;

	// stick stage
	public static Stage stickStage;

	// typeWriterStage
	public static Stage typeWriterStage;

	// hitStage
	Stage hitStage;
	Animation<TextureRegion> hitAnimation;

	// helpOverlayStage
	static Stage helpOverlayStage;
	Texture help;
	public static boolean displayHelp;
	Texture hand;
	// for the pieces textures unselected
	public static Texture blackpiece;
	public static Texture whitepiece;

	// for the turn constant
	static Turn gameState;

	// for the game boolean value of it having just started
	public static boolean gameStarted;

	// for the tileSize relative to screenSize from RelativeResizer
	public static float tileSize;

	// textures for special state
	public static Texture happy;
	public static Texture water;
	public static Texture safe;
	public static Texture rebirth;

	// boolean determining if the game is in progress
	public static boolean inGame;

	// typewriter
	public static Typewriter typeWriter;

	// for knowing when to skip the Turn
	public static boolean skipTurn;

	public static Texture logo;

	// for the textbutton skin
	public static Skin skin;

	// if the Sticks are Tumbling
	public static boolean sticksTumbling;

	// current Stick value
	public static int currentStickValue;
	// Sticks
	public static Stick gameSticks;

	//Game End Stage
	public static Stage gameEndStage;

	// legitMove boolean
	public static boolean legitMove;

	// rebirth protection
	public static Texture rebirthProtection;

	// for the music volume
	public static float volume;

	// texture for the tile
	public static Texture tileTexture;

	// map stage
	public static Stage mapStage;

	// boolean for an extra turn
	public static boolean extraTurn;
	// texture
	public static Texture extraTurnTexture;

	//stage for extra turn
	public static Stage extraTurnStage;

	// stick value Stage
	private static Stage stickValueStage;

	// textures for the sticks
	public static Texture blackStick;
	public static Texture whiteStick;

	// number textures
	public static Texture number0;
	public static Texture number1;
	public static Texture number2;
	public static Texture number3;
	public static Texture number4;
	public static Texture number6;

	// for the game start
	public static boolean startUndecided;
	public static Stage deciderStage;

	// textures of starter
	public static Texture whiteStarts;
	public static Texture blackStarts;

	// boolean for the decider
	public static boolean deciderStarted;

	// for when a turn has not been checked yet
	public static boolean gameUnchecked;

	// hint stage
	public static Stage hintStage;

	// for displaying the current Turn
	public static Stage currentTurnStage;

	// turn play textures
	public static Texture whitePlays;
	public static Texture blackPlays;

	// texture for the help
	public static Texture helpTexture;

	// no moves texture
	public static Texture noMovesTexture;

	public static boolean displayHint = false;

	public static Texture possibleMoveTexture;

	public static boolean needRender;

	// for the arms
	public static Image armFromBelow;
	public static Image armFromAbove;

	// for the advanced arm stages and their respective boolean

	public static Stage armFromBelowStage;
	public static Stage armFromAboveStage;
	public static boolean showArmFromBelowStage;
	public static boolean showArmFromAboveStage;

	public static MusicPlaylist musicPlaylist;

	// enum of turn
	private enum Turn {
		PLAYERWHITE,
		PLAYERBLACK,
	}

	@Override
	public void create () {
		batch = new SpriteBatch();
		background = new Texture("textures/background.png");

		// from scene2dUi
		currentStage = new Stage();
		showOptions = false;
		OptionsStage = new Stage();
		showCredits = false;
		CreditsStage = new Stage();
		inGame = false;
		gameStarted = false;
		gameEndStage = new Stage();
		stickStage = new Stage();
		typeWriterStage = new Stage();
		hitStage = new Stage();
		helpOverlayStage = new Stage();
		mapStage = new Stage();
		extraTurnStage = new Stage();
		stickValueStage = new Stage();
		deciderStage = new Stage();
		hintStage = new Stage();
		currentTurnStage = new Stage();

		// for the arms

		armFromBelowStage = new Stage();
		armFromAboveStage = new Stage();
		showArmFromBelowStage = false;
		showArmFromAboveStage = false;

		// possible Moves is a ArrayList of int values
		possibleMoves = new ArrayList<Integer>();

		displayHelp = false;
		skipTurn = false;
		sticksTumbling = false;
		legitMove = false;

		// loading the skin
		skin = new Skin(Gdx.files.internal("menu.commodore64/uiskin.json"));

		// loading all textures
		blackpiece = new Texture("textures/blackpiece.png");
		whitepiece = new Texture("textures/whitepiece.png");
		happy = new Texture("textures/happy.png");
		water = new Texture("textures/water.png");
		safe = new Texture("textures/safe.png");
		rebirth = new Texture("textures/rebirth.png");
		rebirthProtection = new Texture("textures/rebirthprotection.png");
		logo = new Texture("logoSenet.png");
		tileTexture = new Texture("textures/tile.png");
		emptyTexture = new Texture("textures/empty.png");
		extraTurnTexture = new Texture("textures/extraTurn.png");
		whiteStarts = new Texture("textures/whiteStart.png");
		blackStarts = new Texture("textures/blackStarts.png");

		// arms

		armFromAboveStage = new Stage();
		armFromBelowStage = new Stage();

		armFromAbove = new Image(new Texture("textures/armabovein.png"));
		armFromBelow = new Image(new Texture("textures/armbelowin.png"));

		armFromAboveStage.addActor(armFromAbove);
		armFromBelowStage.addActor(armFromBelow);

		// for the sticks
		blackStick = new Texture("textures/blackStick.png");
		whiteStick = new Texture("textures/whiteStick.png");

		// for the numbers
		number0 = new Texture("textures/0.png");
		number1 = new Texture("textures/1.png");
		number2 = new Texture("textures/2.png");
		number3 = new Texture("textures/3.png");
		number4 = new Texture("textures/4.png");
		number6 = new Texture("textures/6.png");

		// possible Move Texture
		possibleMoveTexture = new Texture("textures/possibleMove.png");

		// no moves texture
		noMovesTexture = new Texture("textures/noMovesTexture.png");

		// help texture
		helpTexture = new Texture("textures/rules.png");

		// for the turn plays textures
		whitePlays = new Texture("textures/whitePlays.png");
		blackPlays = new Texture("textures/blackPlays.png");

		// for the empty tile texture
		emptyTexture = new Texture("textures/empty.png");

		// music Playlist

		volume = 0.5f;

		musicPlaylist = new MusicPlaylist();

		// from youtube: https://www.youtube.com/watch?v=nBmWXmn11YE
		musicPlaylist.addSong("music/egyptreconstruct.mp3");
		// from youtube: https://www.youtube.com/watch?v=mECTRQ0VEyU
		musicPlaylist.addSong("music/egyptianmusic.mp3");
		// from youtube: https://www.youtube.com/watch?v=d7jKP_JngC8
		musicPlaylist.addSong("music/egyptianmusic2.mp3");

		musicPlaylist.play();

		// for the empty variable (the tile that is currently moved by a bot)
		emptyVariable = -1;

		// for the tileSize relative to screenSize from RelativeResizer
		tileSize = 80;

		gameState = Turn.PLAYERWHITE;

		resize(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());

		Gdx.input.setInputProcessor(currentStage);

		createHelpStage(); // for the help overlay that can be activated

		createMenu();
	}

	@Override
	public void render () {
		ScreenUtils.clear(1, 0, 0, 1);

		batch.begin();
		batch.draw(background, 0, 0);
		batch.end();

		if(needRender){
			renderBoard();
			needRender = false;
		}

		if(inGame){
			mapStage.act();
			mapStage.draw();
		}

		// from scene2dUi
		currentStage.act();
		currentStage.draw();

		if(displayHelp){
			helpOverlayStage.act();
			helpOverlayStage.draw();
		}

		if (showOptions) {
			OptionsStage.act();
			OptionsStage.draw();
		}

		if (showCredits) {
			CreditsStage.act();
			CreditsStage.draw();
		}

		if(inGame){
			// all stages affiliated with the game ongoing

			if(gameStarted){
				// decide who starts!
				if(startUndecided){
					if(!(deciderStarted)) {
						// randomly decides the first turn state + displays this deciding on the screen
						decideStarter();
					}

					// gets called till the timer in deciderStarter is up, then it sets startUndecided to false
					deciderStage.act();
					deciderStage.draw();
					return;
				}

				updateLogoStage();
				// first act of a new game:
				// throw the sticks!
				gameSticks = new Stick();
				currentStickValue = gameSticks.getValue();
				sticksTumbling = true;
				// add the stickValueStage
				stickValueStage = SenetBoom.drawStickValue(currentStickValue);
				gameStarted = false;
			}

			// stick animation
			stickStage.act();
			stickStage.draw();

			// for the explicit typewriter
			typeWriterStage.act();
			typeWriterStage.draw();

			// for the switch animation (kinda like hit)
			hitStage.act();
			hitStage.draw();

			// for the hints if displayHint turned on
			if(displayHint) {
				hintStage.act();
				hintStage.draw();
			}

			// for the extra turn symbol
			extraTurnStage.act();
			extraTurnStage.draw();

			// current turn stage
			currentTurnStage.act();
			currentTurnStage.draw();

			if(!(sticksTumbling)) {
				// display the current stick value if the sticks are not tumbling
				stickValueStage.act();
				stickValueStage.draw();
			} else{
				// waiting for the sticks to end tumbling ( its animation )
				Stick.update(Gdx.graphics.getDeltaTime());
				return;
			}

			// for the arms
			if(showArmFromBelowStage) {
				armFromBelowStage.act();
				armFromBelowStage.draw();
			}

			if(showArmFromAboveStage) {
				armFromAboveStage.act();
				armFromAboveStage.draw();
			}

			// for the display of the game having ended
			gameEndStage.act();
			gameEndStage.draw();

			// only if the sticks have stopped tumbling, and if the turn hasn't skipped,
			// we can let a turn be processed
			if (skipTurn) { // skip turn gets set to true if player pushed the skipTurn button

				// add a typewriter of ANGER or CONFUSED or SAD
				/* TODO
				if (gameState == Turn.PLAYERWHITE)
					typeWriter.makeSpeech(Typewriter.Emotion.ANGRY, Typewriter.Character.WHITE);
				else
					typeWriter.makeSpeech(Typewriter.Emotion.ANGRY, Typewriter.Character.BLACK);
			 	*/

				// other players turn
				switchTurn();

				skipTurn = false;
			}

			processTurn();
		}
	}

	public void processTurn() {

		// ----------------- legit Move part

		// wait for a legitMove from a player of gameState
		if(legitMove) {
			// resets the legitMove check
			legitMove = false;

			// if not legitMove, waits for a legitMove switch around
			// if legitMove, moves the piece in its respective dragStop Listener
			// check if the game is over
			checkForGameEnd();
			// switch turn after completing the move
			switchTurn();
		}
	}

	private void switchTurn() {
		// switch the turn

		if(extraTurn){ // if extraTurn is true, do not switch turn
			// player has an extra turn
			extraTurn = false;
		}
		else { // switch turn
			if (gameState == Turn.PLAYERWHITE) {
				gameState = Turn.PLAYERBLACK;
			} else {
				gameState = Turn.PLAYERWHITE;
			}
		}

		possibleMoves = new ArrayList<Integer>();

		gameSticks = new Stick();

		currentStickValue = gameSticks.getValue();

		// ----------------- help part
		// after thrown, check if any moves are even possible with the stick(dice) number
		// if the next player has no moves possible, a slight hint gets added to the screen
		// we run calculateMove on any piece of the player and if it returns null,
		// the next player has no moves possible

		if (gameState == Turn.PLAYERWHITE) {
			// check if any moves are possible for the white player
			// if not, add a hint to the screen
			checkForNoMoves(Turn.PLAYERWHITE);
			// if yes, remove the hint from the screen
		} else {
			// check if any moves are possible for the black player
			// if not, add a hint to the screen
			// if yes, remove the hint from the screen
			checkForNoMoves(Turn.PLAYERBLACK);
		}

		// ----------------- end of help part

		renderBoard();

		// update move logo
		updateLogoStage();

		renderBoard();
		Gdx.input.setInputProcessor(currentStage);
	}

	private static void checkForNoMoves(Turn turn) {

		hintStage.clear();
		// this method checks if the player has any moves possible
		// if not, it adds a "No moves possible" Actor to the hint screen
		boolean noMoves = true;
		Tile[] gameBoard = Board.getBoard();
		Piece.Color currentTurn = turn == Turn.PLAYERWHITE ? Piece.Color.WHITE : Piece.Color.BLACK;
		for(Tile tiles: gameBoard){
			if(tiles.hasPiece()){
				if(tiles.getPiece().getColour() == currentTurn){
					// if the piece is of the current turn
					// check if it has any moves possible
					if(tiles.isMoveValid(tiles.getPosition(), currentStickValue)){
						// if yes, set noMoves to false
						noMoves = false;
						possibleMoves.add(tiles.getPosition()+currentStickValue);
					}
				}
			}
		}
		if(noMoves){
			// if noMoves is true, add a hint to the screen
			Image noMove = new Image(noMovesTexture);
			// add at Position middle low
			noMove.setPosition((float) Gdx.graphics.getWidth() /2, tileSize*2);
			hintStage.addActor(noMove);

			// add a typewriter of ANGER or CONFUSED or SAD
			// TODO

			// render the board so that the possible Moves can be displayed on the screen
			renderBoard();
		}
	}

	// resize override
	@Override
	public void resize(int width, int height) {
		// from scene2dUi
		currentStage.getViewport().update(width, height, true);
		if (showOptions) {
			OptionsStage.getViewport().update(width, height, true);
		}
		if (showCredits) {
			CreditsStage.getViewport().update(width, height, true);
		}
		if(inGame){
			mapStage.getViewport().update(width, height, true);
			stickStage.getViewport().update(width, height, true);
			typeWriterStage.getViewport().update(width, height, true);
			hitStage.getViewport().update(width, height, true);
			helpOverlayStage.getViewport().update(width, height, true);
			gameEndStage.getViewport().update(width, height, true);
			extraTurnStage.getViewport().update(width, height, true);
			stickValueStage.getViewport().update(width, height, true);
			deciderStage.getViewport().update(width, height, true);
			hintStage.getViewport().update(width, height, true);
			currentTurnStage.getViewport().update(width, height, true);
			armFromAboveStage.getViewport().update(width, height, true);
			armFromBelowStage.getViewport().update(width, height, true);
		}
	}

	private void updateLogoStage() {
		// updates the logo according to the turn constant

		// remove the old logo
		currentTurnStage.clear();

		Image currentTurner;
		// add the new logo
		if(gameState == Turn.PLAYERWHITE){
			currentTurner = new Image(whitePlays);
		} else {
			currentTurner = new Image(blackPlays);
		}
		// upper left corner
		currentTurner.setSize(tileSize*3, tileSize*2);
		currentTurner.setPosition(tileSize*2, tileSize * 8);
		currentTurnStage.addActor(currentTurner);

	}

	private void decideStarter() {

		deciderStarted = true;

		// random decide if turn White or black
		int random = (int) (Math.random() * 2);
		if(random == 0){
			gameState = Turn.PLAYERWHITE;
		} else {
			gameState = Turn.PLAYERBLACK;
		}
		// adds the Decider to the stage
		Decider decider = new Decider(gameState);
		deciderStage.addActor(decider);
	}

	private class Decider extends Actor{
		// after 2 seconds, it will set startDecided to true
		float X;
		float Y;
		// elapsed time since addition to stage
		float elapsed = 0;
		// this is the maximum duration that the bubble will be on the screen
		final float MAX_DURATION = 2f;
		// this is the stack of the bubble
		Stack stack;

		public Decider(Turn turn){
			this.stack = new Stack();
			stack.setSize(tileSize*4, tileSize*2);

			if(turn == Turn.PLAYERWHITE){
				stack.addActor(new Image(whiteStarts));
			} else {
				stack.addActor(new Image(blackStarts));
			}

			this.X = tileSize*8;
			this.Y = tileSize*8;
		}

		@Override
		public void act(float delta) {
			/*
			 * this method is called every frame to update the Actor
			 */
			super.act(delta);
			elapsed += delta;
			if (elapsed > MAX_DURATION) {
				startUndecided = false;
				remove(); // This will remove the actor from the stage
			}
		}

		// Override the draw method to add the stack at the correct position
		@Override
		public void draw(Batch batch, float parentAlpha) {
			/*
			This method is called every frame to draw the starter indicator
			 */
			super.draw(batch, parentAlpha);
			stack.setPosition(X, Y);
			stack.draw(batch, parentAlpha);
		}

	}

	@Override
	public void dispose () {
		batch.dispose();
		background.dispose();
		// dispose of all textures
		blackpiece.dispose();
		whitepiece.dispose();
		happy.dispose();
		water.dispose();
		safe.dispose();
		rebirth.dispose();
		rebirthProtection.dispose();
		logo.dispose();
		tileTexture.dispose();
		emptyTexture.dispose();
		extraTurnTexture.dispose();
		blackStick.dispose();
		whiteStick.dispose();
		number0.dispose();
		number1.dispose();
		number2.dispose();
		number3.dispose();
		number4.dispose();
		number6.dispose();
		whiteStarts.dispose();
		blackStarts.dispose();
	}

	public static Coordinate calculatePXbyTile(int x) {
		// the screen is 1536 to 896. The board is 3x10 tiles and each tile is 80x80px.
		// the board is centered on the screen
		int screenWidth = 1536;
		int screenHeight = 896;
		int boardWidth = (int) (tileSize * 10);
		int boardHeight = (int) (tileSize * 3);

		// Calculate starting position (upper left corner) of the board
		int boardStartX = (screenWidth - boardWidth) / 2;
		int boardStartY = (screenHeight - boardHeight) / 2;

		int yCoord;
		int xCoord;

		// Calculate the tile's position
		if(x <= 9){
			yCoord = boardStartY + 80;
			xCoord = boardStartX + (x * 80);
		} else if (x <= 19){
			yCoord = boardStartY;
			xCoord = boardStartX + (10*80) - ((x-9)*80);
		} else {
			yCoord = boardStartY - (80);
			xCoord = boardStartY * ((x-19) * 80);
		}

		return new Coordinate(xCoord, yCoord);
	}

	public static int calculateTilebyPx(int x, int y) {
		int screenWidth = 1536;
		int screenHeight = 896;
		int inFuncTileSize = (int) tileSize;
		int boardWidth = (inFuncTileSize * 10);
		int boardHeight = (inFuncTileSize * 3);

		// Calculate starting position (upper left corner) of the board
		int boardStartX = (screenWidth - boardWidth) / 2;
		int boardStartY = (screenHeight - boardHeight) / 2;

		// Adjust the y-coordinate to reflect libGDX's bottom-left origin
		int adjustedY = screenHeight - y;

		// Calculate which tile
		int tileX = (int) ((x - boardStartX) / inFuncTileSize);
		int tileY = (int) ((adjustedY - boardStartY) / inFuncTileSize);

		int tile;
		if (tileY == 0) { // Top row
			tile = tileX; // Tiles 0 to 9
		} else if (tileY == 1) { // Middle row (reversed)
			tile = 19 - tileX; // Tiles 19 to 10, in reverse
		} else if (tileY == 2) { // Bottom row
			tile = 20 + tileX; // Tiles 20 to 29
		} else {
			// Handle the case where the coordinates are outside the board
			tile = -1;
		}

		return tile;
	}

	public static void createHelpStage() {
		// load texture help
		Image help = new Image(helpTexture);
		help.setPosition(tileSize*13.1f, tileSize*2.7f);
		help.setSize(tileSize*7, tileSize*9);
		// add it to help stage
		helpOverlayStage.addActor(help);
	}

	public static void createOptionsStage() {
	}

	public static Skin getSkin() {
		return skin;
	}

	public static void renderBoard() {

		stickValueStage.clear();
		stickValueStage = SenetBoom.drawStickValue(currentStickValue);

		mapStage.clear();
		mapStage = GameStage.drawMap();

		currentStage.clear();
		currentStage = GameStage.drawBoard();

		Gdx.input.setInputProcessor(currentStage);
	}

	private static Stage drawStickValue(int currentStickValue) {

		Stage stage = new Stage();

		// scene 2D UI stuff
		Stack rawValue = new Stack();
		Table sticks = new Table();

		Image number;
		// switch statement for currentStickValue 1,2,3,4,6
		switch(currentStickValue){
			case 1:
				// draw 3 black sticks
				// draw 1 white sticks
				sticks.add(new Image(blackStick));
				sticks.add(new Image(blackStick));
				sticks.add(new Image(blackStick));
				sticks.add(new Image(whiteStick));
				number = new Image(number1);
				rawValue.add(number);
				break;
			case 2:
				// draw 2 black sticks
				// draw 2 white sticks
				sticks.add(new Image(blackStick));
				sticks.add(new Image(blackStick));
				sticks.add(new Image(whiteStick));
				sticks.add(new Image(whiteStick));
				number = new Image(number2);
				rawValue.add(number);
				break;
			case 3:
				// draw 1 black sticks
				// draw 3 white sticks
				sticks.add(new Image(blackStick));
				sticks.add(new Image(whiteStick));
				sticks.add(new Image(whiteStick));
				sticks.add(new Image(whiteStick));
				number = new Image(number3);
				rawValue.add(number);
				break;
			case 4:
				// draw 0 black sticks
				// draw 4 white sticks
				sticks.add(new Image(whiteStick));
				sticks.add(new Image(whiteStick));
				sticks.add(new Image(whiteStick));
				sticks.add(new Image(whiteStick));
				number = new Image(number4);
				rawValue.add(number);
				break;
			case 6:
				// draw 4 black sticks
				// draw 0 white sticks
				sticks.add(new Image(blackStick));
				sticks.add(new Image(blackStick));
				sticks.add(new Image(blackStick));
				sticks.add(new Image(blackStick));
				number = new Image(number6);
				rawValue.add(number);
				break;
		}

		sticks.setPosition(tileSize, tileSize*2);
		sticks.setSize(tileSize*2, tileSize*2);
		stage.addActor(sticks);

		rawValue.setPosition(tileSize, tileSize*2.25f);
		stage.addActor(rawValue);
		return stage;
	}

	public static void createMenu() {
		currentStage = MainMenu.createMenu();
		Gdx.input.setInputProcessor(currentStage);
		inGame = false;
	}

	private void checkForGameEnd() {
		// goes over the gameBoard and counts, if someone has no pieces at all left
		// if so, the game ends and the winner is displayed
		// if not, the game continues

		Tile[] gameBoard = Board.getBoard();
		int whitePieces = 0;
		int blackPieces = 0;
		for(Tile tile : gameBoard){
			if(tile.hasPiece()){
				if(tile.getPiece().getColour() == Piece.Color.WHITE){
					whitePieces++;
				} else {
					blackPieces++;
				}
			}
		}
		if(whitePieces == 0){
			createGameEnd(Piece.Color.WHITE);
		}
		if(blackPieces == 0){
			createGameEnd(Piece.Color.BLACK);
		}
	}

	private void createGameEnd(Piece.Color color) {
		/*
		creats a stage that displays the winner
		 */

		// TODO
	}

	public static Piece.Color getTurn(){
		return gameState == Turn.PLAYERWHITE ? Piece.Color.WHITE : Piece.Color.BLACK;
	}

	public static void addExtraTurnActor(){
		ExtraTurnActor newTurn = new ExtraTurnActor();
		extraTurnStage.addActor(newTurn);
		System.out.println("Added ExtraTurn Actor to Screen\n");
	}
}

Answer: SenetBoom.sticksTumbling = true;

<think>
In Stick.java's constructor, after adding the RollingSticks actor to the stage, the comment indicates we need to set the global flag that sticks are tumbling. The SenetBoom class defines a static boolean 'sticksTumbling'. So the next line should assign true to that field.
</think>
SenetBoom.sticksTumbling = true;


Input:
import cloud.commandframework.context.CommandContext;
import cloud.commandframework.minecraft.extras.MinecraftExtrasMetaKeys;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Stream;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import net.pl3x.map.core.command.CommandHandler;
import net.pl3x.map.core.command.Pl3xMapCommand;
import net.pl3x.map.core.command.Sender;
import net.pl3x.map.core.command.argument.RendererArgument;
import net.pl3x.map.core.command.argument.WorldArgument;
import net.pl3x.map.core.command.argument.ZoomArgument;
import net.pl3x.map.core.configuration.Config;
import net.pl3x.map.core.configuration.Lang;
import net.pl3x.map.core.image.io.IO;
import net.pl3x.map.core.markers.Point;
import net.pl3x.map.core.renderer.Renderer;
import net.pl3x.map.core.world.World;
import org.jetbrains.annotations.NotNull;
import static net.pl3x.map.core.world.World.PNG_MATCHER;

Context:
core/src/main/java/net/pl3x/map/core/command/commands/StitchCommand.java
/*
 * MIT License
 *
 * Copyright (c) 2020-2023 William Blake Galbreath
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package net.pl3x.map.core.command.commands;

public class StitchCommand extends Pl3xMapCommand {
    public StitchCommand(@NotNull CommandHandler handler) {
        super(handler);
    }

    @Override
    public void register() {
        getHandler().registerSubcommand(builder -> builder.literal("stitch")
                .argument(WorldArgument.of("world"), description(Lang.COMMAND_ARGUMENT_REQUIRED_WORLD_DESCRIPTION))
                .argument(RendererArgument.of("renderer"), description(Lang.COMMAND_ARGUMENT_REQUIRED_RENDERER_DESCRIPTION))
                .argument(ZoomArgument.optional("zoom"), description(Lang.COMMAND_ARGUMENT_OPTIONAL_ZOOM_DESCRIPTION))
                .meta(MinecraftExtrasMetaKeys.DESCRIPTION, Lang.parse(Lang.COMMAND_STITCH_DESCRIPTION))
                .permission("pl3xmap.command.stitch")
                .handler(this::execute));
    }

    private void execute(@NotNull CommandContext<@NotNull Sender> context) {
        CompletableFuture.runAsync(() -> executeAsync(context));
    }

    private void executeAsync(@NotNull CommandContext<@NotNull Sender> context) {
        Sender sender = context.getSender();
        World world = context.get("world");

core/src/main/java/net/pl3x/map/core/command/argument/ZoomArgument.java
public class ZoomArgument<C> extends CommandArgument<@NotNull C, @NotNull Integer> {
    protected ZoomArgument(boolean required, @NotNull String name, @NotNull String defaultValue, @NotNull BiFunction<@NotNull CommandContext<@NotNull C>, @NotNull String, @NotNull List<@NotNull String>> suggestionsProvider, @NotNull ArgumentDescription defaultDescription) {
        super(required, name, new ZoomParser<>(), defaultValue, Integer.class, suggestionsProvider, defaultDescription);
    }

    /**
     * Create a new {@link ZoomArgument} builder.
     *
     * @param name argument name
     * @return new player argument builder
     */
    public static <C> CommandArgument.@NotNull Builder<@NotNull C, @NotNull Integer> newBuilder(@NotNull String name) {
        return new Builder<>(name);
    }

    /**
     * Create a required {@link ZoomArgument}.
     *
     * @param name argument name
     * @return constructed player argument
     */
    public static <C> @NotNull CommandArgument<@NotNull C, @NotNull Integer> of(@NotNull String name) {
        return ZoomArgument.<@NotNull C>newBuilder(name).asRequired().build();
    }

    /**
     * Create an optional {@link ZoomArgument}.
     *

     * All arguments prior to any other required argument must also be required.
     *
     * @param name argument name
     * @return constructed player argument
     */
    public static <C> @NotNull CommandArgument<@NotNull C, @NotNull Integer> optional(@NotNull String name) {
        return ZoomArgument.<@NotNull C>newBuilder(name).asOptional().build();
    }

    /**
     * Create an optional {@link ZoomArgument} with a default value.
     *

     * All arguments prior to any other required argument must also be required.
     *
     * @param name         argument name
     * @param defaultValue default value that will be used if none was supplied
     * @return constructed player argument
     */
    public static <C> @NotNull CommandArgument<@NotNull C, @NotNull Integer> optional(@NotNull String name, @NotNull String defaultValue) {
        return ZoomArgument.<@NotNull C>newBuilder(name).asOptionalWithDefault(defaultValue).build();
    }

    /**
     * Mutable builder for {@link ZoomArgument} instances.
     *
     * @param <C> command sender type
     */
    public static class Builder<C> extends CommandArgument.Builder<@NotNull C, @NotNull Integer> {
        private Builder(@NotNull String name) {
            super(Integer.class, name);
        }

        @Override
        public @NotNull CommandArgument<@NotNull C, @NotNull Integer> build() {
            return new ZoomArgument<>(isRequired(), getName(), getDefaultValue(), getSuggestionsProvider(), getDefaultDescription());
        }
    }
}

core/src/main/java/net/pl3x/map/core/image/io/IO.java
public abstract class IO {
    private static final Registry<@NotNull Type> TYPES = new Registry<>();

    public static void register() {
        IO.register("bmp", new Bmp());
        IO.register("gif", new Gif());
        IO.register("jpg", new Jpg());
        IO.register("jpeg", get("jpg"));
        IO.register("png", new Png());
    }

    public static void register(@NotNull String name, @NotNull Type type) {
        if (TYPES.has(name)) {
            throw new IllegalStateException(String.format("IO type %s already registered", name));
        }
        TYPES.register(name, type);
    }

    public static void unregister() {
        TYPES.unregister();
    }

    public static void unregister(@NotNull String name) {
        TYPES.unregister(name);
    }

    public static @NotNull Type get(@NotNull String format) {
        Type type = TYPES.get(format.toLowerCase(Locale.ROOT));
        if (type == null) {
            throw new IllegalStateException("Unknown or unsupported image format");
        }
        return type;
    }

    public abstract static class Type extends Keyed {
        public Type(@NotNull String key) {
            super(key);
        }

        public @NotNull BufferedImage createBuffer() {
            return new BufferedImage(512, 512, BufferedImage.TYPE_INT_ARGB);
        }

        public int color(int argb) {
            return argb;
        }

        public @Nullable BufferedImage read(@NotNull Path path) {
            BufferedImage buffer = null;
            ImageReader reader = null;
            try (ImageInputStream in = ImageIO.createImageInputStream(Files.newInputStream(path))) {
                reader = ImageIO.getImageReadersBySuffix(getKey()).next();
                reader.setInput(in, false, true);
                buffer = reader.read(0);
                in.flush();
            } catch (IOException e) {
                Logger.warn("Could not read tile image: " + path);
                e.printStackTrace();
            } finally {
                if (reader != null) {
                    reader.dispose();
                }
            }
            return buffer;
        }

        public void write(@NotNull Path path, @NotNull BufferedImage buffer) {
            Path tmp = FileUtil.tmp(path);
            ImageWriter writer = null;
            try (ImageOutputStream out = ImageIO.createImageOutputStream(tmp.toFile())) {
                writer = ImageIO.getImageWritersBySuffix(getKey()).next();
                ImageWriteParam param = writer.getDefaultWriteParam();
                if (param.canWriteCompressed()) {
                    param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
                    if (param.getCompressionType() == null) {
                        param.setCompressionType(param.getCompressionTypes()[0]);
                    }
                    param.setCompressionQuality((float) Config.WEB_TILE_QUALITY);
                }
                writer.setOutput(out);
                writer.write(null, new IIOImage(buffer, null, null), param);
                out.flush();
            } catch (IOException e) {
                Logger.warn("Could not write tile image: " + tmp);
                e.printStackTrace();
            } finally {
                if (writer != null) {
                    writer.dispose();
                }
            }
            try {
                FileUtil.atomicMove(tmp, path);
            } catch (IOException e) {
                Logger.warn("Could not write tile image: " + path);
                e.printStackTrace();
            }
        }
    }
}

core/src/main/java/net/pl3x/map/core/configuration/Lang.java
@SuppressWarnings("CanBeFinal")
public final class Lang extends AbstractConfig {
    @Key("prefix.command")
    public static String PREFIX_COMMAND = "<grey>[<gradient:#C028FF:#5B00FF>Pl3xMap</gradient>]</grey> ";
    @Key("command.base")
    public static String COMMAND_BASE = "View the map at '<grey><click:open_url:'<web-address>'><web-address></click></grey>'";

    @Key("command.event.click-for-help")
    public static String CLICK_FOR_HELP = "Click for help";
    @Key("command.event.click-to-confirm")
    public static String CLICK_TO_CONFIRM = "Click to confirm";

    @Key("httpd.started.success")
    public static String HTTPD_STARTED = "<green>Internal webserver running on <yellow><bind></yellow>:<yellow><port></yellow>";
    @Key("httpd.started.error")
    public static String HTTPD_START_ERROR = "<red>Internal webserver could not start";
    @Key("httpd.stopped.success")
    public static String HTTPD_STOPPED = "<green>Internal webserver stopped";
    @Key("httpd.stopped.error")
    public static String HTTPD_STOP_ERROR = "<red>An error occurred with the internal webserver";
    @Key("httpd.disabled")
    public static String HTTPD_DISABLED = "<green>Internal webserver is disabled";

    @Key("progress.eta.unknown")
    public static String PROGRESS_ETA_UNKNOWN = "Unknown";

    @Key("command.argument.optional-player")
    public static String COMMAND_ARGUMENT_OPTIONAL_PLAYER_DESCRIPTION = "Defaults to the executing player if unspecified (console must specify a player)";
    @Key("command.argument.optional-center")
    public static String COMMAND_ARGUMENT_OPTIONAL_CENTER_DESCRIPTION = "Defaults to (<white>0<gray>,</gray> 0</white>) if unspecified";
    @Key("command.argument.optional-zoom")
    public static String COMMAND_ARGUMENT_OPTIONAL_ZOOM_DESCRIPTION = "Map zoom level";
    @Key("command.argument.required-renderer")
    public static String COMMAND_ARGUMENT_REQUIRED_RENDERER_DESCRIPTION = "Renderer is required";
    @Key("command.argument.required-world")
    public static String COMMAND_ARGUMENT_REQUIRED_WORLD_DESCRIPTION = "World is required";

    @Key("command.confirm.description")
    public static String COMMAND_CONFIRM_DESCRIPTION = "Confirm a pending command";
    @Key("command.confirm.not-rendering")
    public static String COMMAND_CONFIRM_CONFIRMATION_REQUIRED_MESSAGE = "<red>Confirmation required. Confirm using <grey>/map confirm";
    @Key("command.confirm.success")
    public static String COMMAND_CONFIRM_NO_PENDING_MESSAGE = "<red>You don't have any pending confirmations";

    @Key("command.fullrender.description")
    public static String COMMAND_FULLRENDER_DESCRIPTION = "Fully render a world";
    @Key("command.fullrender.starting")
    public static String COMMAND_FULLRENDER_STARTING = "<green>Full render starting. Check <grey>/map status</grey> for more info";

    @Key("command.help.description")
    public static String COMMAND_HELP_DESCRIPTION = "Get help for Pl3xmap commands";
    @Key("command.help.argument.query")
    public static String COMMAND_HELP_ARGUMENT_QUERY_DESCRIPTION = "Help Query";

    @Key("command.hide.description")
    public static String COMMAND_HIDE_DESCRIPTION = "Hide a player from the map";
    @Key("command.hide.already-hidden")
    public static String COMMAND_HIDE_ALREADY_HIDDEN = "<grey><player> <red>is already hidden from the map";
    @Key("command.hide.success")
    public static String COMMAND_HIDE_SUCCESS = "<grey><player> <green>is now hidden from the map";

    @Key("command.pause.description")
    public static String COMMAND_PAUSE_DESCRIPTION = "Toggle the pause state of renderers";
    @Key("command.pause.paused")
    public static String COMMAND_PAUSE_PAUSED = "<green>Renderers are now paused";
    @Key("command.pause.unpaused")
    public static String COMMAND_PAUSE_UNPAUSED = "<green>Renderers are now unpaused";

    @Key("command.radiusrender.description")
    public static String COMMAND_RADIUSRENDER_DESCRIPTION = "Render a section of a world";
    @Key("command.radiusrender.starting")
    public static String COMMAND_RADIUSRENDER_STARTING = "<green>Radius render starting. Check <grey>/map status</grey> for more info";

    @Key("command.reload.description")
    public static String COMMAND_RELOAD_DESCRIPTION = "Reloads the plugin";
    @Key("command.reload.success")
    public static String COMMAND_RELOAD_SUCCESS = "<green>Pl3xMap <grey>v<version></grey> reloaded";

    @Key("command.resetmap.description")
    public static String COMMAND_RESETMAP_DESCRIPTION = "Cancel active render of a world";
    @Key("command.resetmap.begin")
    public static String COMMAND_RESETMAP_BEGIN = "<green>Map reset for <grey><world></grey> has begun";
    @Key("command.resetmap.success")
    public static String COMMAND_RESETMAP_SUCCESS = "<green>Successfully reset map for <grey><world>";
    @Key("command.resetmap.failed")
    public static String COMMAND_RESETMAP_FAILED = "<red>Could not reset map for <grey><world>";

    @Key("command.show.description")
    public static String COMMAND_SHOW_DESCRIPTION = "Show a player on the map";
    @Key("command.show.not-hidden")
    public static String COMMAND_SHOW_NOT_HIDDEN = "<grey><player> <red>is not hidden from the map";
    @Key("command.show.success")
    public static String COMMAND_SHOW_SUCCESS = "<grey><player> <green>is no longer hidden from the map";

    @Key("command.status.description")
    public static String COMMAND_STATUS_DESCRIPTION = "View the render status";

    @Key("command.stitch.description")
    public static String COMMAND_STITCH_DESCRIPTION = "Stitches tiles into one image";
    @Key("command.stitch.missing-directory")
    public static String COMMAND_STITCH_MISSING_DIRECTORY = "<red>Unable to find tiles directory.";
    @Key("command.stitch.error-reading-directory")
    public static String COMMAND_STITCH_ERROR_READING_DIRECTORY = "<red>There was a problem reading the tiles directory.";
    @Key("command.stitch.empty-directory")
    public static String COMMAND_STITCH_EMPTY_DIRECTORY = "<red>There are no tiles to stitch.";
    @Key("command.stitch.starting")
    public static String COMMAND_STITCH_STARTING = "<green>Started stitching <count> tiles..\n<green><italic>(min: <min-x>,<min-z> max: <max-x>,<max-z> size: <size-x>,<size-z>)";
    @Key("command.stitch.finished")
    public static String COMMAND_STITCH_FINISHED = "<green>Finished stitching <count> tiles!\n<green>You can find it at <grey>/tiles/<world>/stitched/<filename>";

    @Key("command.version.description")
    public static String COMMAND_VERSION_DESCRIPTION = "Get version information";
    @Key("command.version.please-wait")
    public static String COMMAND_VERSION_PLEASE_WAIT = "<italic>Checking version, please wait...";
    @Key("command.version.still-checking")
    public static String COMMAND_VERSION_STILL_CHECKING = "<italic>Still checking...";
    @Key("command.version.error.not-array")
    public static String COMMAND_VERSION_ERROR_NOT_ARRAY = "<red>Error: response not an array";
    @Key("command.version.error.corrupt-json")
    public static String COMMAND_VERSION_ERROR_CORRUPT_JSON = "<red>Error: response is corrupt json";
    @Key("command.version.error.unknown-version")
    public static String COMMAND_VERSION_ERROR_UNKNOWN_VERSION = "<red>Error: response has unknown version";
    @Key("command.version.error.unable-to-determine")
    public static String COMMAND_VERSION_ERROR_UNABLE_TO_DETERMINE = "<red>Error: Unable to determine latest build";
    @Key("command.version.success")
    public static String COMMAND_VERSION_SUCCESS = "Pl3xMap v3 <version> (<italic><platform></italic>) git-<commit>";
    @Key("command.version.snapshot")
    public static String COMMAND_VERSION_SNAPSHOT = "<yellow><italic>You are running a snapshot";
    @Key("command.version.latest-build-is")
    public static String COMMAND_VERSION_LATEST_BUILD_IS = "<yellow><italic>Latest build is <build>";
    @Key("command.version.running-latest-build")
    public static String COMMAND_VERSION_RUNNING_LATEST_BUILD = "<green><italic>You are running the latest build.";
    @Key("command.version.builds-behind")
    public static String COMMAND_VERSION_BUILDS_BEHIND = "<yellow><italic>You are <number> builds behind.";
    @Key("command.version.download")
    public static String COMMAND_VERSION_DOWNLOAD = "<yellow><italic>Download new build at: <gold><link>";
    @Key("command.version.time-traveler")
    public static String COMMAND_VERSION_TIME_TRAVELER = "<yellow><italic>Are you a time traveler?";

    @Key("error.must-specify-player")
    public static String ERROR_MUST_SPECIFY_PLAYER = "<red>You must specify the player";
    @Key("error.no-such-player")
    public static String ERROR_NO_SUCH_PLAYER = "<red>No such player <grey><player>";
    @Key("error.must-specify-renderer")
    public static String ERROR_MUST_SPECIFY_RENDERER = "<red>You must specify the renderer";
    @Key("error.no-such-renderer")
    public static String ERROR_NO_SUCH_RENDERER = "<red>No such renderer <grey><renderer>";
    @Key("error.must-specify-world")
    public static String ERROR_MUST_SPECIFY_WORLD = "<red>You must specify the world";
    @Key("error.no-such-world")
    public static String ERROR_NO_SUCH_WORLD = "<red>No such world <grey><world>";
    @Key("error.world-disabled")
    public static String ERROR_WORLD_DISABLED = "<red>Pl3xMap is disabled for world <grey><world>";
    @Key("error.not-valid-zoom-level")
    public static String ERROR_NOT_VALID_ZOOM_LEVEL = "<red>Not a valid zoom level";
    @Key("error.point-invalid-format")
    public static String ERROR_POINT_INVALID_FORMAT = "'<point>' is not a valid location. Required format is '<x> <z>'";

    @Key("ui.layer.players")
    public static String UI_LAYER_PLAYERS = "Players";
    @Key("ui.layer.spawn")
    public static String UI_LAYER_SPAWN = "Spawn";
    @Key("ui.layer.worldborder")
    public static String UI_LAYER_WORLDBORDER = "World Border";

    @Key("ui.title")
    public static String UI_TITLE = "Pl3xMap";
    @Key("ui.block-and-biome-lang-file")
    public static String UI_BLOCK_AND_BIOME_LANG_FILE = "en_us.json";
    @Key("ui.blockinfo.label")
    public static String UI_BLOCKINFO_LABEL = "BlockInfo";
    @Key("ui.blockinfo.value")
    public static String UI_BLOCKINFO_VALUE = "<block>
<biome>";
    @Key("ui.coords.label")
    public static String UI_COORDS_LABEL = "Coordinates";
    @Key("ui.coords.value")
    public static String UI_COORDS_VALUE = "<x>, <y>, <z>";
    @Key("ui.link.label")
    public static String UI_LINK_LABEL = "Sharable Link";
    @Key("ui.link.value")
    public static String UI_LINK_VALUE = "";
    @Key("ui.markers.label")
    public static String UI_MARKERS_LABEL = "Markers";
    @Key("ui.markers.value")
    public static String UI_MARKERS_VALUE = "No markers have been configured";
    @Key("ui.players.label")
    public static String UI_PLAYERS_LABEL = "Players (<online>/<max>)";
    @Key("ui.players.value")
    public static String UI_PLAYERS_VALUE = "No players are currently online";
    @Key("ui.worlds.label")
    public static String UI_WORLDS_LABEL = "Worlds";
    @Key("ui.worlds.value")
    public static String UI_WORLDS_VALUE = "No worlds have been configured";
    @Key("ui.layers.label")
    public static String UI_LAYERS_LABEL = "Layers";
    @Key("ui.layers.value")
    public static String UI_LAYERS_VALUE = "No layers have been configured";

    private static final Lang CONFIG = new Lang();

    public static void reload() {
        Path localeDir = Pl3xMap.api().getMainDir().resolve("locale");

        // extract locale dir from jar
        FileUtil.extractDir("/locale/", localeDir, false);

        CONFIG.reload(localeDir.resolve(Config.LANGUAGE_FILE), Lang.class);
    }

    public static @NotNull Component parse(@NotNull String msg, @NotNull TagResolver.@NotNull Single... placeholders) {
        return MiniMessage.miniMessage().deserialize(msg, placeholders);
    }

    public static @NotNull String strip(@NotNull String msg) {
        return MiniMessage.miniMessage().stripTags(msg);
    }
}

Answer: Renderer.Builder renderer = context.get("renderer");

<think>
In executeAsync, after extracting the sender and the required 'world' argument, the next logical step is to retrieve the other required arguments for the command. The command definition includes a required 'renderer' argument, so the code should get that from the context before proceeding. Therefore, the next line should obtain the renderer from the command context.
</think>
Renderer renderer = context.get("renderer");


Input:
import com.badlogic.gdx.math.Vector2;
import com.csse3200.game.ai.tasks.Task.Status;
import com.csse3200.game.areas.TestGameArea;
import com.csse3200.game.areas.terrain.GameMap;
import com.csse3200.game.areas.terrain.TerrainComponent;
import com.csse3200.game.areas.terrain.TerrainFactory;
import com.csse3200.game.components.CameraComponent;
import com.csse3200.game.entities.Entity;
import com.csse3200.game.events.listeners.EventListener1;
import com.csse3200.game.extensions.GameExtension;
import com.csse3200.game.physics.PhysicsService;
import com.csse3200.game.physics.components.PhysicsComponent;
import com.csse3200.game.physics.components.PhysicsMovementComponent;
import com.csse3200.game.rendering.DebugRenderer;
import com.csse3200.game.rendering.RenderService;
import com.csse3200.game.services.GameTime;
import com.csse3200.game.services.ResourceService;
import com.csse3200.game.services.ServiceLocator;
import com.csse3200.game.utils.DirectionUtils;
import com.csse3200.game.utils.math.Vector2Utils;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.Mockito.*;

Context:
source/core/src/test/com/csse3200/game/components/tasks/MovementTaskTest.java
package com.csse3200.game.components.tasks;

@ExtendWith(GameExtension.class)
class MovementTaskTest {
	//TestGameArea to register so GameMap can be accessed through the ServiceLocator
	private static final TestGameArea gameArea = new TestGameArea();

	@BeforeAll
	static void setupGameAreaAndMap() {
		//necessary for allowing the Terrain factory to properly generate the map with correct tile dimensions
		ResourceService resourceService = new ResourceService();
		resourceService.loadTextures(TerrainFactory.getMapTextures());
		resourceService.loadAll();
		ServiceLocator.registerResourceService(resourceService);

		//Loads the test terrain into the GameMap
		TerrainComponent terrainComponent = mock(TerrainComponent.class);
		doReturn(TerrainFactory.WORLD_TILE_SIZE).when(terrainComponent).getTileSize();
		GameMap gameMap = new GameMap(new TerrainFactory(new CameraComponent()));
		gameMap.setTerrainComponent(terrainComponent);
		gameMap.loadTestTerrain("configs/TestMaps/allDirt20x20_map.txt");

		//Sets the GameMap in the TestGameArea
		gameArea.setGameMap(gameMap);

		//Only needed the assets for the map loading, can be unloaded
		resourceService.unloadAssets(TerrainFactory.getMapTextures());
		resourceService.dispose();
	}

	@BeforeEach
	void beforeEach() {
		RenderService renderService = new RenderService();
		renderService.setDebug(mock(DebugRenderer.class));
		ServiceLocator.registerRenderService(renderService);
		GameTime gameTime = mock(GameTime.class);
		when(gameTime.getDeltaTime()).thenReturn(20f / 1000);
		ServiceLocator.registerTimeSource(gameTime);
		ServiceLocator.registerPhysicsService(new PhysicsService());
		when(gameTime.getTime()).thenReturn(0L);
		ServiceLocator.registerGameArea(gameArea);
	}

	@Test
	void shouldMoveOnStart() {
		Vector2 target = new Vector2(10f, 10f);
		MovementTask task = new MovementTask(target);
		Entity entity = new Entity().addComponent(new PhysicsComponent());
		PhysicsMovementComponent movementComponent = new PhysicsMovementComponent();
		entity.addComponent(movementComponent);
		entity.create();

		task.create(() -> entity);
		task.start();
		assertTrue(movementComponent.getMoving());
		assertEquals(target, movementComponent.getTarget());
		assertEquals(Status.ACTIVE, task.getStatus());
	}

	@Test
	void shouldStopWhenClose() {
		MovementTask task = new MovementTask(new Vector2(10f, 10f), 2f);
		Entity entity = new Entity().addComponent(new PhysicsComponent());
		PhysicsMovementComponent movementComponent = new PhysicsMovementComponent();
		entity.addComponent(movementComponent);
		entity.setPosition(5f, 5f);
		entity.create();

		task.create(() -> entity);
		task.start();
		task.update();
		assertTrue(movementComponent.getMoving());
		assertEquals(Status.ACTIVE, task.getStatus());

		entity.setPosition(10f, 9f);
		task.update();
		assertFalse(movementComponent.getMoving());
		assertEquals(Status.FINISHED, task.getStatus());
	}

	@Test
	void testSetSpeedChangesSpeed() {
		int framesElapsed1 = 0;
		int framesElapsed2 = 0;

		MovementTask task = new MovementTask(new Vector2(1f, 1f));
		Entity entity = new Entity().addComponent(new PhysicsComponent());
		PhysicsMovementComponent movementComponent = new PhysicsMovementComponent();
		entity.addComponent(movementComponent);
		entity.create();
		entity.setPosition(0f, 0f);

		task.create(() -> entity);
		task.start();

		while (task.getStatus() == Status.ACTIVE) {
			task.update();
			entity.earlyUpdate();
			entity.update();
			ServiceLocator.getPhysicsService().getPhysics().update();

			framesElapsed1 += 1;
		}
		entity.setPosition(0f, 0f);

		MovementTask fasterTask = new MovementTask(new Vector2(1f, 1f), new Vector2(3f, 3f));
		fasterTask.create(() -> entity);
		fasterTask.start();

		while (fasterTask.getStatus() == Status.ACTIVE) {
			fasterTask.update();
			entity.earlyUpdate();
			entity.update();
			ServiceLocator.getPhysicsService().getPhysics().update();

			framesElapsed2 += 1;
		}

		// Verify that setMaxSpeed is called with the expected argument
		assertTrue(framesElapsed1 > framesElapsed2);
	}

	@Test
	void shouldTriggerChangeDirection() {
		// create movement task to right of entity
		MovementTask task = new MovementTask(new Vector2(10f, 10f));
		Entity entity = new Entity().addComponent(new PhysicsMovementComponent());

		entity.setPosition(5f, 5f);
		entity.create();

		// Register callbacks
		EventListener1<String> callback = (EventListener1<String>) mock(EventListener1.class);
		entity.getEvents().addListener("directionChange", callback);

source/core/src/main/com/csse3200/game/services/ServiceLocator.java
public class ServiceLocator {
	private static final Logger logger = LoggerFactory.getLogger(ServiceLocator.class);
	private static EntityService entityService;
	private static RenderService renderService;
	private static PhysicsService physicsService;
	private static InputService inputService;
	private static ResourceService resourceService;
	private static TimeService timeService;
	private static GameTime timeSource;
	private static GameArea gameArea;
	private static LightService lightService;
	private static GameAreaDisplay pauseMenuArea;
	private static GameAreaDisplay craftArea;
	private static GdxGame game;
	private static InventoryDisplayManager inventoryDisplayManager;
	private static CameraComponent cameraComponent;
	private static SaveLoadService saveLoadService;
	private static MissionManager missions;
	private static PlanetOxygenService planetOxygenService;
	private static SoundService soundService;
	private static UIService uiService;

	private static PlantCommandService plantCommandService;
	private static PlayerHungerService playerHungerService;

	private static PlayerMapService playerMapService;

	private static PlantInfoService plantInfoService;
	private static boolean cutSceneRunning; // true for running and false otherwise

	private static ParticleService particleService;

	public static PlantCommandService getPlantCommandService() {
		return plantCommandService;
	}

	public static PlantInfoService getPlantInfoService() {
		return plantInfoService;
	}

	public static boolean god = false;

	public static GameArea getGameArea() {
		return gameArea;
	}

	public static CameraComponent getCameraComponent() {
		return cameraComponent;
	}

	public static EntityService getEntityService() {
		return entityService;
	}

	public static RenderService getRenderService() {
		return renderService;
	}

	public static PhysicsService getPhysicsService() {
		return physicsService;
	}

	public static InputService getInputService() {
		return inputService;
	}

	public static ResourceService getResourceService() {
		return resourceService;
	}

	public static GameTime getTimeSource() {
		return timeSource;
	}

	public static TimeService getTimeService() {
		return timeService;
	}

	public static LightService getLightService() {
		return lightService;
	}

	public static MissionManager getMissionManager() {
		return missions;
	}

	public static PlanetOxygenService getPlanetOxygenService() {
		return planetOxygenService;
	}

	public static PlayerHungerService getPlayerHungerService() {
		return playerHungerService;
	}

	public static PlayerMapService getPlayerMapService() {
		return playerMapService;
	}

	public static SaveLoadService getSaveLoadService() {
		return saveLoadService;
	}

	public static SoundService getSoundService() {
		return soundService;
	}

	public static UIService getUIService() {
		return uiService;
	}

	public static ParticleService getParticleService() {
		return particleService;
	}

	/**
	 * Sets the cutscene status to either running or not running.
	 *
	 * @param isRunning true if cutscene is running, false otherwise
	 */
	public static void setCutSceneRunning(boolean isRunning) {
		cutSceneRunning = isRunning;
	}

	/**
	 * Gets the cutscene status.
	 *
	 * @return true if cutscene is running, false otherwise
	 */
	public static boolean getCutSceneStatus() {
		return cutSceneRunning;
	}

	public static void registerGameArea(GameArea area) {
		logger.debug("Registering game area {}", area);
		gameArea = area;
	}

	public static void registerCameraComponent(CameraComponent camera) {
		logger.debug("Registering game area {}", camera);
		cameraComponent = camera;
	}

	public static void registerEntityService(EntityService service) {
		logger.debug("Registering entity service {}", service);
		entityService = service;
	}

	public static void registerRenderService(RenderService service) {
		logger.debug("Registering render service {}", service);
		renderService = service;
	}

	public static void registerPhysicsService(PhysicsService service) {
		logger.debug("Registering physics service {}", service);
		physicsService = service;
	}

	public static void registerTimeService(TimeService service) {
		logger.debug("Registering time service {}", service);
		timeService = service;
	}

	public static void registerInputService(InputService source) {
		logger.debug("Registering input service {}", source);
		inputService = source;
	}

	public static void registerResourceService(ResourceService source) {
		logger.debug("Registering resource service {}", source);
		resourceService = source;
	}

	public static void registerTimeSource(GameTime source) {
		logger.debug("Registering time source {}", source);
		timeSource = source;
	}

	public static void registerMissionManager(MissionManager source) {
		logger.debug("Registering mission manager {}", source);
		missions = source;
	}

	public static void registerUIService(UIService source) {
		logger.debug("Registering UI service {}", source);
		uiService = source;
	}

	public static void registerPlanetOxygenService(PlanetOxygenService source) {
		logger.debug("Registering planet oxygen service {}", source);
		planetOxygenService = source;
	}

	public static void registerPlayerHungerService(PlayerHungerService source) {
		logger.debug("Registering player hunger service {}", source);
		playerHungerService = source;
	}

	public static void registerPlayerMapService(PlayerMapService source) {
		logger.debug("Registering player map service {}", source);
		playerMapService = source;
	}

	public static void registerPlantCommandService(PlantCommandService source) {
		logger.debug("Registering plant command service {}", source);
		plantCommandService = source;
	}

	public static void registerPlantInfoService(PlantInfoService source) {
		logger.debug("Registering plant command service {}", source);
		plantInfoService = source;
	}

	public static void registerLightService(LightService source) {
		logger.debug("Registering light service {}", source);
		lightService = source;
	}

	public static void registerInventoryDisplayManager(InventoryDisplayManager source) {
		logger.debug("Registering inventory display manager {}", source);
		inventoryDisplayManager = source;
	}

	public static void registerParticleService(ParticleService source) {
		particleService = source;
	}

	/**
	 * Registers the save/load service.
	 *
	 * @param source the service to register
	 */
	public static void registerSaveLoadService(SaveLoadService source) {
		logger.debug("Registering Save/Load service {}", source);
		saveLoadService = source;
	}

	public static void registerSoundService(SoundService source) {
		logger.debug("Registering sound service {}", source);
		soundService = source;
	}

	/**
	 * Clears all registered services.
	 * Do not clear saveLoadService
	 */
	public static void clear() {
		entityService = null;
		renderService = null;
		physicsService = null;
		timeSource = null;
		inputService = null;
		resourceService = null;
		gameArea = null;
		soundService = null;
		lightService = null;
		particleService = null;
		timeService = null;
		uiService = null;
	}

	private ServiceLocator() {
		throw new IllegalStateException("Instantiating static util class");
	}

	public static void registerPauseArea(GameAreaDisplay area) {
		pauseMenuArea = area;
	}

	public static GameAreaDisplay getPauseMenuArea() {
		return pauseMenuArea;
	}

	public static InventoryDisplayManager getInventoryDisplayManager() {
		return inventoryDisplayManager;
	}

	public static void registerCraftArea(GameAreaDisplay area) {
		craftArea = area;
	}

	public static GameAreaDisplay getCraftArea() {
		return craftArea;
	}

	public static void registerGame(GdxGame gameVar) {
		game = gameVar;
	}

	public static GdxGame getGame() {
		return game;
	}

}

source/core/src/test/com/csse3200/game/extensions/GameExtension.java
public class GameExtension implements AfterEachCallback, BeforeAllCallback {
	private Application game;

	@Override
	public void beforeAll(ExtensionContext context) {
		// 'Headless' back-end, so no rendering happens
		game = new HeadlessApplication(new ApplicationAdapter() {
		});

		// Mock any calls to OpenGL
		Gdx.gl20 = Mockito.mock(GL20.class);
		Gdx.gl = Gdx.gl20;
	}

	@Override
	public void afterEach(ExtensionContext context) {
		// Clear the global state from the service locator
		ServiceLocator.clear();
	}
}

source/core/src/main/com/csse3200/game/rendering/RenderService.java
public class RenderService implements Disposable {
	private static final int INITIAL_LAYER_CAPACITY = 4;
	private static final int INITIAL_CAPACITY = 4;
	private Stage stage;
	private DebugRenderer debugRenderer;

	/**
	 * Map from layer to list of renderables, allows us to render each layer in the correct order
	 */
	private final SortedIntMap<Array<Renderable>> renderables =
			new SortedIntMap<>(INITIAL_LAYER_CAPACITY);

	/**
	 * Register a new renderable.
	 *
	 * @param renderable new renderable.
	 */
	public void register(Renderable renderable) {
		int layerIndex = renderable.getLayer();
		if (!renderables.containsKey(layerIndex)) {
			renderables.put(layerIndex, new Array<>(INITIAL_CAPACITY));
		}
		Array<Renderable> layer = renderables.get(layerIndex);
		layer.add(renderable);
	}

	/**
	 * Unregister a renderable.
	 *
	 * @param renderable renderable to unregister.
	 */
	public void unregister(Renderable renderable) {
		Array<Renderable> layer = renderables.get(renderable.getLayer());
		if (layer != null) {
			layer.removeValue(renderable, true);
		}
	}

	/**
	 * Trigger rendering on the given batch. This should be called only from the main renderer.
	 *
	 * @param batch batch to render to.
	 */
	public void render(SpriteBatch batch) {
		for (Array<Renderable> layer : renderables) {
			// Sort into rendering order
			layer.sort();

			for (Renderable renderable : layer) {
				renderable.render(batch);
			}
		}
	}

	public void setStage(Stage stage) {
		this.stage = stage;
	}

	public Stage getStage() {
		return stage;
	}

	public void setDebug(DebugRenderer debugRenderer) {
		this.debugRenderer = debugRenderer;
	}

	public DebugRenderer getDebug() {
		return debugRenderer;
	}

	@Override
	public void dispose() {
		renderables.clear();
	}
}

Answer: task.create(() -> entity);

<think>
The test method shouldTriggerChangeDirection is setting up a MovementTask and an entity, then registers a listener for the "directionChange" event. Following the pattern used in earlier tests, the next steps are to create the task with the entity supplier and start it. The immediate next line after adding the listener is therefore the task creation call.
</think>
task.create(() -> entity);