text:
peace love & the middle ages
CFP Medieval Race and the Modern Scholar: Fear, Theory, and the Way Forward #Kzoo2017
Medieval Race and the Modern Scholar: Fear, Theory, and the Way Forward (A Roundtable)
International Congress on Medieval Studies, 2017
Organized by: Cord Whitaker, Sierra Lomuto, Shokoofeh Rajabzadeh
Thomas Hahn's 2001 JMEMS special edition, Race and Ethnicity in the Middle Ages, spearheaded a critical discussion on race in the medieval period; one that Cord Whitaker continues in the 2015 postmedieval edition,Making Race Matter in the Middle Ages. While the articles included in Hahn's edition explore the question he poses in his introduction— "What, if anything, does medieval studies have to do with racial discourses?" — Whitaker's edition takes as its starting point "not whether" the Middle Ages was raced, but "how" it is raced. Making Race Matter pushes the conversation on medieval race into a definitive space significantly evolved from its nascence in 2001. Yet there remains in the larger field of medieval studies a lingering hesitancy to employ the term race when discussing the categorization of difference or the management of alterity within medieval contexts. It often appears in quotations, or is preceded by "pseudo-" or "quasi-."
This panel asks whether and to what extent the discomfort with the concept is a result of the stark binary that has been the cornerstone of race discourse in studies of the Middle Ages: On the one hand, there are scholars even among those who recognize race as a valuable theoretical lens in medieval studies, that still do not consider race integral to the social fabric of the Middle Ages. Rather, they take it as compartmentalized and sequestered, ancillary, a concept that medieval authors and artists could "choose" to "tap into." Race, for these scholars, is only marginal to a medieval European world view. On the other hand, some scholars have read race as a crucial and rich concept whose categories include various forms of alterity. The notion of the "monstrous races," for instance, includes Saracens, Muslims, Jews, monsters, and demons. These categories are often discussed together against a usually white, usually male racially homogenous social norm. In the past few years— in Whitaker's edition and elsewhere— scholars have complicated this binary in formidable ways. They have identified the extremity of these two viewpoints and opened up a space between them rich for exploration. This panel aims to continue the work performed in Making Race Matter by rigorously theorizing race as a concept in the Middle Ages while at the same time querying the persistent resistance to the terminology and concept of medieval race in modern scholarship.
Key questions might include:
How do works engage with and construct race conceptually?
What are the traditions and previous scholarship that cause us to worry over the term race? How do these traditions and scholarship continue to inform our work, even in insidious ways, when we would otherwise take them to task?
What do we, as scholars, bring to texts and works with respect to reading race?
How do we, as scholars in a racially fraught period, negotiate our preconceived readings of race when theorizing race in the Middle Ages?
Please send abstracts of up to 300 words to cord.whitaker@wellesley.edu by September 15.
Posted by Jeffrey Cohen at 1:15 PM
Receive blog posts by email
a medieval studies group blog
It's not easy to see things in the middle, rather than looking down on them from above or up at them from below, or from left to right or right to left: try it, you'll see that everything changes.
-- Deleuze and Guattari, A Thousand Plateaus
"Speak again": Reading Craig Dionne's Posthuman Le...
Deviant Bodies and Animalized Humans
Ecocritical Update
Kant in King Arthur's Court: Charges of Anachronis...
Assembling Arthur at ICMS 2017
The Open Access Companion to the Canterbury Tales
Small Pleasures and Precarious Hopes
CFP Medieval Race and the Modern Scholar: Fear, Th...
Anna Wilson: NCS 2016, Brexit, and 50 Shades of Gr...
GW MEMSI Calendar for 2016-17
Cord J. Whitaker
Leila K. Norako
Mary Kate Hurley
in medias res
convivial and nomadic medieval studies


text:
Tag Archives: Multiple Sclerosis Society
Recent Developments Regarding the Role(s) of Technology in the NHS (BBC News / Health Foundation / Institute for Fiscal Studies / King's Fund / Nuffield Trust / NHS England / RCN / HEE / WHO)
Summary Matt Hancock, the new Secretary of State for Health and Social Care, has spoken of a £487 million investment into "Tech Transformation" in the NHS. Of this, £412 million has been pledged for improving technology in hospitals and increasing … Continue reading →
Posted in Acute Hospitals, Assistive Technology, BBC News, Commissioning, Community Care, Diagnosis, For Carers (mostly), For Doctors (mostly), For Nurses and Therapists (mostly), For Researchers (mostly), Health Education England (HEE), Health Foundation, In the News, Integrated Care, International, King's Fund, Management of Condition, Mental Health, National, NHS, NHS England, Nuffield Trust, Person-Centred Care, Personalisation, Quick Insights, RCN, Telecare, Telehealth, UK, Universal Interest, World Health Organization (WHO)	| Tagged Accelerating Innovation, Access to Electronic Care Records, Access to GP Services, Access to Mental Health Services, Access to Personal Health Records Online, Access to Primary Care, Access to Self-Collected Lifestyle Data From NHS apps or Fitness Trackers, Access to Transformative Health Technology, Ageing Population, Applications of Big Data, Artificial Intelligence, Artificial Intelligence (AI), Assistive Technology, Attitudes Towards Data Sharing, Barriers to Joined-Up Care, BBC Health News, BBC Politics News, Big Data, Big Data Analytics, Cancer Diagnosis, Clever Together, Commissioning for Transformation, Commissioning Support Units (CSUs), Community Services and Primary Care, Corrective to Uncritical Uptake of IT Interventions: World Health Organization (WHO), Data and Digital Health, Data Sharing, Digital Awareness, Digital by Default, Digital Capability, Digital Care Plans, Digital Care Records, Digital Data Capture, Digital Diagnostics, Digital Future of Nursing, Digital Health, Digital Health Innovations, Digital Innovation, Digital Innovations in Health, Digital Interventions for Health System Improvements, Digital Maturity, Digital Maturity Assessments, Digital Maturity Index, Digital NHS, Digital Service Transformation, Digital Services for Patients, Digital Skills, Digital Skills of NHS Workforce, Digital Technology, Digital Technology and Innovation, Early Cancer Diagnosis, Efficiencies and Productivity Gains, Efficiency and Effectiveness, Efficiency Opportunities, Efficiency Savings, Electronic Care Record (ECR), Electronic Health Records, Electronic Health Records (EHRs), Electronic Patient Record (EPR), Electronic Patient Record Systems, Emily Gravestock: UK Space Agency, Every Nurse an E-Nurse: Royal College of Nursing (RCN), Fear of Missing Out (FoMO), Fitness Trackers, Genomic Medicine, Genomic Technologies, Genomics, George Freeman MP: Former Life Sciences Minister, GP at Hand (Babylon), GP Services, Health and Care of Older People, Health and Care Technology, HEE: Health Education England, IFS: Institute for Fiscal Studies, Improving Access to Diagnostics, Improving Access to GP Services, Improving Access to Healthcare, Increasing the Value of Information, Information and Advice, Information and Advice Services, Information and Data Linkage to Support Transformation, Information and Intelligence, Information and Support for Patients and Carers, Information Needs of Patients, Information Pathways, Information Revolution, Information Sharing, Information Technology, Innovation and Improvement, Institute for Fiscal Studies, Integrated Digital Care Records (IDCRs), Integrated Digital Care: An Information Revolution, Integrated Health and Care Records, Integration of Health and Care, Interoperability, Investing for Transformation, Jeremy Porteus, Joined-Up Care, King's College London. Social Care Workforce Research Unit, Leveraging Big Data, Long-Term Conditions (LTCs), Low Morale, Matt Hancock: Secretary of State for Health and Social Care, Mental Health Care and Treatment, MS Society, Multiple Sclerosis, Multiple Sclerosis (MS), Multiple Sclerosis Society, National Information Board's Building a Digital Ready Workforce (BDRW) Programme, New Technology, NHS at 70: New Technology for the NHS and Patients, NHS Technology Agenda, Online Patient Consultations, Open Data and Big Data, Optimising Benefits of Digital Technology, Optimising Patient Outcomes Using Digital Technology, Optimising Use of Digital Technology, Paper-Based Record-Keeping, Paper-Based Systems, Paper-Free Healthcare, Paper-Free NHS, Paperless Systems, Patient Access to Records, Patient Activation, Patient Choice, Personalised Technology, Precision Medicine Initiative, Preparing the Healthcare Workforce for the Digital Future. Interim Report (Topol Review), Primary Care, Reducing Treatment Waiting Times, Remote Care Monitoring, Removal of Barriers to Transformative Health Technology (Facilitators of Innovation), Royal College of Nursing (RCN), Royal Society for Public Health, Royal Society for Public Health: Scroll Free September Campaign, Rt Hon Matt Hancock MP, Scan4Safety: Tracking of Patient Care, Scroll Free September Campaign: Royal Society for Public Health (2018), SCWRU: Social Care Workforce Research Unit (King's College London), Self Care (Technology-Supported), Self-Management (Technology-Supported), Service Transformation, Shirley Cramer: Chief Executive of Royal Society for Public Health, Social Care Workforce Research Unit: King's College London, Space Age Technology (sic), Speed of Cancer Diagnosis, Taxpayers' Alliance, Technological Trends, Technology and Innovation, Technology-Supported Self-Management, Tele-ICU, Telecare LIN, Telemedicine, TeleTracking, The Royal Society for Public Health (RSPH), Tony Young: NHS England National Clinical Director for Innovation, Topol Review: Health Education England, Tracking Patient Care, Tracking Patient Progress, Transformational Commissioning, Transformational Technologies, Transformative Health Technology, Transformative Technology, UK Space Agency, Use of Data and Technology to Transform Outcomes for Patients and Citizens, UTOPIA Project: 2016-17 National Survey of Local Authority Telecare Provision for Older People in England, UTOPIA Project: Using Telecare for Older People in Adult Social Care, Video Consultations in General Practice, Video Consultations With GPs, Virtual Access to GP Services, West Suffolk Hospital, West Suffolk Hospital (Matt Hancock's First NHS Speech), WHO Guideline: Recommendations on Digital Interventions for Health System Strengthening, Wider System Access, World Health Organization (WHO): Corrective to Over-Optimism Regarding IT	| Leave a comment
Carers' Week 2015 (Carers Week / NHS England)
Summary This is Carers' Week 2015; it runs between June 8th – 14th 2015. "Carers Week is an annual campaign to raise awareness of caring, highlight the challenges carers face and recognise the contribution they make to families and communities … Continue reading →
Posted in Age UK, Carers UK, Charitable Bodies, Commissioning, Community Care, For Carers (mostly), For Nurses and Therapists (mostly), For Social Workers (mostly), Integrated Care, Local Interest, Management of Condition, National, NHS, NHS England, Person-Centred Care, Personalisation, Practical Advice, Quick Insights, Standards, UK, Universal Interest	| Tagged Adult Carers in England: Quality of Life, Adult Social Care, Age UK Lincoln, Ageing and Society, Ageing Policy in the UK, Ageing Population, Building Carer Friendly Communities, Burden on Caregivers, Caregiver Assessments, Caregivers, Caregiving (Carers), Carer Awareness, Carer Burden in Dementia, Carer Experience, Carer Fatigue, Carer Friendly Communities, Carer Friendly Communities Conference, Carer Friendly Employers, Carer Friendly Hospitals, Carer Friendly Local Pharmacy Services, Carer Friendly Policies, Carer Friendly Society, Carer Friendly Workplaces, Carer Isolation, Carer Organisations, Carer Support, Carer Support Services, Carer's Needs, Carer's Perspective, Carers and Families, Carers Strategy Cross Government Board, Carers Trust, Carers Week Charities, Carers' Checklist, Carers' Health and Wellbeing, Carers' Week 2015, Caring and Family Finances, Caring into Later Life, Centrica / British Gas, Collaborative Working in Local Communities for Benefit of Carers, Commissioning Carer Support Services, Commitment to Carers (NHS England), Community-Based Services, Crossroads Care, Employers for Carers, Employers Supporting Working Carers, Experiences, Experiences of Health Care Services, Experiences of Social Care Services, Families, Family Caregivers, Family Carers, Financial Issues, Halas Homes, Health and Wellbeing, Home and Community Care Services, Home Care, Hours of Unpaid Care by Older Carers, Impact of Caring on Carers, Improving Lives of Carers, Improving Patient Experience, Independent Age, Informal Caregiving, Informal Carers, Janet Morrison (Chief Executive of Independent Age), Jen Kenward: NHS England Head of Patient Experience and Carers Programme Lead, Lister Hospital in Hertfordshire, Living With MS Days, Lockwood Charitable Foundation, Macmillan Cancer Support, MS Society, Multiple Sclerosis Society, National Carers Strategy, Neil Churchill: National Director of Patient Experience (NHS England), NHS England's Commitment to Carers, NHS England's Improving Patient Experience, NHS Five Year Forward View, Nutricia Advanced Medical Nutrition, Older Carers, Oxfordshire County Council, Sainsbury's (Event Sponsor), Standing Commission on Carers, Suffolk County Council, Suffolk Family Carers, Suffolk Young Carers Schools Development Work, Support for Carers, Sustainable Caring, Triangle of Care, Triangle of Care for Dementia, Triangle of Care Membership Scheme, Underpaid, Undervalued Hidden Workforce, Unpaid Caregivers (Carers), Unpaid Carers, Valuing Carers, Views of Informal Carers, Young Carers	| Leave a comment
Strategic Clinical Networks (NHS Commissioning Board)
Summary The NHS Commissioning Board is planning a small number of national networks to improve health services for specific patient groups or conditions. These strategic clinical networks will adopt the NHS network approach to improving the delivery of patient care. … Continue reading →
Posted in Commissioning, Community Care, For Doctors (mostly), For Nurses and Therapists (mostly), For Social Workers (mostly), Integrated Care, Management of Condition, National, NHS, NHS Improvement, Proposed for Next Newsletter, Quick Insights, UK, Universal Interest	| Tagged Action Duchenne, Action for Dystonia, Action for M.E., and North Yorkshire Neurological Alliance, Ann Conroy Trust, Association of British Neurologists, Ataxia -Telangiectasia Society, Ataxia UK, Batten Disease Family Association, Black Country Neurological Alliance, Brain and Spine Foundation, Brain Research Trust, Brain Tumour UK, British Acoustic Neuroma Association, British Paediatric Neurology Association, British Polio Fellowship, Buckinghamshire Association of Neurological Organisations, Cavernoma Alliance, Chartered Society of Physiotherapists, Clinical Commissioning Groups (CCGs), Clinical Networks, CMT United Kingdom, Community Services, Cornwall Alliance of Neuro-Domain Organisations, Cure Parkinson's Trust, David Bateman: National Clinical Director for Neurological Conditions, Diagnosis, Different Strokes, Dudley NHS Foundation Trust Community Neurology Team, Durham, Dystonia Society, East Kent Primary Care Epilepsy Service, Education and Research, Encephalitis Society, Encouraging Innovation, Epilepsy Action, Epilepsy Bereaved, Epilepsy Society, FibroAction, Fighting Strokes, Forward M.E., Gathering Data and Intelligence, Glenside Manor, Gloucestershire Neurological Alliance, Greater Manchester Neurological Alliance, Guillain-Barré Syndrome Support Group, Hampshire Neurological Alliance, Headway, Health and Social Care Integration, Hemihelp, Hounslow and Richmond Neurological Partnership, Independent Healthcare Advisory Services, Integration, Joint Epilepsy Council of the UK and Ireland, Lancashire and South Cumbria Neurological Alliance, Lincolnshire Neurological Alliance, Local Authorities, Long Term Neurological Conditions (LTNCs), Long-Term Care (LTC), Long-Term Conditions, Long-Term Conditions (LTCs), Mental Health and Community Services, Merseyside and Cheshire Neurological Alliance, Migraine Trust, Motor Neurone Disease Association, Multiple Sclerosis Society, Multiple Sclerosis Trust, Multiple System Atrophy Trust, Myasthenia Gravis Association, National Hospital for Neurology and Neurosurgery Development Foundation, National ME Centre, National Tremor Foundation, Nerve Centre Kirklees, Networks, Neuro Knowhow Training for GPs, Neurological Alliance, Neurological Conditions, Neurology Services, Neurosupport, NHS Commissioning Board, NHS Commissioning Board (NHSCB), NHS Commissioning Board Authority, NHS Commissioning Board Authority (NHSCBA), NHS Outcomes Framework, NHS Outcomes Framework 2012/13, Northern Neurological Alliance, Oxfordshire Neurological Alliance, Pain Concern, Parkinson's UK, PJ Care Limited, Polio Survivors Network, PSP Association, Royal Hospital for Neuro-disability, Sandwell and West Birmingham Hospitals NHS Trust, Sandwell PCT, South West Alliance of Neurological Organisations, Staffordshire and Stoke on Trent Partnership NHS Trust: Adult Ability Team, Stoke Mandeville Spinal Foundation, Strategic Clinical Network: Mental Health; Dementia and Neurological Conditions, Strategic Clinical Networks, Strategic Clinical Networks (NHS Commissioning Board), Strategic Clinical Networks for Mental Health Dementia and Neurological Conditions, Stroke Association, Sue Ryder, Swindon and Wiltshire Neurological Alliance, Tees Valley, Tourettes Action, Transformation Directorate of the NHS CB, Tranverse Myelitis Society, Trigeminal Neuralgia Association UK, Tuberous Sclerosis Association, UK Acquired Brain Injury Forum, Walsall Healthcare NHS Trust Community Neurological Rehabilitation, West Berkshire Neurological Alliance, West Midlands Quality Review Service (WMQRS), Whole Systems Approach, Yorkshire and Humberside Association of Neurological Organisations	| Leave a comment

redpajama_set_name: RedPajamaCommonCrawl


text:
Home News Rodent and cockroach infestation at Plaza Singapura's Toast Box, netizens call for...
Rodent and cockroach infestation at Plaza Singapura's Toast Box, netizens call for harsher penalty
Plaza Singapura's Toast Box outlet has been suspended for the next two weeks due to rodent and cockroach infestations.
The National Environment Agency (NEA) "will be suspending the licence of foodshop At 68 Orchard Road, #01-23, (Left Side, Part Of) Plaza Singapura, Singapore 238839 under the Points Demerit System. The period of suspension is two weeks from 25/05/2018 to 07/06/2018".
The NEA also added that, "The licensee has accumulated 12 demerit points over the last 12 months and fined a total of $800".
It has been reported that while the Toast Box outlet has been closed, the adjoining BreadTalk unit will remain open.
When reached out to for comment, the Toast Box regional general manager, Vincent Lim, said, "We fully acknowledge the results of the NEA assessment which reflected that there were improvements needed in the cleanliness and hygiene standards at our outlet, and we took immediate action to address the findings".
He also added that, "Immediately after the assessment, we administered thorough pest control and sanitisation of the entire outlet".
"During this closure, we will further reinforce our standard operating procedures and training with our staff," he said.
The NEA also stated that, "Depending on his past record, a licensee who accumulates 12 or more demerit points during a 12-month period may have his licence suspended for a period of either two or four weeks, or cancelled. All food handlers working in the suspended premises would also be required to attend and pass the Basic Food Hygiene Course again, before they can resume work as food handlers".
Netizens and patrons of the store feel that the $800 fine barely scratches the surface and call for a greater amount to be imposed.


text:
<!DOCTYPE html>

    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
    <title>获得的商品 - {wc:$webname}触屏版</title>
    <meta content="app-id=518966501" name="apple-itunes-app" />
    <meta content="yes" name="apple-mobile-web-app-capable" />
    <meta content="black" name="apple-mobile-web-app-status-bar-style" />
    <meta content="telephone=no" name="format-detection" />
    <link href="{G_TEMPLATES_MOBILE_CSS}/comm.css" rel="stylesheet" type="text/css" />
	<link href="{G_TEMPLATES_MOBILE_CSS}/member.css" rel="stylesheet" type="text/css" />

	        <s></s>返回

获得的商品

    <input name="hidTotalCount" type="hidden" id="hidTotalCount" />
    <input name="hidPageMax" type="hidden" id="hidPageMax" />

正在加载

	        点击加载更多

{wc:templates "mobile/index","footer"}

redpajama_set_name: RedPajamaGithub


text:
Schools eager for Hochul to act on masks, vaccines, quarantine and more
Gary Stern Katelyn Cordero
Incoming Gov. Kathy Hochul is expected to soon mandate masks for school classrooms this fall — tackling one of the most contentious issues in the country — but school districts still face major health decisions before the new school year begins.
Virtually all New York districts will have students in school full time, a fundamental and welcome change from a year ago, even as rising COVID numbers from the delta variant bring a new level of uncertainty.
Many districts have posted preliminary reopening plans, with all in the Hudson Valley requiring masks to this point. Others hope the state may still step in and resolve thorny issues such as quarantine rules, social distancing rules, COVID testing, and the possible requiring of vaccinations for staff.
In Dutchess, all 13 districts have announced plans that include an indoor mask mandate. Wappingers Superintendent Dwight Bonk said his district has received "countless" emails from parents about masks and other protocols and ultimately followed medical guidance.
"The decision was extremely difficult," he said. "In June I was hopeful that we would not be in this predicament, but unfortunately we are."
Opening day will vary across the region, with some districts welcoming students as soon as Sept. 1 and others waiting until Sept. 8, 9 or 10, after Labor Day and Rosh Hashanah.
Opinion: Kathy Hochul, here's how to move Empire State forward
Tracking COVID: Rockland dashboard now gives vaccine status
Fall sports: Putnam, Dutchess letting schools set guidelines
The summer began with schools expecting the state Health Department to deliver an updated series of mandates and recommendations for the 2021-22 school year. But the department abruptly canceled the project in early August, as Gov. Andrew Cuomo fought for his political life, saying it lost the authority to produce statewide rules when New York's state of emergency ended on June 25.
The state Education Department responded with a series of nonbinding recommendations based on guidance from the U.S. Centers for Disease Control and Prevention and the American Academy of Pediatrics.
Hochul hasn't indicated whether she will address school issues other than masks after she takes office at midnight Tuesday. So it could be left to districts, working with county health departments, to adopt health policies on a local or regional basis.
Lindsay Neptune, who leads health centers run by the nonprofit Open Door Family Medical Center at seven schools in Port Chester and Ossining, said that everyone's goal for the new school year should be to have policies that keep schools open. Her staff has prioritized vaccinations and mask-wearing to parents.
"The reason we need rules is not for anyone to be uncomfortable, but to give students the opportunity to do what they do best," said Neptune, a pediatric nurse practitioner. "If kids can be with their peers, access teachers and counselors, take part in activities, they will thrive. We need to decrease fear by letting kids know they can be safe."
The key issues
Masks: Hochul repeated Wednesday that she plans to mandate indoor masks for schools in New York, a move that would be applauded by the educational community. Schools want to avoid making local decisions on health policy, particularly on an emotional issue that has provoked conflict across the country.
"I think it would be wonderful if the governor comes through with a mask mandate, which would help create a clear path to reopening," said Fran Wills, who represents Westchester, Rockland, Putnam, Dutchess and Orange counties on the state Board of Regents. "When you hear parents' anxieties and fears, you have to pay attention. But parents should have confidence in their schools to make sure kids are safe."
In many districts, pockets of parents oppose mandatory masks, saying that schools are creating unnecessary hardships for students. In Clarkstown, a school board meeting was halted Aug. 12 when audience members refused to wear masks.
"I feel like we are going back to everything that was happening last year even though we've made a lot of advancements with vaccines and everything this year to protect adults," said Sarah Hanganu, an Arlington mom of three who is part of a new Dutchess chapter of Moms for Liberty, a group that opposes mask mandates.
"So we are putting the burden on children to protect parents because we know that children are not at a great risk of this," she said at an Arlington school board meeting.
The mask issue continues to be battled out across the country. Several Florida districts, including the vast Miami-Dade district, mandated masks in recent days, defying an order from Gov. Ron Desantis that prohibits such policies.
Education officials have noted that a mask mandate in New York could be lifted during the school year if circumstances warrant it.
Staff vaccines: Many wonder whether Hochul will address the question of possible mandatory vaccinations for most school staff statewide. Hudson Valley districts have encouraged teachers and other staffers to get vaccinated, and generally say that the majority have done so, but officials have been leery of requiring the vaccine.
New York City and Yonkers schools have said that staff has to be vaccinated or undergo weekly testing.
Momentum appears to be picking up for mandatory vaccinations. Washington State said Wednesday that all school personnel have to be vaccinated by Oct. 18, and New Jersey Gov. Phil Murphy is expected to announce a similar requirement.
Harry Leonardatos, a Rockland County principal who will become president in October of the School Administrators Association of New York State, said that a vaccine mandate is the right move.
"I would like to see the new governor tackle that — all those who are eligible get the vaccine and weekly testing for all of those who aren't," he said.
Quarantine and contact tracing rules: Quarantines were a major disruption to school last year. Districts worked with county health departments to identify students and staff who needed to quarantine, but each county had its own rules.
This year, the state Education Department recommends following CDC guidance for quarantines and contact tracing. The CDC says that fully vaccinated people should not have to quarantine unless they show symptoms and that masked students should be partially exempt from quarantine rules.
In states with low vaccination rates, many districts that have opened schools are already facing large numbers of students in quarantine. In New York, with most staff and many students vaccinated, and the likelihood of a mask mandate, educators expect to see far few quarantines than last year.
But many would still like to see Hochul produce uniform rules.
"Schools are working hard to do the right thing for their communities, but having standardization around certain things, like quarantining, would really help," North Rockland Superintendent Kris Felicello said. "If the governor were to give quarantine rules some teeth, it would help districts and municipalities."
Remote learning: Most districts have no plans for remote learning this year — and hope that won't change. "It's a given that we need to have contingency plans to revert to remote in the event for a (COVID) surge," said Bob Lowry of the New York State Superintendents Council.
One issue is how districts will educate students who do have to quarantine. It seems that districts will use their own approaches, including tutors, home delivery of materials and some daily interraction with teachers.
Social distancing: The state Education Department, following the CDC, recommends keeping three feet between students indoors. Other strategies, like keeping students in groups, are proposed when three feet cannot be maintained.
When it comes to having large groups of students in cafeterias — a major challenge for schools last year — the Education Department says that doing so should depend on community transmission rates. If rates are high, meals can be eaten outdoors or in classrooms.
Six feet is still recommended between students and adults, and between adults who are not fully vaccinated.
COVID testing: Dozens of New York districts chose to do random testing of students and staff during the last school year, most with tests provided by the state. It's up to counties and districts whether to do testing this year and under what circumstances. The state has provided federal funds to counties to assist with testing in schools.
The state Education Department called for testing in communities where the virus is spreading fastest or with low vaccination rates.
COVID tracking and reporting: Last year, districts had to report case numbers to the state, which put district-by-district results into an online tracker. No such requirement exists for the new year, but the state Education Department is asking districts to report cases to their county health department. Most districts will continue providing regular updates to their communities as well.
Gary Stern is an editor/writer covering K-12 education in the Hudson Valley. Reach him at gstern@lohud.com. Twitter: @garysternNY. Click here for his latest.


text:
Auto Auction Mall
Dealer Auctions
Shipping, Export & Import
Top 10 car auctions
How Car Auctions Work?
Do I need a license to buy?
US States Rebuild Title Rules
9am - 7pm ET Mon-Fri
What is Salvage title?
Export cars from the U.S.
US States Rebuilt Title Rules
Subastas Online
Exportar Carros
Auto Auction Mall > Knowledge Base > What is Salvage title?
What is Salvage title? Export cars from the U.S.
Importing Used or Salvage Vehicles from the United States into Lebanon
By Mike Richards Updated: 11/05/2019 Posted: 12/02/2016
Although Lebanon is a small country, imported used cars are big business there. This has much to do with the fact that Lebanon itself does not make its own cars and therefore must rely on imports from abroad. Although Asia and Europe take the lion's share of both the new and used car import markets in Lebanon, the United States holds a high stake. For this reason, many might be interested in what's involved in importing used cars from the United States into Lebanon.
First, you must know what restrictions Lebanon has placed on the import of used cars. More importantly, though, you'll want to know the process for clearing customs, as well as what customs duties and taxes will be due once your used U.S. vehicle arrives in the country. Below, we're going to cover all this and more, filling you in on everything you need to know about importing used cars from the United States into Lebanon.
Lebanese Restrictions on the Import of Used Vehicles
When seeking to export a used vehicle from the United States to Lebanon, there are a few restrictions you should be aware of. First, Lebanon prohibits the import of used vehicles over eight years old. To calculate a vehicle's age, Lebanon goes by the model year and not the date of manufacture or the sale date. In addition to this, Lebanon also prohibits the import of used vehicles that use diesel fuel.
Should you have any questions about import restrictions for used cars, or else wish to ask about what exemptions might exist to the rules, please contact the Embassy of Lebanon in the United States.
Purchasing Used Vehicles at U.S. Online Car Auctions
When it comes to getting an incredible deal on a used car in the United States, used car auctions have long been the best options. Unfortunately, used and salvage car auctions have typically only been available to those who have a dealer's license. That's all changed in recent years, though, thanks to online car auctions.
These online car auction sites list vehicles from certain dealer-only auction houses on their site. So, you get access to this inventory at great prices and also to the savings that had previously only been available to dealers. Best of all, you can participate in used car auctions from the comfort of your own home, the top level of convenience!
Importing Used or Salvage Vehicles from the United States into Panama
Exporting Cars from the USA to Lebanon with a visit to the embassy
Importing Used or Salvage Vehicles from the United States into Togo
Importing Used or Salvage Vehicles from the United States into Jordan Auto Market
To get started with an online used car auction, you first need to create an account. After this, you will need to make an initial deposit, which will establish your bidding power. With most sites, you'll find that this deposit equals one-tenth of whatever your maximum bid can be. For example, were you to start with a $500 deposit, you would then be able to bid up to $5,000.
After you've created your account and made your deposit, the real fun begins. An extensive database of used car auctions taking place across the entire country will be literally at your fingertips. To help you sort through the volume, you can speak to an auction agent or broker. He or she can help you with everything from a bidding strategy to the history of cars that interest you. Additionally, this agent or broker can connect you with used car auctions that cannot be displayed publicly on online lists.
In the end, if you're looking to get the car that's right for you at savings that could reach 70% or more, online car auctions are the best!
Shipping a Used or Salvage U.S. Car to Lebanon
Lebanon serves a vital role in international trade, especially as a gateway for the Middle East. As such, most major U.S. ports will offer shipping services to the country. When it comes to importing your used U.S. vehicle into Lebanon, then, the only real choice that you'll have to make is the shipping method.
Naturally, you can opt for traditional container shipping, which offers the benefit of providing exceptional protection for your vehicle. However, if you're willing to accept a small amount of risk, there is another shipping method that could work exceptionally well for you.
This method is known as RORO shipping. RORO stands for "roll-on roll-off." Simply put, when you opt for this shipping method, your used vehicle will roll onto the ship at your chosen port of departure and then roll off once it arrives in Lebanon. Because this involves significantly less labor and overhead than container shipping, it's also much cheaper.
As far as risk is concerned, it is important to remember that your vehicle could be exposed to the elements due to the lack of the protection of a container. Also, ship workers will be responsible for moving your vehicle. That said, the risk of damage occurring due to either of these factors is incredibly minor. In most cases, the savings offset the risk. This is especially true when shipping a used vehicle to Lebanon, which calculates import duties and taxes based upon CIF.
There are ports along the coastline of Lebanon, many of which will offer service for used U.S. vehicles arriving via the RORO shipping method. However, if you are going ship your used vehicle to Lebanon via a container, you will have two options when it comes to Lebanese container ports. The first is the Port of Tripoli, located along the country's northern shore. The second is the Port of Beirut, located along the country's southern shore.
To find out more information about the Port of Tripoli, please consult its official website here. To find out more information about the Port of Beirut, please consult its official website here. Also, you may also wish to consult with the Lebanese Marine Agency if you're interested in shipping your used vehicle to one of the country's smaller, non-container ports.
Clearing Your Used Vehicle Shipped to Lebanon Through U.S. Customs
Before your used U.S. vehicle is ready to export to Lebanon, it must first clear U.S. customs. Thankfully, you'll find that the process is incredibly simple. It merely requires that you submit your vehicle for inspection. You need to provide the vehicle's documents to customs at your chosen port of departure at least 72 hours in advance of your ship date. (To find the location of the customs office at your departure port, contact the port's director.)
As far as documentation is concerned, you will need to gather your vehicle's Original Certificate of Title. Also, you will also need to furnish U.S. customs with either a certified copy of that title or two complete copies of the title. These, you can get from the DMV in the state where your used or salvage vehicle is registered.
Once U.S. customs has your vehicle and documents, they will check that the vehicle in question is the same as the one listed on the documents. Also, they will also inspect the vehicle to ensure that it is clear of illegal items. Provided everything checks out, your vehicle will then clear customs and is ready to load onto the ship.
Should you have any more questions about the process for clearing customs at your chosen U.S. port of departure, please consult this guide provided by U.S. Customs and Border Security.
Getting Your Used or Salvage Car Through Lebanese Customs
When importing a used vehicle into Lebanon, you will have to present the right documentation for your vehicle. You will also need to pay import duties and taxes. You will need to present Lebanese Customs with:
The original Bill of Lading
The original U.S. Vehicle Registration
The original Certificate of Title
A Purchase or Commercial Invoice
Note that the bill of lading will need to include vital information about your used vehicle. It should include both the make and model along with the VIN, engine number, vehicle color, and weight. Failing to have a Bill of Lading that includes the above information could delay your customs clearance.
After inspecting both your vehicle and the above papers, you will have to pay import duties and fees, outlined below. Following that, your vehicle will clear Lebanese customs, at which point you can register the vehicle.
The above should cover the vast majority of cases where a used U.S. vehicle is imported into Lebanon. However, if your case is special, you may wish to consult this complete guide to the import of used vehicles and other items that are provided by Lebanese Customs.
Import Duties and Taxes for U.S. Vehicles Imported into Lebanon
When calculating duties and taxes on imported used vehicles, Lebanon uses the CIF value of the imported vehicle. If you are not already familiar with CIF, then allow us to explain. CIF is short for "Cost, Insurance, Freight." It represents the total value of the vehicle (as determined by customs and documentation that you submit) plus the total cost of shipping and shipping insurance. It's for this reason that you will want to save as much money as possible when shipping.
Regarding assessing its import duty, Lebanon takes into account the value of the vehicle imported. For imported vehicles where the CIF is 20 million LBP or less, a flat customs duty of 5 million LBP is charged. For vehicles where the CIF is greater than 20 million LBP, then customs duty is 50% of the CIF amount.
In addition to the above customs duty, there is also a Value Added Tax (VAT) added by Lebanese customs authorities. Regardless of age, value or condition of the imported used vehicle, this VAT is equal to 10% of the sum of the vehicle's CIF and whatever the amount paid for the import duty.
As an example, let's consider a used vehicle that has a CIF of 10 million LBP. In this instance, a 5 million LBP duty, and a VAT of 1.5 million LBP (15,000,000 LBP x 10%) is assessed. Therefore, the total cost of importing the vehicle into Lebanon would be 6.5 million LBP.
Should you have any more questions about import duties and taxes paid on used vehicles imported from the United States into Lebanon, please consult the official website for Lebanese Customs here.
How to Register an Imported Used Car in Lebanon
The Traffic, Trucks, and Vehicles Management Authority handles vehicle registration in Lebanon. Much of the process you can complete through the authority's online portal, which can be accessed here.
The Used Vehicle Market in Lebanon
With little domestic automotive manufacturing to speak of, both the new and used car markets in Lebanon rely heavily on imports. Because of this, the import market for vehicles both new and used is valued at over $1.14 billion, according to statistics compiled by the Massachusetts Institute of Technology. Of that total market, the United States has a 16% share, valued at around $183 million. While significant, the market shares owned by Europe and Asia are much higher. For example, Germany alone owns a 23% share of the market, while Japan owns a 20% share.
In recent years, the sales of new autos in Lebanon have been slower than in the past. As such, there has been a concomitant rise in the sale of used vehicles in the country. Like many other countries around the globe, the trend in Lebanon has been toward smaller and more fuel-efficient vehicles. For this reason, cars like the Toyota Yaris have been enjoying strong sales in the country. Actually, Toyota currently owns a 26.5% share of the market overall. This brand is famous for its small, fuel-efficient and easy-to-repair vehicles.
Outside the light vehicle sector, there has been growing demand for heavier vehicles. In particular, the Toyota Land Cruiser has enjoyed remarkably strong sales of late. Last year, for example, the Land Cruiser was the fourth most popular car on the Lebanese auto market overall. When it comes to luxury automobiles, Lexus has been doing well, with its LX model enjoying increasing sales year-over-year.
See our Vehicle Auctions, Car Auctions and Education Centre.
subscribers to get free tips & guides on cars for sale.
We hate spam as much as you! Unsubscribe any time
Thank you for subscribing to Auto Auction Mall's Newsletter!
About Auto Auction Mall
Auto Auction Mall is an online marketplace that connects to all of the major salvage & insurance vehicle auction houses in North America.
We have helped thousands of buyers from dozens of countries buy and ship their dream cars while spending a fraction of the retail price to get them. It's a win win situation for us and for you. So join us today and start shopping for your dream car.
Need More Help?Check out our FAQs sectionAccess FAQs
Top 10 Best Online Car Auctions Websites to Buy Used & Salvage Cars
How You Can Get Your Next Car from a Dealers Auto Auction
A Guide to Finding Repo Cars for Sale
Car Auction Checklist: What You Need to Have Ready
What Does It Mean When a Car Has a "Clean Title" At Salvage and Clean Title Car Auctions?
Auction Starts In
Location Candia NH
Status Starts & Moves
Mileage 64,273 (Actual)
Title Status clear
Financing From $20 / month
Current Bid $100
Everything You Need to Know about Buying Used Cars 09/25/2018 What is Salvage title?
Exporting Cars from the USA to Lebanon with a visit to the embassy 10/26/2015 Export cars from the U.S.
Importing Used or Salvage Vehicles from the United States into Panama 12/09/2016 What is Salvage title?
"Second Hand" Cars in Ghana are importing from the United States – Used or Salvage Vehicles for Sale 09/02/2016 What is Salvage title?
Once you find a vehicle you like on our website and you are ready to start bidding on it, please contact our agent so they can walk you through the sign up and deposit process.
Contact our Auto Auction Specialist
© 2019 Auto Auction Mall. All Rights Reserved.
Use of this Website constitutes acceptance of Auto Auction Mall Terms of Service and Privacy Policy.
Auto Auction Mall is not owned by or affiliated with IAA-Insurance Auto Auctions, Copart, Inc., or its subsidiaries.
Chat with our agent


I really love potatoes, whether they're mashed, roasted, baked or grilled, they are one of my favourite foods. So, it was only fitting that on the hottest day in oh, say 92 years, I was craving some roasted potatoes. Well, there was no chance that I was going to turn on my oven so I decided to fire up the grill and grill some potatoes. Earlier this year I had stumbled upon a recipe for herb grilled potatoes which sounded delicious and I decided to give it a try, and boy, were these ever good. To me, this seems like a healthier and lighter alternative to the ever present potato salad, and personally, I prefer the grilled potatoes over their doused in mayonnaise first cousin, twice removed.
Also, check out the new visual Recipe Index! I have just completely added it to the site, there are different categories such as appetizers, healthy, desserts and baked goods etc. check it out and let me know what you think.
Slice potatoes in 1/2-inch thick slices, and cook in a pot of salted water for 10 minutes.
While potatoes are cooking, in a small bowl, stir together herbs, garlic, olive oil, salt and pepper.
Drain the potatoes and place them in a large bowl. Pour the oil mixture over the potatoes and toss to coat.
Transfer the potatoes to a pre-heated grill and grill the potatoes turning once or twice, until tender, about 5 minutes total.
Transfer potatoes to serving platter and squeeze lemon over the potatoes and serve.
These herb grilled potatoes have to be one of my favourite dishes of the summer so far, what's your favourite?


text:
Kelly Rigg, Contributor
Campaign consultant
The Real Earth Day Conspiracy
04/22/2011 04:29 pm ET Updated Jun 22, 2011
Many have noted the tragic and hugely ironic coincidence that some of the biggest environmental catastrophes have happened on or around Earth Day. Think about it...
The Deepwater Horizon blew out last year on April 20th, and sank two days later -- on Earth Day, 2010. That day BP CEO Tony Hayward (in a lawsuit against Halliburton & Transocean) claimed the oil giant was not at fault.
The very same Earth Day, Massey Energy CEO Don Blankenship stated that the Big Branch Coal Mine disaster, which took the lives of 25 miners just a few weeks prior, again was likely not the fault of the coal giant and may have resulted from a "natural occurring phenomenon."
Now one year later to the day, the blowout of a natural gas fracking well in Bradford County, Pennsylvania made headline news with the threat of thousands of gallons of toxic compounds entering the water supply.
The timing of that one was coincidental not only because it was the anniversary of the Gulf spill, but because the debate over fracking had just reached a feverish pitch. A study released on April 12 showed that the global warming impact of shale gas wells is worse than coal due to the methane leaks which are inherent to the process of fracking, and just last month another report was released linking natural gas fracking to increased earthquake activity.
So we've got a coal disaster, an oil disaster, and a natural gas disaster. But this curious series of coincidences does not end with fossil fuels. The Three Mile Island nuclear accident, which happened just a few weeks before Earth Day 1979, was a wake-up call for environmentalists who came out in the tens of thousands to protest nuclear power. Seven years later we had Chernobyl on April 26, 1986.
Often when a series of bizarre coincidences occur in sequence we humans are prone to come up with an explanation, and those often take the form of a conspiracy theory. Last year, the creative people at Fox News came up with an interesting explanation - the BP oil spill was a conspiracy by environmentalists (and President Obama) to take down our poor, assaulted petroleum industry (an industry which BTW had record-setting profits in 2009 along with hundreds of filed safety violations, yet somehow managed to pay no U.S. taxes).
The Glenn Beck Show even went so far as to say that naturally occurring crude oil leakage from the ocean floor was comparable to the BP oil spill, and that "Mother Nature has a way of taking care of these sorts of things."
I don't know about you, but if I were Mother Nature I would be pretty pissed right about now. I should be ashamed to admit this, but one of the consequences of being a childhood TV addict is that whenever I think of Mother Nature I picture the woman in that old margarine commercial from the 1970s who shouts, "It's Not Nice to Fool Mother Nature!" as the sound of a thunderstorm erupts in the background. I'm thinking if she can get that mad about replacing butter with margarine, surely she has some wrath in store for the men who irresponsibly pillage her resources and then attempt to blame her for their manufactured disasters.
In all seriousness, the First Earth Day in 1970 was sparked by the Santa Barbara oil spill of 1969, the largest spill in US waters at the time. It was the brainchild of former Wisconsin Senator Gaylord Nelson, conceived as a nationwide teach-in on environmental issues. It was a bipartisan initiative, co-chaired by Senator Pete McCloskey. And it was the start of an unprecedented effort to establish an environmental legal and regulatory framework, notably signed into law by archconservative President Nixon.
Today was the 41st anniversary of that first Earth Day, and it was celebrated all over the world. The tweets on #EarthDay were a veritable cascade, scrolling by so fast that I could barely read them and many referenced the disasters listed above.
Hopefully Mother Nature has a Twitter account and will stay her hand as we attempt to expose the real Earth Day conspiracy - that a handful of companies are putting the lives of billions at risk and trading away the future of our beautiful, abundant planet for next quarter's profit report.
Green Earth Day Gulf Oil Spill Fracking


text:
Women's Soccer Wraps Up Road Schedule at Saint Joseph's (Maine) Wednesday
Saint Joseph's (Me.)
Suffolk (9-5-0, 7-4-0) 0 0 0
Saint Joseph's (Me.) (12-2-2, 8-1-1) 2 1 3
1st - 6:41 - Madeline Wood (Saint Joseph's (Me.))
1st - 31:06 - McKenzie Murphy (Saint Joseph's (Me.))
2nd - 48:53 - Ashley Emery (Saint Joseph's (Me.))
Sv: Allison Rodrigues - 15
G: 3 Players (#2, #10, #16) - 1
Sh: 2 Players (#2, #16) - 4
Sv: Adia Grogan - 1
WEDNESDAY, OCT. 23 // 7:00 PM
SJC ATHLETIC COMPLEX // STANDISH, MAINE
LIVE STATS // VIDEO
LAST MEETING // OCT. 6, 2018, L, 2-1
LAST SUFFOLK WIN // SEPT. 22, 2010, W, 6-2
STREAK // L4
BOSTON – Suffolk women's soccer concludes its regular-season road slate with a trip to Saint Joseph's (Maine) Wednesday, Oct. 23. The GNAC kickoff is scheduled for 7 p.m.
HELP THE #RAMSWINTHEDAY OCT. 25
On Support Ram Nation Day your gifts help shape the future of Suffolk Athletics, while having an immediate impact on the experiences of our student-athletes and the quality of their teams.
Join us for Support Ram Nation Day 2019, on Friday, Oct. 25, when thousands of Rams – alumni, students, parents, friends, neighbors, faculty and staff – will come together to give back.
You support the programs and teams that you came most about, so more Rams can win in the classroom, in their sports and beyond Suffolk.
SAVE THE DATE | MORE INFO
BENCH PRESS FOR BREAST CANCER
Members of Ram Nation are asked to pull their weight in an effort to take the load off of those affected by breast cancer in Suffolk Athletics' Bench Press for Breast Cancer event Tuesday, Oct. 29 from 12 p.m. to 1:30 p.m.
For more information or to find out how you can donate, click here.
Suffolk women's soccer scored twice in the first frame and held off the Blue Jays to take a 2-0 win over Saint Joseph (Conn.) Saturday afternoon at USJ Soccer Field.
MORE READING: Women's Soccer Snips USJ, 2-0
With two games remaining on its regular season schedule, Suffolk sits in third place in the GNAC standings with a 7-3-0 league ledger and a 9-4-0 overall mark.
Caleigh O'Brien anchors the Rams' 28-goal offense with team leading numbers in every offensive category with eight goals, five assists for 21 points. Addisyn Lanza, Julia Hunt and Liv Hurley have each found the back of the net four times. Lanza is second on the squad in assists (3a) and points (11), while Hunt is third in points with a pair of assists to her credit.
Allison Rodrigues has been a staple in net for Suffolk. The sophomore boasts an identical 9-4-0 record with a .847 save percentage and a 1.13 GAA.
MONKS MENTIONABLES
Saint Joseph's has not fallen in October and currently rides a seven-game unbeaten streak into the midweek match that put the Monks at 11-2-2 on the year and 7-1-1 against GNAC foes. Of those seven outings, the Monks have kept five opponents off the scoreboard including the last three outings.
SJC's 35-goal offense sees a trio of players with double digit points in McKenzie Murphy (7g, 4a), Ashley Emery (7g, 3a) and Madison Michaud (5g, 3a). Madeline Wood is on the cusp of double figures as well with nine points off three markers and three helpers.
Adia Grogan is the Monks' go-to starter in net. Over 14 appearances, all starts, the goalkeeper has put together a 10-2-2 record behind a .873 save percentage and 0.71 GAA. Cori Balam has also played time between the posts for St. Joe's. In four games played, one start, she assembled a stat line of 1.00 save percentage and 0.00 GAA.
Suffolk looks for its first win over St. Joseph's (Maine) since 2010, as the Rams trail the all-time series, 1-10-2.
The Rams' lone victory came in 2010 in a 6-2 decision.
Suffolk is on a four-game skid versus the Monks including a 2-1 setback a year ago.
There has been on shutout throughout the series. SJC took the cleansheet, 1-0, in 2009.
Suffolk takes the weekend off before concluding the regular season next Wednesday, Oct. 30 against Rivier. Kick-off at James A. Sartori Stadium at East Boston Memorial Park is set for 7 p.m.


I'm not one to tease about physical limitations, or take advantage of someone because of them, but last year I found the perfect moment to capitalize on a friend's frustrations.
I expected him to make a quick change, but by the time I'd landed and released three trout on three casts he was still fiddling with his tippet and flies and calling me a fish hog. That comment may have been meant to deter me from making another cast, but I took it another way: Now I wanted to catch every trout in the pool. I mean, if you are going to be called fish hog, you might as well act the part.
I'm not sure how many fish I landed from that corner — maybe eight or 10, with strikes on nearly every cast — before Randy was rigged up and ready to fish. By that time I'd made four straight casts without a strike so I smiled and said, "It's all yours." Randy made a few casts, but the truth was evident: I'd caught every willing fish in that pool and there wasn't another one to be had.
Ah, makes sense now. The close range dilemma. The scourge of 40-some-year-olds. The demise of the dry-fly aficionado. I saw this happen to my father in his late 40s on Rock Creek, and I went through the same frustration — while trying to tie on a tiny Trico mayfly imitation — when fishing the Bitterroot River two years ago. In my case, I finally gave up and decided to fish a size 4 streamer in the middle of a mayfly hatch because the eye on that fly looked like a basketball hoop compared to the opening on that Trico.
So be it. It's one of those givens and there's nothing any of us can do about it. When the hook eye went blurry on me I just thought, OK, time is a factor now. What do you really want to do?
The easy answer is to fish more, the sooner the better. For me, that means more trips into Idaho's forested panhandle region, which includes the St. Joe, Clearwater, Nez Perce, and Bitterroot national forests. These forests, which roll off the west slope of the Bitterroot Mountains between Missoula and Coeur d' Alene, Idaho, offer amazing public fishing and camping access. Some great spots are located beside roads. Many others are off the beaten path and accessible only to those who trek in. This is also one of the last bastions of the West's native fishes, including the westslope cutthroat and the bull trout.
All of these Idaho streams follow a steep gradient off the Bitterroot Mountains. They are susceptible to runoff, and in big snow years they roll down steep, mountainous valleys at an alarming rate. If you are going to fish these streams, a rule of thumb is to show up no earlier than July 4. After that date the flows quickly diminish and anglers can safely move up and down the rocky banks.
That timeframe coincides with the green drake hatch. When conditions are favorable and that bug comes off, the cutthroats throw caution aside and eat as many drakes as possible. They have to; during spring and early summer, the fish spend most of their lives just trying to find a safe place to rest in high flows; during winter, they move far downstream to broader and calmer water where they manage to find just enough food to survive. So during summer and fall, these fish feed voraciously, making up for the challenging conditions they've just been through. Detractors call these westslope cutthroats stupid. I like to think of them as survivors, each one a yellowish-olive jewel.
Westslope cutthroats are amazingly colorful fish, with olive backs punctuated by dozens of inky-black dots. Their sides are a vibrant golden-yellow, and at times many have flush pink bellies. Their eyes are bright yellow with oversized black pupils. Holding one in the hand is like examining the perfect pastel.
I, too, like to fish these Idaho rivers as runoff subsides in July, but my favorite time is August when the woods are laden with huckleberries. Some years these berries may take you away from your fishing. They taste great, and are great for you. When ripe and at peak flavor, it's almost impossible not to spend a portion of the day plucking them off the limbs and palming them into your mouth. Sometimes you might find a cutthroat resting just under a limb laden with huckleberries, and draw it into the open with a perfect cast. As you might imagine, this scenario — with hungry cutthroats in the rivers, millions of huckleberries waiting to be picked in the cedar and pine forests, and beautiful campsites in spades — is perfect for kids. Think about it: trout fishing and huck picking by day, campfires, s'mores, and an array of dazzling stars overhead at night. Isn't that the description of a lifetime memory?
Summer isn't the only time to fish Idaho. During the fall, these rivers get great blue-wing olive and October caddis hatches. October caddis are nearly as large as Montana's heralded salmonfly and they bring fish to the top in droves. The olives, which come off in the afternoon hours, also bring scads of fish to the surface. Once, while fishing Kelly Creek — Idaho's first designated catch-and-release-only stream — a friend coaxed trout to rise to his olive imitation on 20-some straight casts … but was never able to hook one. Small flies. Wary, late-season trout. And maybe some vision issues on the horizon.
Idaho's westslope cutthroats are fun to catch, and in fly fishing there may be no greater thrill than taking a fish on a dry fly. But I'm just as inclined to fish these rivers for bull trout, which is legal to do in Idaho. In Montana, there are only a couple places to legally fish bulls, even though many anglers specifically target them on restricted waters. That's not for me. I like fishing with a clean conscience, and in Idaho I can do that for bulls.
You'll find bulls in these rivers from spring through fall, but they seem to be most abundant in August and September. You don't need to search all the water for them — these fish stack up in the deepest pools. To catch them you'll need to get a fly in front of them. Because bull trout feed almost entirely on other fish, you'll want to use a weighted streamer that mimics a baitfish and gets deep. There are exceptions: I once caught a 5-pound bull trout while fishing a cicada pattern for Idaho's cutthroats.
With all that Idaho offers, I wonder why more Montanans don't hit these streams when the fishing can be as entertaining as what we find within our own borders. Many of us can easily fish one or more of these cutthroat streams within a two hour drive. To fish Montana's Big Hole, Beaverhead, Madison, Bighorn, and Missouri rivers — which many of us do without hesitation each year — often requires longer travel. Do some people shy away from these streams due to the additional out-of-state license cost? If so, the next time you hold off on Idaho because it might cost you 60-some dollars for the annual out-of-state fee, consider what you might pay for a single round of golf and what you (and your kids) might be missing, just over the Bitterroot divide.


text:
function gradeMean(assignment, type, section) {
   // Check if assignment exists
   if ($.type(section.assignmentInfo[type][assignment]) == "undefined") {
      return -1;
      //throw new Error("Assignment " + assignment + " is undefined.");
   };

   var grades = getGrades(assignment, type, section);

   return getMean(grades);
};

// Calculates grade median for a particular assignment
// params: assignment - name of column to calculate from
//            section - class section object
// assert: section conforms to project standard
// return: number - median grade for a particular column, or -1 if invalid
function gradeMedian(assignment, type, section) {
   // Check if assignment exists
   if ($.type(section.assignmentInfo[type][assignment]) == "undefined") {
      return -1;
      //throw new Error("Assignment " + assignment + " is undefined.");
   };

   var grades = getGrades(assignment, type, section);

   return getMedian(grades);
};

// Calculates grade range for a particular assignment
// params: assignment - name of column to calculate from
//            section - class section object
// assert: section conforms to project standard
// return:   number - grade range for a particular column, or -1 if invalid
function gradeRange(assignment, type, section) {
   // Check if assignment exists
   if ($.type(section.assignmentInfo[type][assignment]) == "undefined") {
      return -1;
      //throw new Error("Assignment " + assignment + " is undefined.");
   };

   var grades = getGrades(assignment, type, section);
   return getRange(grades);
};

// Calculates grade mean for the whole class
// params: section - class section object
// assert: section conforms to project standard
// return:  number - mean grade for a particular column, or -1 if invalid
function classMean(section) {
   var grades = getTotalGrades(section);
   return getMean(grades);
};

// Calculates grade median for the whole class
// params: section - class section object
// assert: section conforms to project standard
// return:  number - median grade for a particular column, or -1 if invalid
function classMedian(section) {
   var grades = getTotalGrades(section);
   return getMedian(grades);
};

// Calculates grade range for the whole class
// params: section - class section object
// assert: section conforms to project standard
// return:   number - median grade for a particular column, or -1 if invalid
function classRange(section) {
   var grades = getTotalGrades(section);
   return getRange(grades);
};

// Returns the mean of an array of numbers
// params: nums - array of numbers
// assert: each element of nums is >= 0
// return: number - mean of given array, or -1 if invalid
function getMean(nums) {
	var numsCopy = nums.slice(0);
	var sum = 0;

	for (var i in numsCopy) sum += numsCopy[i];

	return (containsValidGrades(nums)) ? sum / numsCopy.length : -1;
};

// Returns the median of an array of numbers
// params: nums - array of numbers
// assert: each element of nums is >= 0
// return: number - median of the given array, or -1 if invalid
function getMedian(nums) {
   // Get a copy of nums: (if there's a bettery way, I'd love to know)
   var numsCopy = nums.slice(0);
   var median;

   // Check for negatives and non-numbers
   if (!containsValidGrades(numsCopy)) return -1;

   // Ascending numerical sort:
   numsCopy.sort(function(a,b){ return a-b; });

   // If array has even number of elements, median is avg of two middle elements
   if (numsCopy.length %2 == 0) {
      var midHi = numsCopy[Math.ceil((numsCopy.length-1)/2)];
      var midLo = numsCopy[Math.floor((numsCopy.length-1)/2)];
      median = (midHi + midLo) / 2;
   }
   // Else, if array has odd number of elements, median is middle element
   else { median = numsCopy[Math.floor(numsCopy.length / 2)]; };

   return median;
};

// Returns the range of an array of numbers
// params: nums - array of numbers
// assert: each element of nums is >= 0
// return: number - range of the given array, or -1 if invalid
function getRange(nums) {
   // Get a copy of nums: (if there's a bettery way, I'd love to know)
   var numsCopy = nums.slice(0);

   // Check for negatives and non-numbers
   if (!containsValidGrades(numsCopy)) return -1;

   // Ascending numerical sort:
   numsCopy.sort(function(a,b){ return a-b; });
   var last = numsCopy.length - 1;

   return numsCopy[last] - numsCopy[0];
};

// Returns true if the array contains only valid grades, otherwise false
// params: nums - array of numbers
// return: true if array is only valid grades, otherwise false
//         A valid grade is of type "number" and is >= 0, or is null.
function containsValidGrades(nums) {
   var isValid = true;

   for (var i in nums)
   	isValid = (isValid && isValidGrade(nums[i]));

   return isValid;
};

// Returns true if num is of type "number" and is >= 0 or is "null" type
// params: num - a number
// return: true if num is a valid grade or null, otherwise false
//         A valid grade is of type "number" and is >= 0, or is null.
function isValidGrade(num) {
	return (($.type(num) == "number" && num >= 0)
	      || $.type(num) == "null");
};

// Calculates and returns total grade of given student, otherwise -1 if invalid
// params: student - the repo name for whom to generate a letter grade
//			  section - the section the above student resides
// return: final grade of given student if it is valid, otherwise -1
function getTotalGrade(student, section) {
	var scores = section.students[student].scores;
	var totalGrade = 0;

	var earned = 0;
	var possible = 0;
	var nullWeights = [];
	for (var type in scores) {
		for (var assignment in scores[type]) {
			var assignmentInfo = section.assignmentInfo[type][assignment];
			if (!isValidGrade(scores[type][assignment])) { return -1; }
         else if ($.type(scores[type][assignment]) == "null") {
         	nullWeights.push(assignmentInfo.weight);
         }
         else {
			   earned = scores[type][assignment];
			   possible = assignmentInfo.max;
			   totalGrade += (earned / possible) * assignmentInfo.weight;
			}
		};
	};

	// Factor exempt/ungraded assignments into total
	var ungradedFactor = 0;
	for (var i in nullWeights) ungradedFactor += totalGrade * nullWeights[i];

	// Convert to %
   totalGrade = (totalGrade + ungradedFactor) * 100;

   // dirty rounding to 2 decimal places
   totalGrade = Math.round(totalGrade * 100) / 100;

	return (isValidGrade(totalGrade)) ? totalGrade : -1;
};

// Returns letter grade of the given student, otherwise -1 if invalid
// params: student - the repo name for whom to generate a letter grade
//			  section - the section the above student resides
// return: letter grade of given student if final grade is valid, otherwise -1
function getLetterGrade(student, section) {
	var totalGrade = section.students[student].totalGrade;

	if (isValidGrade(totalGrade)) {
      if ($.type(totalGrade) == "null") return totalGrade;
		for (letter in section.cutoffs) {
			if (totalGrade >= section.cutoffs[letter])
				return letter;
		};
		// else (if totalGrade is valid)
		return "F";
	};

	// else (if finalGrade is invalid)
	return -1;
};

// Returns total grade for every student in the given section
// params: section - The section to get total grades from
// return: an array of total grades
function getTotalGrades(section) {
   var grades = [];
   var grade;
   for (var repo in section.students) {
      grade = section.students[repo].totalGrade;
      if ($.type(grade) != "null") grades.push(grade);
   };

   return grades;
};

// Returns every students' grade for a particular assignment
// params: assignment - the assignment of the desired grade
//         type - the type of assignment
//         section - the section object containing students and their grades
function getGrades(assignment, type, section) {
   var grades = [];
   var grade;
   for (var repo in section.students) {
      grade = section.students[repo].scores[type][assignment];
      if ($.type(grade) != "null") grades.push(grade);
   };

   return grades;
};

// Returns true on valid stats addition, otherwise false
// params: section - class section object
// assert: section conforms to project standard
// return: true if valid stats were added, otherwise false
function addClassStats(section) {
	section.classStats = {
		averageGrade: classMean(section),
		medianGrade:  classMedian(section),
		gradeRange:   classRange(section)
	};

	if (section.classStats.averageGrade == -1
	 || section.classStats.medianGrade  == -1
	 || section.classStats.gradeRange	== -1)
	 	return false;
	// else
	return true;
};

// Returns true on successful student stats addition, otherwise false
// params: student - the student to add stats for
//			  section - class section object
// assert: section conforms to project standard
// return: true if stats were added, otherwise false
function addTotalAndLetterGrades(student, section) {
	section.students[student].totalGrade = getTotalGrade(student, section);
	section.students[student].letterGrade = getLetterGrade(student, section);

	if (section.students[student].totalGrade ==  -1
	 || section.students[student].letterGrade == -1)
	 	return false;
	// else
	return true;
};


Welcome to The Subulate Palpomere, a blog about beetles, beetle diversity and evolution, and the Tree of Life. It is written or edited by David Maddison. It includes posts about my efforts and my lab's efforts to discover and document biodiversity, including new species of beetles from around the world. On occasion it also covers other things that relate to this: cool beetles, how-to guides to studying beetles, programming and software for studying evolutionary trees, scientific illustration, field work, and the life of an academic.
As to why it is called The Subulate Palpomere: there is a particularly cool group of beetles, the genus Bembidion and its relatives, that have subulate palpomeres, and I have loved these beetles for almost 40 years. Beetles have appendages around their mouth called "palps" that are like little feelers – the beetles use palps to handle their food, and to taste their food. A palp is made of several pieces, and each piece is called a "palpomere". Bembidion and its relatives are unusual in that the palpomere at the end of the palps (the last palpomere) is thin and tapered – and the word used in entomology to describe such a thin and tapered palpomere is "subulate" (see picture, below).
I just found your blog and have to say that I'm quite enjoying it. Your post on drawing beetles is very interesting.
If inspiration strikes, would you be willing to write a post on identifying beetles? I've got American Beetles Vol. 1 and 2, but don't get much use out of them because I tend to get lost in the lingo!
I'd be happy to write a post about identifying beetles – but how you do it depends upon the group of beetles. I could easily write one for Bembidion, for example, but that would be a very different post than writing one for all of beetles. Where do you tend to get lost?
Carabids and cerambycids are the tough ones for me.
Awesome blog ! The beauty of patterns on some of those beetles is very inspiring.
I was wondering while looking at pictures of some elytron what function the patterns have. Do the bumps, ridges, and striations have a structural function that helps stiffen the elytra?
Some of them features are thought to stiffen the elytra. Some aspects (e.g., the microsculpture) have functions that to some extent can likely be understood (e.g., the rougher microsculpture of females may allow the males to hold on more readily), but surely there are functions we don't yet understand.


text:
// Copyright 2016 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "src/js/xml_http_request.h"

#include <algorithm>
#include <cctype>
#include <cerrno>
#include <cstring>
#include <stdexcept>
#include <utility>

#include "src/core/environment.h"
#include "src/core/js_manager_impl.h"
#include "src/js/events/event.h"
#include "src/js/events/event_names.h"
#include "src/js/events/progress_event.h"
#include "src/js/js_error.h"
#include "src/js/navigator.h"
#include "src/js/timeouts.h"
#include "src/memory/heap_tracer.h"
#include "src/util/clock.h"
#include "src/util/utils.h"

namespace shaka {
namespace js {

namespace {

/** The minimum delay, in milliseconds, between "progress" events. */
constexpr size_t kProgressInterval = 15;

constexpr const char* kCookieFileName = "net_cookies.dat";

size_t UploadCallback(void* buffer, size_t member_size, size_t member_count,
                      void* user_data) {
  auto* request = reinterpret_cast<XMLHttpRequest*>(user_data);
  auto* buffer_bytes = reinterpret_cast<uint8_t*>(buffer);
  size_t total_size = member_size * member_count;
  return request->OnUpload(buffer_bytes, total_size);
}

size_t DownloadCallback(void* buffer, size_t member_size, size_t member_count,
                        void* user_data) {
  auto* request = reinterpret_cast<XMLHttpRequest*>(user_data);
  auto* buffer_bytes = reinterpret_cast<uint8_t*>(buffer);
  size_t total_size = member_size * member_count;
  request->OnDataReceived(buffer_bytes, total_size);
  return total_size;
}

size_t HeaderCallback(char* buffer, size_t member_size, size_t member_count,
                      void* user_data) {
  auto* request = reinterpret_cast<XMLHttpRequest*>(user_data);
  auto* buffer_bytes = reinterpret_cast<uint8_t*>(buffer);
  size_t total_size = member_size * member_count;
  request->OnHeaderReceived(buffer_bytes, total_size);
  return total_size;
}

double CurrentDownloadSize(CURL* curl) {
  double ret;
  CHECK_EQ(CURLE_OK, curl_easy_getinfo(curl, CURLINFO_SIZE_DOWNLOAD, &ret));
  return ret;
}

/**
 * Parses the status line of the request.  This will extract the status code
 * and message.
 * @param buffer The input buffer containing the status line.
 * @param length The length of the buffer.
 * @param code [OUT] Where to put the status code.
 * @param message [OUT] Where to put the pointer to the start of the message.
 *   It will be a pointer within |buffer|.  Namely
 *   |buffer| <= |*message| < |buffer + length|.
 * @param message_length [OUT] Where to put the length of the message.
 * @return True on success, false on error.
 */
bool ParseStatusLine(const char* buffer, size_t length, int* code,
                     const char** message, size_t* message_length) {
  // NOTE: curl will convert the status line of http2 to match http1.1.
  // e.g.: "HTTP/1.1 200 OK\r\n"
  constexpr const char kMinStatusLine[] = "HTTP/1.1 200 \r\n";
  constexpr const char kHttp10[] = "HTTP/1.0 ";
  constexpr const char kHttp11[] = "HTTP/1.1 ";
  constexpr const size_t kMinStatusSize = sizeof(kMinStatusLine) - 1;
  constexpr const size_t kHttp10Size = sizeof(kHttp10) - 1;
  constexpr const size_t kHttp11Size = sizeof(kHttp11) - 1;
  constexpr const size_t kStatusSize = 3;

  if (length < kMinStatusSize)
    return false;
  if (strncmp(buffer, kHttp10, kHttp10Size) != 0 &&
      strncmp(buffer, kHttp11, kHttp11Size) != 0)
    return false;

  // Convert the status code, must be three numbers [0-9].
  const char* status_code = buffer + kHttp10Size;
  const char* status_code_end = status_code + kStatusSize;
  if (!std::isdigit(status_code[0]) || !std::isdigit(status_code[1]) ||
      !std::isdigit(status_code[2])) {
    return false;
  }
  if (status_code_end[0] != ' ')
    return false;
  if (buffer[length - 2] != '\r' || buffer[length - 1] != '\n')
    return false;

  *code = std::stoi(std::string(status_code, status_code_end));
  *message = status_code_end + 1;
  *message_length = length - kMinStatusSize;
  return true;
}

}  // namespace

XMLHttpRequest::XMLHttpRequest()
    : ready_state(XMLHttpRequest::ReadyState::Unsent),
      mutex_("XMLHttpRequest"),
      curl_(curl_easy_init()),
      request_headers_(nullptr),
      with_credentials_(false) {
  AddListenerField(EventType::Abort, &on_abort);
  AddListenerField(EventType::Error, &on_error);
  AddListenerField(EventType::Load, &on_load);
  AddListenerField(EventType::LoadStart, &on_load_start);
  AddListenerField(EventType::Progress, &on_progress);
  AddListenerField(EventType::ReadyStateChange, &on_ready_state_change);
  AddListenerField(EventType::Timeout, &on_timeout);
  AddListenerField(EventType::LoadEnd, &on_load_end);

  Reset();
}

// \cond Doxygen_Skip
XMLHttpRequest::~XMLHttpRequest() {
  // Don't call Abort() since we can't raise events.
  abort_pending_ = true;
  JsManagerImpl::Instance()->NetworkThread()->AbortRequest(this);

  curl_easy_cleanup(curl_);
  if (request_headers_)
    curl_slist_free_all(request_headers_);
  request_headers_ = nullptr;
}
// \endcond Doxygen_Skip

void XMLHttpRequest::Trace(memory::HeapTracer* tracer) const {
  // No need to trace on_* members as EventTarget handles it.
  EventTarget::Trace(tracer);
  std::unique_lock<Mutex> lock(mutex_);
  tracer->Trace(&response);
  tracer->Trace(&upload_data_);
}

bool XMLHttpRequest::IsShortLived() const {
  return true;
}

void XMLHttpRequest::Abort() {
  if (!JsManagerImpl::Instance()->NetworkThread()->ContainsRequest(this))
    return;

  abort_pending_ = true;
  JsManagerImpl::Instance()->NetworkThread()->AbortRequest(this);

  std::unique_lock<Mutex> lock(mutex_);
  if (ready_state != XMLHttpRequest::ReadyState::Done) {
    // Fire events synchronously.
    ready_state = XMLHttpRequest::ReadyState::Done;
    RaiseEvent<events::Event>(EventType::ReadyStateChange);

    double total_size = CurrentDownloadSize(curl_);
    RaiseEvent<events::ProgressEvent>(EventType::Progress, true, total_size,
                                      total_size);
    RaiseEvent<events::Event>(EventType::Abort);
    RaiseEvent<events::ProgressEvent>(EventType::LoadEnd, true, total_size,
                                      total_size);
  }

  // The spec says at the end to change the ready state without firing an event.
  // https://xhr.spec.whatwg.org/#the-abort()-method
  ready_state = XMLHttpRequest::ReadyState::Unsent;
}

std::string XMLHttpRequest::GetAllResponseHeaders() const {
  std::unique_lock<Mutex> lock(mutex_);
  std::string ret;
  for (auto it : response_headers_) {
    ret.append(it.first + ": " + it.second + "\r\n");
  }
  return ret;
}

shaka::optional<std::string> XMLHttpRequest::GetResponseHeader(
    const std::string& name) const {
  std::unique_lock<Mutex> lock(mutex_);
  auto it = response_headers_.find(name);
  if (it == response_headers_.end())
    return nullopt;
  return it->second;
}

ExceptionOr<void> XMLHttpRequest::Open(const std::string& method,
                                       const std::string& url,
                                       optional<bool> async,
                                       optional<std::string> user,
                                       optional<std::string> password) {
  if (async.has_value() && !async.value()) {
    return JsError::DOMException(NotSupportedError,
                                 "Synchronous requests are not supported.");
  }

  // This will call Abort() which may call back into JavaScript by firing
  // events synchronously.
  Reset();

  std::unique_lock<Mutex> lock(mutex_);
  this->ready_state = XMLHttpRequest::ReadyState::Opened;
  ScheduleEvent<events::Event>(EventType::ReadyStateChange);

  curl_easy_setopt(curl_, CURLOPT_URL, url.c_str());
  curl_easy_setopt(curl_, CURLOPT_CUSTOMREQUEST, method.c_str());
  if (method == "HEAD")
    curl_easy_setopt(curl_, CURLOPT_NOBODY, 1L);

  if (user.has_value())
    curl_easy_setopt(curl_, CURLOPT_USERNAME, user->c_str());
  if (password.has_value())
    curl_easy_setopt(curl_, CURLOPT_PASSWORD, password->c_str());

  return {};
}

ExceptionOr<void> XMLHttpRequest::Send(
    optional<variant<ByteBuffer, ByteString>> maybe_data) {
  // Don't query while locked to avoid a deadlock.
  const bool contains_request =
      JsManagerImpl::Instance()->NetworkThread()->ContainsRequest(this);

  {
    std::unique_lock<Mutex> lock(mutex_);
    // If we are not open, or if the request has already been sent.
    if (ready_state != XMLHttpRequest::ReadyState::Opened || contains_request) {
      return JsError::DOMException(InvalidStateError,
                                   "The object's state must be OPENED.");
    }
    if (response_type != "arraybuffer") {
      return JsError::DOMException(
          NotSupportedError,
          "Response type " + response_type + " is not supported");
    }

    if (maybe_data.has_value()) {
      if (holds_alternative<ByteBuffer>(*maybe_data)) {
        upload_data_ = std::move(get<ByteBuffer>(*maybe_data));
      } else {
        ByteString* str = &get<ByteString>(*maybe_data);
        upload_data_.SetFromBuffer(str->data(), str->size());
      }

      upload_pos_ = 0;
      curl_easy_setopt(curl_, CURLOPT_UPLOAD, 1L);
      curl_easy_setopt(curl_, CURLOPT_INFILESIZE_LARGE,
                       static_cast<curl_off_t>(upload_data_.size()));
      curl_easy_setopt(curl_, CURLOPT_READDATA, this);
      curl_easy_setopt(curl_, CURLOPT_READFUNCTION, UploadCallback);
    } else {
      curl_easy_setopt(curl_, CURLOPT_UPLOAD, 0L);
    }

    curl_easy_setopt(curl_, CURLOPT_TIMEOUT_MS,
                     static_cast<long>(timeout_ms));  // NOLINT
    curl_easy_setopt(curl_, CURLOPT_HTTPHEADER, request_headers_);
  }

  // Don't add while locked to avoid a deadlock.
  JsManagerImpl::Instance()->NetworkThread()->AddRequest(this);
  return {};
}

ExceptionOr<void> XMLHttpRequest::SetRequestHeader(const std::string& key,
                                                   const std::string& value) {
  std::unique_lock<Mutex> lock(mutex_);
  if (ready_state != XMLHttpRequest::ReadyState::Opened) {
    return JsError::DOMException(InvalidStateError,
                                 "The object's state must be OPENED.");
  }
  const std::string header = key + ": " + value;
  request_headers_ = curl_slist_append(request_headers_, header.c_str());
  return {};
}

bool XMLHttpRequest::WithCredentials() const {
  return with_credentials_;
}

ExceptionOr<void> XMLHttpRequest::SetWithCredentials(bool with_credentials) {
  if (ready_state != XMLHttpRequest::ReadyState::Unsent &&
      ready_state != XMLHttpRequest::ReadyState::Opened) {
    return JsError::DOMException(
        InvalidStateError,
        "withCredentials can only be set if the object's state is UNSENT or "
        "OPENED.");
  }
  with_credentials_ = with_credentials;
  return {};
}

void XMLHttpRequest::RaiseProgressEvents() {
  if (abort_pending_)
    return;

  if (ready_state == XMLHttpRequest::ReadyState::Opened) {
    this->ready_state = XMLHttpRequest::ReadyState::HeadersReceived;
    RaiseEvent<events::Event>(EventType::ReadyStateChange);
  }
  if (ready_state != XMLHttpRequest::ReadyState::Loading) {
    this->ready_state = XMLHttpRequest::ReadyState::Loading;
    RaiseEvent<events::Event>(EventType::ReadyStateChange);
  }

  double cur_size;
  {
    std::unique_lock<Mutex> lock(mutex_);
    cur_size = CurrentDownloadSize(curl_);
  }
  RaiseEvent<events::ProgressEvent>(EventType::Progress, estimated_size_ != 0,
                                    cur_size, estimated_size_);
}

void XMLHttpRequest::OnDataReceived(uint8_t* buffer, size_t length) {
  std::unique_lock<Mutex> lock(mutex_);

  // We need to schedule these events from this callback since we don't know
  // when the last header will be received.
  const uint64_t now = util::Clock::Instance.GetMonotonicTime();
  if (!abort_pending_ && now - last_progress_time_ >= kProgressInterval) {
    last_progress_time_ = now;

    RefPtr<XMLHttpRequest> req(this);
    JsManagerImpl::Instance()->MainThread()->AddInternalTask(
        TaskPriority::Internal, "Schedule XHR events",
        std::bind(&XMLHttpRequest::RaiseProgressEvents, req));
  }

  temp_data_.AppendCopy(buffer, length);
}

void XMLHttpRequest::OnHeaderReceived(const uint8_t* buffer, size_t length) {
  std::unique_lock<Mutex> lock(mutex_);
  // This method is called for each header (including status line) for the
  // duration of the request, this includes redirects.
  // https://curl.haxx.se/libcurl/c/CURLOPT_HEADERFUNCTION.html
  //
  // Be careful about using string methods.  This data may not be null-
  // terminated.  Be sure to use the |length| parameter and always pass the
  // explicit end to std::string.
  auto* str = reinterpret_cast<const char*>(buffer);
  if (!parsing_headers_) {
    const char* message;
    size_t message_size;
    if (!ParseStatusLine(str, length, &status, &message, &message_size))
      return;
    status_text.assign(message, message + message_size);

    parsing_headers_ = true;
    // Clear headers from the previous request.  This is important for
    // redirects so we don't keep headers from the redirect.
    response_headers_.clear();
  } else {
    // 'Content-Length: 123\r\n'
    const char* sep = std::find(str, str + length, ':');
    // |sep == str + length| if not found.
    const size_t key_len = sep - str;
    const size_t rest_len = length - key_len;  // == 0 if not found.
    if (rest_len >= 2 && sep[rest_len - 2] == '\r' &&
        sep[rest_len - 1] == '\n') {
      std::string key = util::ToAsciiLower(std::string(str, sep));
      std::string value =
          util::TrimAsciiWhitespace(std::string(sep + 1, sep + rest_len - 1));

      if (response_headers_.count(key) == 0)
        response_headers_[key] = value;
      else
        response_headers_[key] += ", " + value;

      // Parse content-length so we can get the size of the download.
      if (key == "content-length") {
        errno = 0;  // |errno| is thread_local.
        char* end;
        const auto size = strtol(value.c_str(), &end, 10);
        if (errno != ERANGE && end == value.c_str() + value.size()) {
          estimated_size_ = size;
        }
      }
    }
    // Ignore invalid headers.
  }
  if (length == 2 && str[0] == '\r' && str[1] == '\n') {
    // An empty header signals the end of the headers for the current request.
    // If there is a redirect or the XMLHttpRequest object is used to make
    // another request then we should parse the status line.
    parsing_headers_ = false;
  }
}

size_t XMLHttpRequest::OnUpload(uint8_t* buffer, size_t length) {
  std::unique_lock<Mutex> lock(mutex_);
  const size_t remaining = upload_data_.size() - upload_pos_;
  if (length > remaining)
    length = remaining;
  std::memcpy(buffer, upload_data_.data() + upload_pos_, length);
  upload_pos_ += length;
  return length;
}

void XMLHttpRequest::Reset() {
  Abort();
  response.Clear();
  response_text = "";
  response_type = "arraybuffer";
  response_url = "";
  status = 0;
  status_text = "";
  timeout_ms = 0;

  last_progress_time_ = 0;
  estimated_size_ = 0;
  parsing_headers_ = false;
  abort_pending_ = false;

  response_headers_.clear();
  temp_data_.Clear();
  upload_data_.Clear();

  curl_easy_reset(curl_);
  curl_easy_setopt(curl_, CURLOPT_WRITEFUNCTION, DownloadCallback);
  curl_easy_setopt(curl_, CURLOPT_WRITEDATA, this);
  curl_easy_setopt(curl_, CURLOPT_HEADERFUNCTION, HeaderCallback);
  curl_easy_setopt(curl_, CURLOPT_HEADERDATA, this);
  curl_easy_setopt(curl_, CURLOPT_FOLLOWLOCATION, 1L);
  curl_easy_setopt(curl_, CURLOPT_USERAGENT, USER_AGENT);

  const std::string cookie_file =
      JsManagerImpl::Instance()->GetPathForDynamicFile(kCookieFileName);
  curl_easy_setopt(curl_, CURLOPT_COOKIEFILE, cookie_file.c_str());
  curl_easy_setopt(curl_, CURLOPT_COOKIEJAR, cookie_file.c_str());

  // Don't batch up TCP packets.
  curl_easy_setopt(curl_, CURLOPT_TCP_NODELAY, 1L);
  // Don't wait for a 100 Continue for uploads.
  curl_easy_setopt(curl_, CURLOPT_EXPECT_100_TIMEOUT_MS, 1L);

  if (request_headers_)
    curl_slist_free_all(request_headers_);
  request_headers_ = nullptr;
}

void XMLHttpRequest::OnRequestComplete(CURLcode code) {
  // Careful, this is called from the worker thread, so we cannot call into V8.
  std::unique_lock<Mutex> lock(mutex_);

#ifdef OS_IOS
  // HACK: On some requests, iOS returns an abort error at the end of the
  // request.  This error usually happens during the SSL handshake, but this
  // case is after we have received the whole response.  If we get this error
  // at the end of the request, just ignore it.
  if (status != 0 && code == CURLE_RECV_ERROR) {
    curl_off_t len;
    const auto res =
        curl_easy_getinfo(curl_, CURLINFO_CONTENT_LENGTH_DOWNLOAD_T, &len);
    if (res == 0) {
      if (len < 0 && temp_data_.Size() > 0) {
        // We don't know when the request ends; assume we have everything so
        // long as we have seen the headers and gotten some data back.  This
        // could mask a real network abort, but we'll probably get errors
        // later in that case.
        LOG(WARNING) << "Ignoring CURLE_RECV_ERROR due to possible iOS bug.  "
                        "We can't tell if the request was aborted due to lack "
                        "of Content-Length header.";
        code = CURLE_OK;
      } else if (len > 0 && temp_data_.Size() == static_cast<size_t>(len)) {
        // Since we have the Content-Length header, we know when we have
        // received all the data.  Only ignore when we have received everything.
        VLOG(1) << "Ignoring CURLE_RECV_ERROR due to possible iOS bug.";
        code = CURLE_OK;
      }
    }
  }
#endif

  if (code == CURLE_OK) {
    response_text = temp_data_.CreateString();
    response.SetFromDynamicBuffer(temp_data_);
    temp_data_.Clear();

    char* url;
    curl_easy_getinfo(curl_, CURLINFO_EFFECTIVE_URL, &url);
    response_url = url;

    // Flush cookie list to disk so other instances can access them.
    curl_easy_setopt(curl_, CURLOPT_COOKIELIST, "FLUSH");
  } else {
    // Don't need to reset everything on error because it was reset in Send().
    // But we do need to set these as they are set in OnHeaderReceived.
    status = 0;
    status_text = "";
  }

  // Don't schedule events if we are aborted, they will be called within
  // Abort().
  if (!abort_pending_) {
    this->ready_state = XMLHttpRequest::ReadyState::Done;
    ScheduleEvent<events::Event>(EventType::ReadyStateChange);

    double total_size = CurrentDownloadSize(curl_);
    ScheduleEvent<events::ProgressEvent>(EventType::Progress, true, total_size,
                                         total_size);
    switch (code) {
      case CURLE_OK:
        ScheduleEvent<events::Event>(EventType::Load);
        break;
      case CURLE_OPERATION_TIMEDOUT:
        ScheduleEvent<events::Event>(EventType::Timeout);
        break;
      default:
        LOG(ERROR) << "Error returned by curl: " << code;
        ScheduleEvent<events::Event>(EventType::Error);
        break;
    }
    ScheduleEvent<events::ProgressEvent>(EventType::LoadEnd, true, total_size,
                                         total_size);
  }
}

XMLHttpRequestFactory::XMLHttpRequestFactory() {
  AddConstant("UNSENT", XMLHttpRequest::ReadyState::Unsent);
  AddConstant("OPENED", XMLHttpRequest::ReadyState::Opened);
  AddConstant("HEADERS_RECEIVED", XMLHttpRequest::ReadyState::HeadersReceived);
  AddConstant("LOADING", XMLHttpRequest::ReadyState::Loading);
  AddConstant("DONE", XMLHttpRequest::ReadyState::Done);

  AddReadOnlyProperty("readyState", &XMLHttpRequest::ready_state);
  AddReadOnlyProperty("response", &XMLHttpRequest::response);
  AddReadOnlyProperty("responseText", &XMLHttpRequest::response_text);
  AddReadWriteProperty("responseType", &XMLHttpRequest::response_type);
  AddReadOnlyProperty("responseURL", &XMLHttpRequest::response_url);
  AddReadOnlyProperty("status", &XMLHttpRequest::status);
  AddReadOnlyProperty("statusText", &XMLHttpRequest::status_text);
  AddReadWriteProperty("timeout", &XMLHttpRequest::timeout_ms);
  AddGenericProperty("withCredentials", &XMLHttpRequest::WithCredentials,
                     &XMLHttpRequest::SetWithCredentials);

  AddListenerField(EventType::Abort, &XMLHttpRequest::on_abort);
  AddListenerField(EventType::Error, &XMLHttpRequest::on_error);
  AddListenerField(EventType::Load, &XMLHttpRequest::on_load);
  AddListenerField(EventType::LoadStart, &XMLHttpRequest::on_load_start);
  AddListenerField(EventType::Progress, &XMLHttpRequest::on_progress);
  AddListenerField(EventType::ReadyStateChange,
                   &XMLHttpRequest::on_ready_state_change);
  AddListenerField(EventType::Timeout, &XMLHttpRequest::on_timeout);
  AddListenerField(EventType::LoadEnd, &XMLHttpRequest::on_load_end);

  AddMemberFunction("abort", &XMLHttpRequest::Abort);
  AddMemberFunction("getAllResponseHeaders",
                    &XMLHttpRequest::GetAllResponseHeaders);
  AddMemberFunction("getResponseHeader", &XMLHttpRequest::GetResponseHeader);
  AddMemberFunction("open", &XMLHttpRequest::Open);
  AddMemberFunction("send", &XMLHttpRequest::Send);
  AddMemberFunction("setRequestHeader", &XMLHttpRequest::SetRequestHeader);
}

}  // namespace js
}  // namespace shaka


text:
Beside a Giant
Saturn's largest moon, Titan, looks small seen to the right of the gas giant in this Cassini view.
Titan (3200 miles, 5150 kilometers across) is in the upper right. Saturn's rings appear across the top of the image, and they cast a series of shadows onto the planet across the middle of the image.
The moon Prometheus (53 miles, 86 kilometers across) appears as a tiny speck above the rings in the far upper right of the image. The shadow cast by Prometheus can be seen as a small black speck on the planet on the far left of the image, between the shadows cast by the main rings and the thin F ring. The shadow of the moon Pandora also can be seen on the planet south of the shadows of all the rings, below the center of the image. Pandora is not shown here.
This view looks toward the southern, unilluminated side of the rings from about 1 degree below the ringplane.
The image was taken with the Cassini spacecraft wide-angle camera on Jan. 5, 2012 using a spectral filter sensitive to wavelengths of near-infrared light centered at 752 nanometers. The view was acquired at a distance of approximately 426,000 miles (685,000 kilometers) from Saturn and at a Sun-Saturn-spacecraft, or phase, angle of 20 degrees. Image scale is 23 miles (37 kilometers) per pixel on Saturn.
The Cassini Solstice Mission is a joint United States and European endeavor. The Jet Propulsion Laboratory, a division of the California Institute of Technology in Pasadena, manages the mission for NASA's Science Mission Directorate, Washington, D.C. The Cassini orbiter was designed, developed and assembled at JPL. The imaging team consists of scientists from the US, England, France, and Germany. The imaging operations center and team lead (Dr. C. Porco) are based at the Space Science Institute in Boulder, Colo.
For more information about the Cassini Solstice Mission visit http://ciclops.org, http://www.nasa.gov/cassini and http://saturn.jpl.nasa.gov.
Credit: NASA/JPL-Caltech/Space Science Institute
Released: February 27, 2012 (PIA 14597)
Image/Caption Information
PIA 14597
Avg Rating: 8.78/10
Full Size 1020x1020:
JPEG 172 KB
PNG 345 KB
TIFF 552 KB
Alliance Member Comments
NeKto (Feb 27, 2012 at 9:40 AM):
Titan is not a small object. but this really gives a sense of scale. what a fascinating system.


text:
Browse the strands
Maureen Duffy
Rags and Riches Walking Tour
Greening Aldwych: a walking tour of lost and future green spaces of Aldwych
Home » Savoy Hotel
Posts Tagged 'Savoy Hotel'
Monet's Pied-à-terre
By Théophraste Fady | 9 September 2019 | 0
"I find London lovelier to paint each day" – Claude Monet. Monet's link to London Monet fell in love with London in 1870-71, while in exile from France, during the Franco-Prussian war. After his return to France he vowed to revisit London, which he did in 1899, 1900 and 1901. In each of these three…
A Smoking Rebellion at the Savoy?
By Théophraste Fady | 12 August 2019 | 1
The Savoy hotel is a treasure trove of weird and intriguing events over the last century of Strand history. In 1896, per the Fairmont Hotel Group blog, the Duchesse de Clermont-Tonnerre was the first woman to smoke in public and did so at the Savoy. "The Duchesse de Clermont-Tonnerre, the first woman to smoke in…
Lost buildings of the Strand
Can you volunteer for Strandlines and Layers of London?
A short history of Great Queen Street
Untitled Poem
The Eleanor (Charing) Cross
Strandlines content is licensed under a Creative Commons Attribution-NonCommercial 4.0 International License. If you would like to assert ownership of your work under different terms, please do get in touch with the Strandlines editors
contact@strandlines.london
© 2017 Strandlines. All Rights Reserved.
We use cookies to help us improve website user experience. By continuing to use this site or closing this panel, you agree to our use of cookies. Find out more