text:
House Republicans Take New Action On Trump In Hopes Of Avoiding Impeachment
Posted by Ryan Saavedra | Jan 12, 2021 | Uncategorized | 0 |
https://www.dailywire.com/news/house-republicans-introduce-new-measure-to-censure-trump-in-hopes-of-avoiding-impeachment
Several House Republicans introduced a measure on Tuesday to censure President Donald Trump and condemn what happened last week in what appears to be an attempt to stave off impeachment efforts from Democrats.
"Today, January 12th, 2020, Representative Brian Fitzpatrick (PA-01) and colleagues introduced a concurrent resolution to censure the President of the United States, Donald J. Trump, for attempting to unlawfully overturn the 2020 Presidential election and for violating his oath of office on January 6th, 2021," a statement from Rep. Brian Fitzpatrick's (R-PA) office said. "In the aftermath of the riot at the Capitol last week, lawmakers have the solemn duty to accomplish two missions: hold the President fully and unequivocally accountable for his actions, and simultaneously calm and heal the fever-pitch tensions in our country."
The statement noted how Rep. Eleanor Holmes Norton (D-DC) supports censuring the president rather than taking more drastic measures and also notes recent remarks from Sen. Joe Manchin (D-WV), who said that the move to impeach Trump was "ill advised."
"Moreover, both Democrat and Republican Members of the U.S. Senate are convinced that the House's impeachment efforts will almost certainly result in a second acquittal of President Trump, which would even further divide and inflame tensions in our nation," the statement added. "There are two constitutional purposes of impeachment: 1) removal from office, and 2) barring the future holding of office. The current approach being advanced by House leadership is certain to accomplish neither one of these."
The resolution censures and condemns Trump for the events on January 6, 2021, and calls on Congress to publicly call out Trump for his actions and to recognize that Democrat Joe Biden is the president-elect.
Republican members gave the following statements on the resolution:
Fitzpatrick: "President Trump's attempts to undermine the outcome of the 2020 election have been unconscionable. The combination of a false information campaign coupled with inflammatory rhetoric led to the devastation that I was a personal witness to on the House Floor on January 6th. His actions threatened the integrity of our democracy, Congress, and his own Vice President. For months, President Trump has been lying to the American people with false information, and giving his supporters false expectations. The election is over. Joe Biden will be sworn in as President of the United States on January 20th, 2021. President Trump's actions, behavior, and language are unacceptable and unbecoming of the office he holds for the next eight days."
Rep. Tom Reed (R-NY): "This is an important step to hold the President accountable. Congress must make clear that it rejects extremism and condemns the President's actions. We will continue to push for Congressional leaders to work with us on investigating the events surrounding this dark period in our history and make sure it never happens again with the public's trust in our democratic institutions restored."
Rep. Young Kim (D-CA): "The violence that our nation witnessed on Wednesday was abhorrent and resulted in an assault on law enforcement, lives lost and many more put in danger. These rioters must be prosecuted to the fullest extent of the law. The president also misled many Americans to believe that the outcome of the election could change on January 6th, when that simply was not true, and must held accountable for his role. I believe censuring the president after his actions helps hold him accountable and could garner wide bipartisan support, allowing the House to remain united during some of our nation's darkest days. I'm proud to join Rep. Fitzpatrick and others in introducing this resolution today. Like many of my colleagues, I came to Washington promising to bridge the divide. I hope both parties can acknowledge our role in perpetuating division and come together to support this effort and move forward for our constituents and the nation."
Rep. Fred Upton (R-MI): "A peaceful transfer of power from one presidential administration to the next is the bedrock of the American republic. Last Wednesday that bedrock was almost destroyed. President Donald Trump must be held accountable for his actions, and a censure is appropriate."
This report has been updated to include additional information.
The Daily Wire is one of America's fastest-growing conservative media companies and counter-cultural outlets for news, opinion, and entertainment. Get inside access to The Daily Wire by becoming a member.
PreviousPence rejects calls to invoke 25th Amendment to remove Trump
NextREAD: Pence letter to Pelosi rejecting calls to invoke 25th Amendment
Trump urges Fed to make large rate cut as policymakers meet
Odell Beckham Jr. And Jarvis Landry Mock The Ravens Extending Marcus Peters
Mueller Proved Comey Told the Truth About Trump
Capitol Hill Rioter Who Stole Pelosi's Laptop Surrenders, Device Still Missing
5 Hank Williams Jr. Classics That Would Be Canceled Today
China slaps Trump administration officials with sanctions as they exit office
MASK MANDATE? Biden to Sign Executive Order Asking Americans to Wear Face-Masks for 100 Days
Jan 20, 2021 | Sean Hannity
White House contact for now asks for your PRONOUNS


LaClasse offers professional and accurate Marathi translation services across India. We provide complete Marathi translation for companies, community, government, organizations, and individuals. We offer our Marathi translation services for legal, pharmaceutical, medical, business, software, contract providing a highly precise, and error free translation.
Why LaClasse as your next Marathi Language Translation Company in India?
Quality Confirmation: Work is relegated to interpreters in view of their range of ability took after by general editing and customer criticism coordination. Quality is not discretionary at LaClasse.
What Marathi Language Translation Services we provide?
At LaClasse India, we hire only certified Marathi translators in Delhi who are skilled in Marathi to English translation, English to Marathi translation and Marathi sentence translation. The translators have a strong command over the Marathi language and have experience in translating different kinds of documents. The team of expert Marathi translators at LaClasse can translate Marathi documents such as legal documents, medical documents, and financial documents amongst others. Our Marathi translators have a in-depth knowledge of Marathi grammar, inflection, declination, deference, formal address, informal address, and the other complex features of the Marathi language.


text:
THISDAYLIVE
Home Business NNPC: No Plan to Pay N36bn Compensation to Port Harcourt Refinery...
NNPC: No Plan to Pay N36bn Compensation to Port Harcourt Refinery Host Community
• Report: Oil thieves forced 150,000bpd Nembe creek trunk line to shut down for 122 days in two years
By Ejiofor Alike in Lagos and Chineme Okafor in Abuja
The Nigerian National Petroleum Corporation (NNPC) yesterday dismissed insinuation that it planned to pay N36 billion compensation allegedly due to Alesa-Eleme community in Rivers State as royalty for playing host to its Port Harcourt Refining Company.
NNPC said in a statement by its Group General Manager, Group Public Affairs Division, Mr. Ndu Ughamadu, in Abuja that such report was a hoax which originated from a traditional ruler regarded as a claimant to the Alesa-Eleme traditional stool.
It alleged that the said traditional ruler went to town with the fake story after a purported meeting with the Minister of State for Petroleum Resources, Dr. Ibe Kachikwu, adding that it had checked with Kachikwu to confirm that there was no such meeting at which he made the promise of a compensation payment to the community.
NNPC explained the story was fabricated to cause disharmony between it and Alesa-Eleme community which it said has being a good host to it. Â
The corporation said through the years, the refinery had enjoyed cordial relations with all the 10 communities in Eleme where it is located, including Alesa Eleme and Alade Eleme, through an existing Joint Community Relations committee (JCRC).
NNPC said the JCRC, comprising representatives from the various interest groups of the community, had been relating with the management of the refinery on a sustained basis for creation and execution of development projects and needs of the communities.
It asked the community members to discountenance the reported plan to pay out N36 billion compensation as there was no such approval or payment to any entity.
Meanwhile, a status report on the operation of the Nembe Creek Trunk Line (NCTL) has indicated that the 150,000 barrels per day capacity pipeline was closed down for 122 days between January 2016 and May 2018, THISDAY has learnt.
The NCTL and the Trans Niger Pipeline (TNP) are the two major pipelines used by oil companies operating in the eastern Niger Delta to evacuate crude oil to the Shell-operated Bonny Export Terminal.
THISDAY gathered that the NCTL is a major crude oil transportation channel that conveys crude oil injected from  Oil Mining Leases (OMLs) 29, 18, 24, 25, 23 and 55; running from Nembe Creek in Bayelsa State through Cawthorne Channel Field on OML 18 to the Bonny Oil Terminal for export.
The pipeline has a capacity of 150,000 barrels per day at Nembe Creek, but can evacuate 600,000 barrels of liquids from the  Cawthorne Channel end.
The 115 kilometre-capacity line was built by Shell Petroleum Development Company (SPDC) between 2006 and 2010 at a cost of about $1.1 billion but is currently being operated by Aiteo Group since 2015 when Shell completed the assignment of its interest in OML 29 and the NCTL to Aiteo Eastern E&P Co. Ltd.
The status report on the operations of the pipeline, which was obtained by THISDAY from one of the oil producing companies that evacuate crude oil through the facility, showed that due to recurrent thefts on the pipeline route, which are evidenced by significant pressure reductions on the trunk line, theft points identification as well as illegal refineries, Nigeria has experienced loss of production and huge revenue.
The report showed that between January 14, 2016 and May 23, 2018, the NCTL was out of operation for 122 days as a result of the activities of oil thieves that created several illegal bunkering points on the pipeline.
 According to the report, in December 2016 alone, 45.46 per cent of the total net crude oil injected into the NCTL was lost.
A breakdown of the operation of the pipeline showed that it was shut down for 53 days in 2016; 62 days in 2017 and seven days in 2018.
"Third party interference with the, line has oftentimes resulted in oil leaks, which ultimately culminate in shutting down the NCTL to undertake emergency repairs. This in itself has resulted in the NCTL being shut down for about 122 days and an approximate deferment of 50.386 million barrels of crude oil (net) for the six injectors into the NCTL since Aiteo took over the operatorship of the Trunk line. As at May 1, 2018, there were a total of 24 illegal bunkering points identified along the NCTL. Aiteo Eastern E&P successfully repaired nine of these illegal bunkering points," the report said.
The report added that these illegal bunkering points also contribute to the huge losses on the volumes injected across the NCTL by the six oil mining leases and the volumes actually received at Bonny Terminal.
THISDAY had reported that Aiteo paid the Joint Task Force in the Niger Delta a total of N1.192 billion for the protection of the pipeline over a period of three years.
A breakdown of the payment schedule showed that for 2015 alone, the company paid a total of N19.696 million to the JTF; N462.033 million in 2016; N449.419 million in 2017 and N260.663 million in 2018.
Previous articleSuspected Herdsmen Kill Seven in Benue
Next articleBanks' Borrowing from CBN Window Surges
With Rising Income Inequality, 100 Bank Customers Get 47% of Loan
Report: 5G Subscriptions Estimated to Reach 1.9bn in 2024
GSMA Targets Youth Population to Drive Subscriber Growth
Oshiomhole Denies Instigating Takeover of Edo Assembly by House of Representatives
Tambuwal Woos UK Investors
African Intelligence Agencies Build Database to Monitor Terrorist Groups
Customs Intercepts Ambulance Stuffed with Tramadol
Ekiti to Dismiss Teachers Collecting Illegal Fees
Addressing Open Defecation in Nigeria
Durosinmi-Etti: Avastin has Saved Many Nigerians with Cancer
Buhari Approves Payment of Minimum Wage for Workers Earning Below N30,000
editor - July 17, 2019 4:59 am
President Muhammadu Buhari has approved the immediate implementation of the N30,000 new national wage for Federal Public Service workers currently earning below the minimum...
NLC, TUC Take over Negotiations for Implementation of New Minimum Wage
Ango Abdullahi's Tenor and Tenure
Tribunal Orders INEC Chairman to Appear in Court Thursday
Stakeholders Reject Ethiopian Airlines' Plan to Fly Local Routes in Nigeria
Buhari Plays Video to Prove No Electronic Voting in Presidential Election
Obaseki Adamant as House Orders Fresh Proclamation of Edo Assembly
IN THE LAST WEEK
Afenifere, PANDEF Fault FG's Plan to Deploy Military in Highways
Senate President, Pinnick, Others Encourage Eagles to Go for Bronze
Wike to Launch New Security Architecture in Rivers
GOtv Boxing Night 19: Fans Excited As Show Returns To Lagos
Founded on January 22, 1995, THISDAY is published by THISDAY NEWSPAPERS LTD., 35 Creek Road Apapa, Lagos, Nigeria with offices in 36 states of Nigeria , the Federal Capital Territory and around the world. It is Nigeria's most authoritative news media available on all platforms for the political, business, professional and diplomatic elite and broader middle classes while serving as the meeting point of new ideas, culture and technology for the aspirationals and millennials. The newspaper is a public trust dedicated to the pursuit of truth and reason covering a range of issues from breaking news to politics, business, the markets, the arts, sports and community to the crossroads of people and society.
Contact us: hello@thisdaylive.com
© Copyright 2016 THISDAY NEWSPAPERS LTD.

redpajama_set_name: RedPajamaCommonCrawl


text:
Twm Siôn Cati (also sometimes spelt Twm Sion Cati, historically Twm Shon Catti or Twm Shon Catty) is a figure in Welsh folklore.

Background

Tales about him vary on details, but he is usually said to have been born in or very near to Tregaron, in or around 1530, his mother being one Cati Jones of Tregaron. His father was supposed to be Siôn ap Dafydd ap Madog ap Hywel Moetheu of Porth-y-ffin, also near Tregaron. He was an illegitimate son whose mother named him Thomas. The Welsh-language equivalent of Tom is Twm. It was also common practice in rural Wales for children with common names to be nicknamed after their mothers. Thus he became known as Twm Siôn Cati.

He was supposedly a Protestant by faith at a time when Mary I of England, a Catholic monarch, ruled and he had to gain an income as best he could, choosing robbery as his trade as his religion had him marked out as a rebel already and his high status meant that he could rely on any advantage or protection from others. As a young man he fled to Geneva in 1557 to escape the law. After the accession of the Protestant Queen Elizabeth I, he was able to obtain a pardon for his thievery, enabling his return to Wales in 1559.

Twm was active in west Wales, with forays into England, in the late sixteenth century.  Stories centre on his tricks, with which he outwitted law-abiding people and criminals alike.

The original character is often said to have been based on one Thomas Jones (c. 1530–1609) who, according to the Oxford Companion to the Literature of Wales, was pardoned for unspecified offences in 1559, wrote poetry, was a steward who "often had recourse to the law", and married the widow of Thomas Rhys Williams of Ystrad-ffin. It seems unlikely, however, that all the tales told of Twm Siôn Cati in later times can be attributed to this one man. The Oxford Companion further asserts "he has been confused with others of the same name who were raiders and highwaymen in the district of Tregaron" and lists another eleven Thomas Joneses in the field of literature alone. The Dictionary of Welsh Biography identifies Jones as a cousin of John Dee, and his second wife as a daughter of John Prise.

Although the original tales were passed on orally, there were later a number of written stories of Twm Siôn Cati.  An English-language pamphlet, Tomshone Catty's Tricks, was printed in 1763.  William Frederick Deacon wrote two books involving him in the 1820s. In 1828, T J Llewelyn Prichard's The Adventures and Vagaries of Twm Shon Catti, descriptive of Life in Wales was published.  Enlarged (and somewhat altered) editions of this followed. An eight-page pamphlet, Y Digrifwr, was published in 1811, its subtitle admirably describing its contents ("The jokester: a collection of feats and tricks of Thomas Jones of Tregaron, Cardiganshire, he who is generally known under the name Twm Sion Catti").  George Borrow, walking through Wild Wales in 1854, heard several tales about Twm from a fellow-walker on the way to Tregaron and later read what was probably Prichard's book.

In the tale told by Llewelyn Prichard, Twm is the illegitimate son of Cati Jones following attentions from John Wynn of Gwydir (John "Wynn" ap Maredudd); the Welsh forms of the names of his parents became incorporated into his name. He grows up in Tregaron and after a spell working for a farmer, he works for a local landowner. He is trusted to take a large sum of the squire's money to England. The journey is fraught with encounters with highwaymen, footpads, and villains, all of whom Twm is able to best. Twm woos and eventually marries the Lady of Ystrad-ffin and subsequently becomes a magistrate and mayor of Brecon.

George Borrow disapproved of the veneer of respectability in Prichard's book: "Its grand fault is endeavouring to invest Twm Shon (a name Borrow spells with varying consistency) with a character of honesty, and to make his exploits appear rather those of a wild young waggish fellow than of a robber." According to the stories which Borrow picked up around Tregaron, Twm's career was more straightforward.  "Between eighteen and nineteen, in order to free himself and his mother from poverty which they had long endured, he adopted the profession of a thief, and soon became celebrated through the whole of Wales for the cleverness and adroitness which he exercised in his calling".

It is rumoured that Twm had a number of illegitimate children during his time as a highway man. To hide the true identity of their father, the children were given religious or biblical surnames.

Tall tales

Borrow recounted a story in which a farmer is hunting Twm over the theft of a bullock. The farmer reaches Twm's mother's house and asks whether Twm Shone Catti (another of Borrow's spellings) lives there. A beggar answers that he does, and agrees to hold the farmer's horse and whip for him. As the farmer goes into the house, the beggar jumps onto the horse: it is Twm. He gallops to the house of the farmer and tells the farmer's wife that the farmer is in trouble, needs money urgently, and has sent Twm to fetch it, with the horse and whip to prove that the message really came from the farmer. The farmer's wife pays up. Twm, now in possession of the farmer's money and horse, hastily departs for London, later selling the horse.

A tale recounted by Meyrick recalls how Twm was asked by a poor man to steal a pitcher for him. They went together to a merchant where Twm started belittling the man's wares. Having told his friend secretly to take the pitcher of his choice, Twm distracted the merchant by telling him there was a hole in one of the pitchers, which the man denied. Twm desired him to put his hand in the pitcher to test it and the man still denied there was a hole. Twm then asked him how, if there was no hole, could he have put his hand inside? By this time his friend had disappeared with his pitcher, undetected.

A tale from Prichard's book involves an occasion when Twm is staying in an inn overnight and realises other people are planning to rob him the following day after he sets off. He has a large sum of money with him. The following morning he behaves as though his money is in the pack-saddle of his horse. When the highwayman catches up, Twm drops the saddle in the middle of a pool. The highwayman wades into the pool to fetch it. Twm takes the opportunity to make off with the highwayman's horse. A complication arises because the horse responds to the voice of the highwayman crying "Stop!" Luckily Twm, in terror, happens to shout a word which makes the horse gallop on again, and he is conveyed to safety.

Another tale recounts how Twm waylaid a rich squire, who was accompanied by his daughter, Twm was so smitten with her that he returned her jewellery to her and attempted to woo her, against her father's opposition and, initially, her own. One full moon shortly after the robbery, he crept to her window, roused her from sleep, caught her hand at the window and kissed it, refusing to let her go until she promised to marry him. She wouldn't promise so Twm drew his dagger, drew blood on her wrist and threatened to sever her hand unless she assented to marriage forthwith. She agreed to marry him and she kept her hand. Their marriage followed soon after, despite her father's views and the directness of Twm's courtship methods. The girl was supposedly the widow of the sheriff of Carmarthen. Through this marriage Twm is supposed to have gained respectability, eventually becoming a justice of the peace, sitting in judgement on others, a position he held until his death aged 79.

Memorabilia
Twm Siôn Cati's Cave is on Dinas Hill, near Ystrad-ffin and Rhandir-mwyn. There is a steep ascent to the cave, which is surrounded by trees and boulders, and it is necessary to crawl inside. Part of the cave roof has collapsed but the cave itself has obviously been visited over many years, as evidenced by the carvings – one reads 1832. It overlooks the confluence of the River Tywi with the River Pysgotwr.  The Oxford Companion to the Literature of Wales notes that Prichard's vivid descriptions of Twm's cave suggest the author knew the area around Rhandir-mwyn well. Historical accounts have been published by Lynne Hughes (whose book Hawkmoor, was serialised by the BBC in 1977) and three by Welsh-language children's author T. Llew Jones.

The community of Tregaron held a year of activities to commemorate the 400th anniversary of the death of Twm Siôn Cati in 2009.
The year saw activities such as an exhibition at Tregaron Kite Centre (the red kite is common in the area), a charity walk from his cave to his birthplace and the launching of four books. Local artists created souvenir items. A wood-carving of Twm created by Grace Young Monaghan was placed on Tregaron Square.

An international Twm Siôn Cati Day is held each 17 May. A Twm Siôn Cati Community Prize is presented annually to a Tregaron Primary School pupil for doing a good deed in Tregaron. A Twm Town Trail, designed by the school's pupils, is walked by hundreds of people every year.

Television

The television series Hawkmoor created by Lynn Hughes and starring John Ogwen as Twm and Jane Asher as Lady Johane Williams was broadcast by the BBC in 1978, depicting Twm as a Welsh Robin Hood/freedom fighter protecting the Welsh people from the repression of English-born Sheriff John Stedman (Jack May) and the cruel (Catholic) Vicar Davyd (Philip Madoc). A Penguin paperback relating some of the television adventures (and containing a poem actually written by Twm) was written by Lynn Hughes and published in 1978.

References

First edition of The Adventures and Vagaries of Twm Shon Catti online at Books from the Past
Later edition as The Comical Adventures of Twm Shon Catty (Thomas Jones Esq) Commonly Known as the Welsh Robin Hood published in facsimile by Llanerch 1991
Chapter XCIII of Wild Wales: Its People, Language and Scenery by George Borrow
Meic Stephens 1986 The Oxford Companion to the Literature of Wales, pub: OUP,
Y Digrifwr: Casgliad o gampiau a dichellion Thomas Jones o Dregaron yn Sir Aberteifi; yr hwn sydd yn cael ei adnobod yn gyffredin wrth yr enw Twm Sion Catti ("The Joker: a collection of exploits and tricks of Thomas Jones of Tregaron in Cardiganshire, commonly known by the name of Twm Sion Catti"): pamphlet published in 1811.

External links
Places and photos relating to Twm Shon Cati held on Gathering the Jewels
BBC Mid-Wales: Twm Sion Cati

Welsh folklore
Welsh rebels
1609 deaths
Recipients of English royal pardons
Year of birth unknown

redpajama_set_name: RedPajamaWikipedia


Our wood diffuser has gained a lot of attention from our friends. They love it so much and many of them come to share their special usage with us.
Elaine is a cat lover, she has two cats at home and she has a big book shelf at home. However, her cats are so naughty that they always climb up the book shelf and let these books fall down on the floor. Therefore, they will play with these papers and make the place very messy.
She tried many ways to stop them, but not success at all. One day she got an idea and put two wood diffusers in front of the book shelf and found that her cats don't get close to the book shelf any more. She used basil and lemongrass, both has very strong scent.
Lily is a nurse and she is working in the public hospital. Whenever she has night shift, she will bring this wood diffuser in her desk and has the pleasant smell to accompany her for the whole night.
She thought that it's a very brilliant design. Due to her job nature that she does not have fixed working area and she needs to work in the different places. Therefore, she can carry this handy wood diffuser with her.
Many customers also put this wood diffuser inside the wardrobe and it will spread the nice smell all over your clothes on the one hand and help you to get rid of bugs on the other hand. You can choose basil, peppermint, geranium, bergamot, cajeput, citronella, eucalyptus or any oil with strong smell will be effective.
If you choose any essential oils, you can get a Wood Diffuser for HK$5!


When Jessica O'Dwyer and her husband fell in love with the online photo of a Guatemalan baby girl, they had no idea of the twisted journey that awaited them. Their eagerness to become adoptive parents lured them into signing with an inept LA agency whose slapdash methods left the couple fearful that their baby would never come home. At that point, Jessica made the brave decision to move to Guatemala, learning how to care for baby Olivia, while at the same time struggling to break through the bureaucratic indifference that stood in the way of making Olivia hers forever.
Kirkus Reviews calls this memoir, "a scathing critique on a foreign adoption system and one woman's attempt to fight it."
Author Joyce Maynard describes Mamalita as a book about the nature of parenthood, "the fierce love and loyalty that makes it possible for us to do more than we ever knew we were capable of." You may have a good cry when you get to the end; I certainly did!
You can learn more about Jessica's story on her blog.
How has being a mom or dad drawn out your inner strength? Or if you're not a parent, what important relationship or situation has demanded that you act with courage?
1. Follow our blog (publicly) and leave another comment (or let us know if you already are).
2. Subscribe to the Mama Memo and leave another comment (or let us know if you already are).
3. Blog about the giveaway, and link back here. Post your blog entry before you comment.
4. Add the Mama Manifesto button to your sidebar.
5. Follow us on Twitter and Tweet about this giveaway: "Giveaway- Win a copy of Mamalita: An Adoption Memoir from @MamaManifesto. Enter at mamamanifesto.com"
6. Become a fan of Mama Manifesto on Facebook by clicking the button on the left.
7. Become a fan of Mamalita: An Adoption Memoir on Facebook!
This giveaway will be closed Saturday at 11 p.m. and the winner will be announced next Sunday!
I am not a parent, but care daily for a group of formerly homeless and/or abused children while their mothers take classes to become self-sufficient. These children give me the opportunity to see a new side of myself and of humanity. They call me daily to act with great courage to break through their cries, behavior, and lack of ability to handle their situations, to just LOVE them above all else. My husband and I want to have and adopt children in our future, and working with and loving these children has solidified in my mind that I do want to adopt, and that maybe, with the grace of God and the experiences I have now, we will be able to handle whatever our adopted child(ren) come to us with.
Being a mom has drawn out my inner strength from Day 1. I do many things that I couldn't have handles before my son came along and gave me that extra motivation. One example is living on little to no sleep or keeping up with work during a really busy time while my son is home sick for an entire week.
i've never been patient...God has used parenting to teach me patience...as we had 1 child...then 2...then 3...then 4...and now as we wait and wait and wait for our 2 boys in africa.
This book sounds inspirational and educational, and I'd love to read it. To answer the question - parenting has drawn out my inner strength because it forces me to focus on someone else. Life is no longer all about me; it is mostly about them, and as a parent, I am okay with that. I've become concerned not only about my children, but all children, and I find strength in that.
I was a single mom and raised my daughter alone. Her father was a "Disneyland Dad", not a bad person but he left all the practical issues to me. He was undependable. I was the one who took her to the doctor and dentist, went to the teacher conferences, washed pukey sheets at 3:00 a.m. I had almost no time for myself. Before she was born, I read a book every week. In the years afterward, I was lucky to finish a book each month. My church had a mom's group that I longed to join, but it met during business hours, when I was at work. I hated my job, but the benefits were so good that I couldn't afford to leave. I managed to carve out as good a life for us as I could afford. My daughter now tells me that her earliest memory is sitting on my lap while I read to her. I made raising her my first priority. I taught her the survival skills she would need as an adult. When she moved into her first apartment, she was appalled at how casually her roommates grocery shopped. "They just throw stuff into the cart and don't even compare prices or use coupons," she said. Today, she is a self-supporting young adult, in a committed relationship, with many friends. She never had a drug or alcohol problem, or got into trouble at school. She is a kind, compassionate young woman and I am very proud of her.


just picked up a technics sa x900l off freecycle with a panasinic jl 7 turntable. what your thoughts on these, also the tape deck on the technics is making a clicking noise as the cassette plays.
anyone got a ROTEL RCD 955ax cd player or 965bx cd player going cheapish ?
Hmmm... I'll see your Sony and raise you my Pure Mi which including the battery and charger was £1..
Absolute 80s - proper retro radio, paradoxically on DAB.
It replaced my 207 pro player.
The wife is happy as its smaller than the Sony player.
Thanks. Can't beat quality hi-fi. Waiting for a Tuner and headphones to arrive.


An ultrafast and accurate scoring function for protein−protein and protein-ligand docking is presented. It includes (1) a molecular mechanics (MM) part based on a 12−6 Lennard-Jones potential; (2) an electrostatic component based on an implicit solvent model (ISM) with individual desolvation penalties for each partner in the protein−protein complex plus a hydrogen bonding term; and (3) a surface area (SA) contribution to account for the loss of water contacts upon protein−protein complex formation. The accuracy and performance of the scoring function, termed MM-ISMSA, have been assessed by (1) comparing the total binding energies, the electrostatic term, and its components (charge−charge and individual desolvation energies), as well as the per residue contributions, to results obtained with well-established methods such as APBSA or MM-PB(GB)SA for a set of 1242 decoy protein−protein complexes and (2) testing its ability to recognize the docking solution closest to the experimental structure as that providing the most favorable total binding energy. For this purpose, a test set consisting of 15 protein−rotein complexes with known 3D structure mixed with 10 decoys for each complex was used. The correlation between the values afforded by MM-ISMSA and those from the other methods is quite remarkable (r2 ∼ 0.9), and only 0.2−5.0 s (depending on the number of residues) are spent on a single calculation including an all vs all pairwise energy decomposition. On the other hand, MM-ISMSA correctly identifies the best docking solution as that closest to the experimental structure in 80% of the cases. Finally, MM-ISMSA can process molecular dynamics trajectories and reports the results as averaged values with their standard deviations.
MM-ISMSA has been implemented as a plugin to the widely used molecular graphics program PyMOL, although it can also be executed in command-line mode.
MM-ISMSA is free distributed for non commercial purposes.
MM-ISMSA: an ultra-fast and accurate scoring function for protein-protein docking.
Morreale, A.; Gil-Redondo, R.; Ortiz, A.R.
Proteins 2007 May, 67: 606-16.


text:
package com.android.settings.fuelgauge;

import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.DashPathEffect;
import android.os.BatteryManager;
import android.text.format.DateFormat;
import android.text.format.Formatter;
import android.util.Log;
import android.util.TimeUtils;
import com.android.settings.R;
import com.android.settings.Utils;

import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Typeface;
import android.os.BatteryStats;
import android.os.SystemClock;
import android.os.BatteryStats.HistoryItem;
import android.telephony.ServiceState;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;
import libcore.icu.LocaleData;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Locale;

public class BatteryHistoryChart extends View {
    static final boolean DEBUG = false;
    static final String TAG = "BatteryHistoryChart";

    static final int CHART_DATA_X_MASK = 0x0000ffff;
    static final int CHART_DATA_BIN_MASK = 0xffff0000;
    static final int CHART_DATA_BIN_SHIFT = 16;

    static class ChartData {
        int[] mColors;
        Paint[] mPaints;

        int mNumTicks;
        int[] mTicks;
        int mLastBin;

        void setColors(int[] colors) {
            mColors = colors;
            mPaints = new Paint[colors.length];
            for (int i=0; i<colors.length; i++) {
                mPaints[i] = new Paint();
                mPaints[i].setColor(colors[i]);
                mPaints[i].setStyle(Paint.Style.FILL);
            }
        }

        void init(int width) {
            if (width > 0) {
                mTicks = new int[width*2];
            } else {
                mTicks = null;
            }
            mNumTicks = 0;
            mLastBin = 0;
        }

        void addTick(int x, int bin) {
            if (bin != mLastBin && mNumTicks < mTicks.length) {
                mTicks[mNumTicks] = (x&CHART_DATA_X_MASK) | (bin<<CHART_DATA_BIN_SHIFT);
                mNumTicks++;
                mLastBin = bin;
            }
        }

        void finish(int width) {
            if (mLastBin != 0) {
                addTick(width, 0);
            }
        }

        void draw(Canvas canvas, int top, int height) {
            int lastBin=0, lastX=0;
            int bottom = top + height;
            for (int i=0; i<mNumTicks; i++) {
                int tick = mTicks[i];
                int x = tick&CHART_DATA_X_MASK;
                int bin = (tick&CHART_DATA_BIN_MASK) >> CHART_DATA_BIN_SHIFT;
                if (lastBin != 0) {
                    canvas.drawRect(lastX, top, x, bottom, mPaints[lastBin]);
                }
                lastBin = bin;
                lastX = x;
            }

        }
    }

    static final int SANS = 1;
    static final int SERIF = 2;
    static final int MONOSPACE = 3;

    // First value if for phone off; first value is "scanning"; following values
    // are battery stats signal strength buckets.
    static final int NUM_PHONE_SIGNALS = 7;

    final Paint mBatteryBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    final Paint mBatteryGoodPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    final Paint mBatteryWarnPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    final Paint mBatteryCriticalPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    final Paint mTimeRemainPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    final Paint mChargingPaint = new Paint();
    final Paint mScreenOnPaint = new Paint();
    final Paint mGpsOnPaint = new Paint();
    final Paint mFlashlightOnPaint = new Paint();
    final Paint mCameraOnPaint = new Paint();
    final Paint mWifiRunningPaint = new Paint();
    final Paint mCpuRunningPaint = new Paint();
    final Paint mDateLinePaint = new Paint();
    final ChartData mPhoneSignalChart = new ChartData();
    final TextPaint mTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
    final TextPaint mHeaderTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
    final Paint mDebugRectPaint = new Paint();

    final Path mBatLevelPath = new Path();
    final Path mBatGoodPath = new Path();
    final Path mBatWarnPath = new Path();
    final Path mBatCriticalPath = new Path();
    final Path mTimeRemainPath = new Path();
    final Path mChargingPath = new Path();
    final Path mScreenOnPath = new Path();
    final Path mGpsOnPath = new Path();
    final Path mFlashlightOnPath = new Path();
    final Path mCameraOnPath = new Path();
    final Path mWifiRunningPath = new Path();
    final Path mCpuRunningPath = new Path();
    final Path mDateLinePath = new Path();

    BatteryStats mStats;
    Intent mBatteryBroadcast;
    long mStatsPeriod;
    int mBatteryLevel;
    String mMaxPercentLabelString;
    String mMinPercentLabelString;
    String mDurationString;
    String mChargeLabelString;
    String mChargeDurationString;
    String mDrainString;
    String mChargingLabel;
    String mScreenOnLabel;
    String mGpsOnLabel;
    String mCameraOnLabel;
    String mFlashlightOnLabel;
    String mWifiRunningLabel;
    String mCpuRunningLabel;
    String mPhoneSignalLabel;

    int mChartMinHeight;
    int mHeaderHeight;

    int mBatteryWarnLevel;
    int mBatteryCriticalLevel;

    int mTextAscent;
    int mTextDescent;
    int mHeaderTextAscent;
    int mHeaderTextDescent;
    int mMaxPercentLabelStringWidth;
    int mMinPercentLabelStringWidth;
    int mDurationStringWidth;
    int mChargeLabelStringWidth;
    int mChargeDurationStringWidth;
    int mDrainStringWidth;

    boolean mLargeMode;

    int mLastWidth = -1;
    int mLastHeight = -1;

    int mLineWidth;
    int mThinLineWidth;
    int mChargingOffset;
    int mScreenOnOffset;
    int mGpsOnOffset;
    int mFlashlightOnOffset;
    int mCameraOnOffset;
    int mWifiRunningOffset;
    int mCpuRunningOffset;
    int mPhoneSignalOffset;
    int mLevelOffset;
    int mLevelTop;
    int mLevelBottom;
    int mLevelLeft;
    int mLevelRight;

    int mNumHist;
    long mHistStart;
    long mHistDataEnd;
    long mHistEnd;
    long mStartWallTime;
    long mEndDataWallTime;
    long mEndWallTime;
    boolean mDischarging;
    int mBatLow;
    int mBatHigh;
    boolean mHaveWifi;
    boolean mHaveGps;
    boolean mHavePhoneSignal;
    boolean mHaveCamera;
    boolean mHaveFlashlight;

    final ArrayList<TimeLabel> mTimeLabels = new ArrayList<TimeLabel>();
    final ArrayList<DateLabel> mDateLabels = new ArrayList<DateLabel>();

    Bitmap mBitmap;
    Canvas mCanvas;

    static class TextAttrs {
        ColorStateList textColor = null;
        int textSize = 15;
        int typefaceIndex = -1;
        int styleIndex = -1;

        void retrieve(Context context, TypedArray from, int index) {
            TypedArray appearance = null;
            int ap = from.getResourceId(index, -1);
            if (ap != -1) {
                appearance = context.obtainStyledAttributes(ap,
                                    com.android.internal.R.styleable.TextAppearance);
            }
            if (appearance != null) {
                int n = appearance.getIndexCount();
                for (int i = 0; i < n; i++) {
                    int attr = appearance.getIndex(i);

                    switch (attr) {
                    case com.android.internal.R.styleable.TextAppearance_textColor:
                        textColor = appearance.getColorStateList(attr);
                        break;

                    case com.android.internal.R.styleable.TextAppearance_textSize:
                        textSize = appearance.getDimensionPixelSize(attr, textSize);
                        break;

                    case com.android.internal.R.styleable.TextAppearance_typeface:
                        typefaceIndex = appearance.getInt(attr, -1);
                        break;

                    case com.android.internal.R.styleable.TextAppearance_textStyle:
                        styleIndex = appearance.getInt(attr, -1);
                        break;
                    }
                }

                appearance.recycle();
            }
        }

        void apply(Context context, TextPaint paint) {
            paint.density = context.getResources().getDisplayMetrics().density;
            paint.setCompatibilityScaling(
                    context.getResources().getCompatibilityInfo().applicationScale);

            paint.setColor(textColor.getDefaultColor());
            paint.setTextSize(textSize);

            Typeface tf = null;
            switch (typefaceIndex) {
                case SANS:
                    tf = Typeface.SANS_SERIF;
                    break;

                case SERIF:
                    tf = Typeface.SERIF;
                    break;

                case MONOSPACE:
                    tf = Typeface.MONOSPACE;
                    break;
            }

            setTypeface(paint, tf, styleIndex);
        }

        public void setTypeface(TextPaint paint, Typeface tf, int style) {
            if (style > 0) {
                if (tf == null) {
                    tf = Typeface.defaultFromStyle(style);
                } else {
                    tf = Typeface.create(tf, style);
                }

                paint.setTypeface(tf);
                // now compute what (if any) algorithmic styling is needed
                int typefaceStyle = tf != null ? tf.getStyle() : 0;
                int need = style & ~typefaceStyle;
                paint.setFakeBoldText((need & Typeface.BOLD) != 0);
                paint.setTextSkewX((need & Typeface.ITALIC) != 0 ? -0.25f : 0);
            } else {
                paint.setFakeBoldText(false);
                paint.setTextSkewX(0);
                paint.setTypeface(tf);
            }
        }
    }

    static class TimeLabel {
        final int x;
        final String label;
        final int width;

        TimeLabel(TextPaint paint, int x, Calendar cal, boolean use24hr) {
            this.x = x;
            final String bestFormat = DateFormat.getBestDateTimePattern(
                    Locale.getDefault(), use24hr ? "km" : "ha");
            label = DateFormat.format(bestFormat, cal).toString();
            width = (int)paint.measureText(label);
        }
    }

    static class DateLabel {
        final int x;
        final String label;
        final int width;

        DateLabel(TextPaint paint, int x, Calendar cal, boolean dayFirst) {
            this.x = x;
            final String bestFormat = DateFormat.getBestDateTimePattern(
                    Locale.getDefault(), dayFirst ? "dM" : "Md");
            label = DateFormat.format(bestFormat, cal).toString();
            width = (int)paint.measureText(label);
        }
    }

    public BatteryHistoryChart(Context context, AttributeSet attrs) {
        super(context, attrs);

        if (DEBUG) Log.d(TAG, "New BatteryHistoryChart!");

        mBatteryWarnLevel = mContext.getResources().getInteger(
                com.android.internal.R.integer.config_lowBatteryWarningLevel);
        mBatteryCriticalLevel = mContext.getResources().getInteger(
                com.android.internal.R.integer.config_criticalBatteryWarningLevel);

        mThinLineWidth = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
                2, getResources().getDisplayMetrics());

        mBatteryBackgroundPaint.setColor(0xFF009688);
        mBatteryBackgroundPaint.setStyle(Paint.Style.FILL);
        mBatteryGoodPaint.setARGB(128, 0, 128, 0);
        mBatteryGoodPaint.setStyle(Paint.Style.STROKE);
        mBatteryWarnPaint.setARGB(128, 128, 128, 0);
        mBatteryWarnPaint.setStyle(Paint.Style.STROKE);
        mBatteryCriticalPaint.setARGB(192, 128, 0, 0);
        mBatteryCriticalPaint.setStyle(Paint.Style.STROKE);
        mTimeRemainPaint.setColor(0xFFCED7BB);
        mTimeRemainPaint.setStyle(Paint.Style.FILL);
        mChargingPaint.setStyle(Paint.Style.STROKE);
        mScreenOnPaint.setStyle(Paint.Style.STROKE);
        mGpsOnPaint.setStyle(Paint.Style.STROKE);
        mCameraOnPaint.setStyle(Paint.Style.STROKE);
        mFlashlightOnPaint.setStyle(Paint.Style.STROKE);
        mWifiRunningPaint.setStyle(Paint.Style.STROKE);
        mCpuRunningPaint.setStyle(Paint.Style.STROKE);
        mPhoneSignalChart.setColors(com.android.settings.Utils.BADNESS_COLORS);
        mDebugRectPaint.setARGB(255, 255, 0, 0);
        mDebugRectPaint.setStyle(Paint.Style.STROKE);
        mScreenOnPaint.setColor(0xFF009688);
        mGpsOnPaint.setColor(0xFF009688);
        mCameraOnPaint.setColor(0xFF009688);
        mFlashlightOnPaint.setColor(0xFF009688);
        mWifiRunningPaint.setColor(0xFF009688);
        mCpuRunningPaint.setColor(0xFF009688);
        mChargingPaint.setColor(0xFF009688);

        TypedArray a =
            context.obtainStyledAttributes(
                attrs, R.styleable.BatteryHistoryChart, 0, 0);

        final TextAttrs mainTextAttrs = new TextAttrs();
        final TextAttrs headTextAttrs = new TextAttrs();
        mainTextAttrs.retrieve(context, a, R.styleable.BatteryHistoryChart_android_textAppearance);
        headTextAttrs.retrieve(context, a, R.styleable.BatteryHistoryChart_headerAppearance);

        int shadowcolor = 0;
        float dx=0, dy=0, r=0;

        int n = a.getIndexCount();
        for (int i = 0; i < n; i++) {
            int attr = a.getIndex(i);

            switch (attr) {
                case R.styleable.BatteryHistoryChart_android_shadowColor:
                    shadowcolor = a.getInt(attr, 0);
                    break;

                case R.styleable.BatteryHistoryChart_android_shadowDx:
                    dx = a.getFloat(attr, 0);
                    break;

                case R.styleable.BatteryHistoryChart_android_shadowDy:
                    dy = a.getFloat(attr, 0);
                    break;

                case R.styleable.BatteryHistoryChart_android_shadowRadius:
                    r = a.getFloat(attr, 0);
                    break;

                case R.styleable.BatteryHistoryChart_android_textColor:
                    mainTextAttrs.textColor = a.getColorStateList(attr);
                    headTextAttrs.textColor = a.getColorStateList(attr);
                    break;

                case R.styleable.BatteryHistoryChart_android_textSize:
                    mainTextAttrs.textSize = a.getDimensionPixelSize(attr, mainTextAttrs.textSize);
                    headTextAttrs.textSize = a.getDimensionPixelSize(attr, headTextAttrs.textSize);
                    break;

                case R.styleable.BatteryHistoryChart_android_typeface:
                    mainTextAttrs.typefaceIndex = a.getInt(attr, mainTextAttrs.typefaceIndex);
                    headTextAttrs.typefaceIndex = a.getInt(attr, headTextAttrs.typefaceIndex);
                    break;

                case R.styleable.BatteryHistoryChart_android_textStyle:
                    mainTextAttrs.styleIndex = a.getInt(attr, mainTextAttrs.styleIndex);
                    headTextAttrs.styleIndex = a.getInt(attr, headTextAttrs.styleIndex);
                    break;

                case R.styleable.BatteryHistoryChart_barPrimaryColor:
                    mBatteryBackgroundPaint.setColor(a.getInt(attr, 0));
                    mScreenOnPaint.setColor(a.getInt(attr, 0));
                    mGpsOnPaint.setColor(a.getInt(attr, 0));
                    mCameraOnPaint.setColor(a.getInt(attr, 0));
                    mFlashlightOnPaint.setColor(a.getInt(attr, 0));
                    mWifiRunningPaint.setColor(a.getInt(attr, 0));
                    mCpuRunningPaint.setColor(a.getInt(attr, 0));
                    mChargingPaint.setColor(a.getInt(attr, 0));
                    break;

                case R.styleable.BatteryHistoryChart_barPredictionColor:
                    mTimeRemainPaint.setColor(a.getInt(attr, 0));
                    break;

                case R.styleable.BatteryHistoryChart_chartMinHeight:
                    mChartMinHeight = a.getDimensionPixelSize(attr, 0);
                    break;
            }
        }

        a.recycle();

        mainTextAttrs.apply(context, mTextPaint);
        headTextAttrs.apply(context, mHeaderTextPaint);

        mDateLinePaint.set(mTextPaint);
        mDateLinePaint.setStyle(Paint.Style.STROKE);
        int hairlineWidth = mThinLineWidth/2;
        if (hairlineWidth < 1) {
            hairlineWidth = 1;
        }
        mDateLinePaint.setStrokeWidth(hairlineWidth);
        mDateLinePaint.setPathEffect(new DashPathEffect(new float[] {
                mThinLineWidth * 2, mThinLineWidth * 2 }, 0));

        if (shadowcolor != 0) {
            mTextPaint.setShadowLayer(r, dx, dy, shadowcolor);
            mHeaderTextPaint.setShadowLayer(r, dx, dy, shadowcolor);
        }
    }

    void setStats(BatteryStats stats, Intent broadcast) {
        mStats = stats;
        mBatteryBroadcast = broadcast;

        if (DEBUG) Log.d(TAG, "Setting stats...");

        final long elapsedRealtimeUs = SystemClock.elapsedRealtime() * 1000;

        long uSecTime = mStats.computeBatteryRealtime(elapsedRealtimeUs,
                BatteryStats.STATS_SINCE_CHARGED);
        mStatsPeriod = uSecTime;
        mChargingLabel = getContext().getString(R.string.battery_stats_charging_label);
        mScreenOnLabel = getContext().getString(R.string.battery_stats_screen_on_label);
        mGpsOnLabel = getContext().getString(R.string.battery_stats_gps_on_label);
        mCameraOnLabel = getContext().getString(R.string.battery_stats_camera_on_label);
        mFlashlightOnLabel = getContext().getString(R.string.battery_stats_flashlight_on_label);
        mWifiRunningLabel = getContext().getString(R.string.battery_stats_wifi_running_label);
        mCpuRunningLabel = getContext().getString(R.string.battery_stats_wake_lock_label);
        mPhoneSignalLabel = getContext().getString(R.string.battery_stats_phone_signal_label);

        mMaxPercentLabelString = Utils.formatPercentage(100);
        mMinPercentLabelString = Utils.formatPercentage(0);

        mBatteryLevel = com.android.settings.Utils.getBatteryLevel(mBatteryBroadcast);
        String batteryPercentString = Utils.formatPercentage(mBatteryLevel);
        long remainingTimeUs = 0;
        mDischarging = true;
        if (mBatteryBroadcast.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0) == 0) {
            final long drainTime = mStats.computeBatteryTimeRemaining(elapsedRealtimeUs);
            if (drainTime > 0) {
                remainingTimeUs = drainTime;
                String timeString = Formatter.formatShortElapsedTime(getContext(),
                        drainTime / 1000);
                mChargeLabelString = getContext().getResources().getString(
                        R.string.power_discharging_duration, batteryPercentString, timeString);
            } else {
                mChargeLabelString = batteryPercentString;
            }
        } else {
            final long chargeTime = mStats.computeChargeTimeRemaining(elapsedRealtimeUs);
            final String statusLabel = com.android.settings.Utils.getBatteryStatus(getResources(),
                    mBatteryBroadcast);
            final int status = mBatteryBroadcast.getIntExtra(BatteryManager.EXTRA_STATUS,
                    BatteryManager.BATTERY_STATUS_UNKNOWN);
            if (chargeTime > 0 && status != BatteryManager.BATTERY_STATUS_FULL) {
                mDischarging = false;
                remainingTimeUs = chargeTime;
                String timeString = Formatter.formatShortElapsedTime(getContext(),
                        chargeTime / 1000);
                int plugType = mBatteryBroadcast.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0);
                int resId;
                if (plugType == BatteryManager.BATTERY_PLUGGED_AC) {
                    resId = R.string.power_charging_duration_ac;
                } else if (plugType == BatteryManager.BATTERY_PLUGGED_USB) {
                    resId = R.string.power_charging_duration_usb;
                } else if (plugType == BatteryManager.BATTERY_PLUGGED_WIRELESS) {
                    resId = R.string.power_charging_duration_wireless;
                } else {
                    resId = R.string.power_charging_duration;
                }
                mChargeLabelString = getContext().getResources().getString(
                        resId, batteryPercentString, timeString);
            } else {
                mChargeLabelString = getContext().getResources().getString(
                        R.string.power_charging, batteryPercentString, statusLabel);
            }
        }
        mDrainString = "";
        mChargeDurationString = "";
        setContentDescription(mChargeLabelString);

        int pos = 0;
        int lastInteresting = 0;
        byte lastLevel = -1;
        mBatLow = 0;
        mBatHigh = 100;
        mStartWallTime = 0;
        mEndDataWallTime = 0;
        mEndWallTime = 0;
        mHistStart = 0;
        mHistEnd = 0;
        long lastWallTime = 0;
        long lastRealtime = 0;
        int aggrStates = 0;
        int aggrStates2 = 0;
        boolean first = true;
        if (stats.startIteratingHistoryLocked()) {
            final HistoryItem rec = new HistoryItem();
            while (stats.getNextHistoryLocked(rec)) {
                pos++;
                if (first) {
                    first = false;
                    mHistStart = rec.time;
                }
                if (rec.cmd == HistoryItem.CMD_CURRENT_TIME
                        || rec.cmd == HistoryItem.CMD_RESET) {
                    // If there is a ridiculously large jump in time, then we won't be
                    // able to create a good chart with that data, so just ignore the
                    // times we got before and pretend like our data extends back from
                    // the time we have now.
                    // Also, if we are getting a time change and we are less than 5 minutes
                    // since the start of the history real time, then also use this new
                    // time to compute the base time, since whatever time we had before is
                    // pretty much just noise.
                    if (rec.currentTime > (lastWallTime+(180*24*60*60*1000L))
                            || rec.time < (mHistStart+(5*60*1000L))) {
                        mStartWallTime = 0;
                    }
                    lastWallTime = rec.currentTime;
                    lastRealtime = rec.time;
                    if (mStartWallTime == 0) {
                        mStartWallTime = lastWallTime - (lastRealtime-mHistStart);
                    }
                }
                if (rec.isDeltaData()) {
                    if (rec.batteryLevel != lastLevel || pos == 1) {
                        lastLevel = rec.batteryLevel;
                    }
                    lastInteresting = pos;
                    mHistDataEnd = rec.time;
                    aggrStates |= rec.states;
                    aggrStates2 |= rec.states2;
                }
            }
        }
        mHistEnd = mHistDataEnd + (remainingTimeUs/1000);
        mEndDataWallTime = lastWallTime + mHistDataEnd - lastRealtime;
        mEndWallTime = mEndDataWallTime + (remainingTimeUs/1000);
        mNumHist = lastInteresting;
        mHaveGps = (aggrStates&HistoryItem.STATE_GPS_ON_FLAG) != 0;
        mHaveFlashlight = (aggrStates2&HistoryItem.STATE2_FLASHLIGHT_FLAG) != 0;
        mHaveCamera = (aggrStates2&HistoryItem.STATE2_CAMERA_FLAG) != 0;
        mHaveWifi = (aggrStates2&HistoryItem.STATE2_WIFI_RUNNING_FLAG) != 0
                || (aggrStates&(HistoryItem.STATE_WIFI_FULL_LOCK_FLAG
                        |HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG
                        |HistoryItem.STATE_WIFI_SCAN_FLAG)) != 0;
        if (!com.android.settings.Utils.isWifiOnly(getContext())) {
            mHavePhoneSignal = true;
        }
        if (mHistEnd <= mHistStart) mHistEnd = mHistStart+1;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        mMaxPercentLabelStringWidth = (int)mTextPaint.measureText(mMaxPercentLabelString);
        mMinPercentLabelStringWidth = (int)mTextPaint.measureText(mMinPercentLabelString);
        mDrainStringWidth = (int)mHeaderTextPaint.measureText(mDrainString);
        mChargeLabelStringWidth = (int)mHeaderTextPaint.measureText(mChargeLabelString);
        mChargeDurationStringWidth = (int)mHeaderTextPaint.measureText(mChargeDurationString);
        mTextAscent = (int)mTextPaint.ascent();
        mTextDescent = (int)mTextPaint.descent();
        mHeaderTextAscent = (int)mHeaderTextPaint.ascent();
        mHeaderTextDescent = (int)mHeaderTextPaint.descent();
        int headerTextHeight = mHeaderTextDescent - mHeaderTextAscent;
        mHeaderHeight = headerTextHeight*2 - mTextAscent;
        setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec),
                getDefaultSize(mChartMinHeight+mHeaderHeight, heightMeasureSpec));
    }

    void finishPaths(int w, int h, int levelh, int startX, int y, Path curLevelPath,
            int lastX, boolean lastCharging, boolean lastScreenOn, boolean lastGpsOn,
            boolean lastFlashlightOn, boolean lastCameraOn, boolean lastWifiRunning,
            boolean lastCpuRunning, Path lastPath) {
        if (curLevelPath != null) {
            if (lastX >= 0 && lastX < w) {
                if (lastPath != null) {
                    lastPath.lineTo(w, y);
                }
                curLevelPath.lineTo(w, y);
            }
            curLevelPath.lineTo(w, mLevelTop+levelh);
            curLevelPath.lineTo(startX, mLevelTop+levelh);
            curLevelPath.close();
        }

        if (lastCharging) {
            mChargingPath.lineTo(w, h-mChargingOffset);
        }
        if (lastScreenOn) {
            mScreenOnPath.lineTo(w, h-mScreenOnOffset);
        }
        if (lastGpsOn) {
            mGpsOnPath.lineTo(w, h-mGpsOnOffset);
        }
        if (lastFlashlightOn) {
            mFlashlightOnPath.lineTo(w, h-mFlashlightOnOffset);
        }
        if (lastCameraOn) {
            mCameraOnPath.lineTo(w, h-mCameraOnOffset);
        }
        if (lastWifiRunning) {
            mWifiRunningPath.lineTo(w, h-mWifiRunningOffset);
        }
        if (lastCpuRunning) {
            mCpuRunningPath.lineTo(w, h - mCpuRunningOffset);
        }
        if (mHavePhoneSignal) {
            mPhoneSignalChart.finish(w);
        }
    }

    private boolean is24Hour() {
        return DateFormat.is24HourFormat(getContext());
    }

    private boolean isDayFirst() {
        final String value = LocaleData.get(getResources().getConfiguration().locale)
                .getDateFormat(java.text.DateFormat.SHORT);
        return value.indexOf('M') > value.indexOf('d');
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);

        if (DEBUG) Log.d(TAG, "onSizeChanged: " + oldw + "x" + oldh + " to " + w + "x" + h);

        if (mLastWidth == w && mLastHeight == h) {
            return;
        }

        if (mLastWidth == 0 || mLastHeight == 0) {
            return;
        }

        if (DEBUG) Log.d(TAG, "Rebuilding chart for: " + w + "x" + h);

        mLastWidth = w;
        mLastHeight = h;
        mBitmap = null;
        mCanvas = null;

        int textHeight = mTextDescent - mTextAscent;
        if (h > ((textHeight*10)+mChartMinHeight)) {
            mLargeMode = true;
            if (h > (textHeight*15)) {
                // Plenty of room for the chart.
                mLineWidth = textHeight/2;
            } else {
                // Compress lines to make more room for chart.
                mLineWidth = textHeight/3;
            }
        } else {
            mLargeMode = false;
            mLineWidth = mThinLineWidth;
        }
        if (mLineWidth <= 0) mLineWidth = 1;

        mLevelTop = mHeaderHeight;
        mLevelLeft = mMaxPercentLabelStringWidth + mThinLineWidth*3;
        mLevelRight = w;
        int levelWidth = mLevelRight-mLevelLeft;

        mTextPaint.setStrokeWidth(mThinLineWidth);
        mBatteryGoodPaint.setStrokeWidth(mThinLineWidth);
        mBatteryWarnPaint.setStrokeWidth(mThinLineWidth);
        mBatteryCriticalPaint.setStrokeWidth(mThinLineWidth);
        mChargingPaint.setStrokeWidth(mLineWidth);
        mScreenOnPaint.setStrokeWidth(mLineWidth);
        mGpsOnPaint.setStrokeWidth(mLineWidth);
        mCameraOnPaint.setStrokeWidth(mLineWidth);
        mFlashlightOnPaint.setStrokeWidth(mLineWidth);
        mWifiRunningPaint.setStrokeWidth(mLineWidth);
        mCpuRunningPaint.setStrokeWidth(mLineWidth);
        mDebugRectPaint.setStrokeWidth(1);

        int fullBarOffset = textHeight + mLineWidth;

        if (mLargeMode) {
            mChargingOffset = mLineWidth;
            mScreenOnOffset = mChargingOffset + fullBarOffset;
            mCpuRunningOffset = mScreenOnOffset + fullBarOffset;
            mWifiRunningOffset = mCpuRunningOffset + fullBarOffset;
            mGpsOnOffset = mWifiRunningOffset + (mHaveWifi ? fullBarOffset : 0);
            mFlashlightOnOffset = mGpsOnOffset + (mHaveGps ? fullBarOffset : 0);
            mCameraOnOffset = mFlashlightOnOffset + (mHaveFlashlight ? fullBarOffset : 0);
            mPhoneSignalOffset = mCameraOnOffset + (mHaveCamera ? fullBarOffset : 0);
            mLevelOffset = mPhoneSignalOffset + (mHavePhoneSignal ? fullBarOffset : 0)
                    + mLineWidth*2 + mLineWidth/2;
            if (mHavePhoneSignal) {
                mPhoneSignalChart.init(w);
            }
        } else {
            mScreenOnOffset = mGpsOnOffset = mCameraOnOffset = mFlashlightOnOffset =
                    mWifiRunningOffset = mCpuRunningOffset = mChargingOffset =
                    mPhoneSignalOffset = 0;
            mLevelOffset = fullBarOffset + mThinLineWidth*4;
            if (mHavePhoneSignal) {
                mPhoneSignalChart.init(0);
            }
        }

        mBatLevelPath.reset();
        mBatGoodPath.reset();
        mBatWarnPath.reset();
        mTimeRemainPath.reset();
        mBatCriticalPath.reset();
        mScreenOnPath.reset();
        mGpsOnPath.reset();
        mFlashlightOnPath.reset();
        mCameraOnPath.reset();
        mWifiRunningPath.reset();
        mCpuRunningPath.reset();
        mChargingPath.reset();

        mTimeLabels.clear();
        mDateLabels.clear();

        final long walltimeStart = mStartWallTime;
        final long walltimeChange = mEndWallTime > walltimeStart
                ? (mEndWallTime-walltimeStart) : 1;
        long curWalltime = mStartWallTime;
        long lastRealtime = 0;

        final int batLow = mBatLow;
        final int batChange = mBatHigh-mBatLow;

        final int levelh = h - mLevelOffset - mLevelTop;
        mLevelBottom = mLevelTop + levelh;

        int x = mLevelLeft, y = 0, startX = mLevelLeft, lastX = -1, lastY = -1;
        int i = 0;
        Path curLevelPath = null;
        Path lastLinePath = null;
        boolean lastCharging = false, lastScreenOn = false, lastGpsOn = false;
        boolean lastFlashlightOn = false, lastCameraOn = false;
        boolean lastWifiRunning = false, lastWifiSupplRunning = false, lastCpuRunning = false;
        int lastWifiSupplState = BatteryStats.WIFI_SUPPL_STATE_INVALID;
        final int N = mNumHist;
        if (mEndDataWallTime > mStartWallTime && mStats.startIteratingHistoryLocked()) {
            final HistoryItem rec = new HistoryItem();
            while (mStats.getNextHistoryLocked(rec) && i < N) {
                if (rec.isDeltaData()) {
                    curWalltime += rec.time-lastRealtime;
                    lastRealtime = rec.time;
                    x = mLevelLeft + (int)(((curWalltime-walltimeStart)*levelWidth)/walltimeChange);
                    if (x < 0) {
                        x = 0;
                    }
                    if (false) {
                        StringBuilder sb = new StringBuilder(128);
                        sb.append("walloff=");
                        TimeUtils.formatDuration(curWalltime - walltimeStart, sb);
                        sb.append(" wallchange=");
                        TimeUtils.formatDuration(walltimeChange, sb);
                        sb.append(" x=");
                        sb.append(x);
                        Log.d("foo", sb.toString());
                    }
                    y = mLevelTop + levelh - ((rec.batteryLevel-batLow)*(levelh-1))/batChange;

                    if (lastX != x) {
                        // We have moved by at least a pixel.
                        if (lastY != y) {
                            // Don't plot changes within a pixel.
                            Path path;
                            byte value = rec.batteryLevel;
                            if (value <= mBatteryCriticalLevel) path = mBatCriticalPath;
                            else if (value <= mBatteryWarnLevel) path = mBatWarnPath;
                            else path = null; //mBatGoodPath;

                            if (path != lastLinePath) {
                                if (lastLinePath != null) {
                                    lastLinePath.lineTo(x, y);
                                }
                                if (path != null) {
                                    path.moveTo(x, y);
                                }
                                lastLinePath = path;
                            } else if (path != null) {
                                path.lineTo(x, y);
                            }

                            if (curLevelPath == null) {
                                curLevelPath = mBatLevelPath;
                                curLevelPath.moveTo(x, y);
                                startX = x;
                            } else {
                                curLevelPath.lineTo(x, y);
                            }
                            lastX = x;
                            lastY = y;
                        }
                    }

                    if (mLargeMode) {
                        final boolean charging =
                            (rec.states&HistoryItem.STATE_BATTERY_PLUGGED_FLAG) != 0;
                        if (charging != lastCharging) {
                            if (charging) {
                                mChargingPath.moveTo(x, h-mChargingOffset);
                            } else {
                                mChargingPath.lineTo(x, h-mChargingOffset);
                            }
                            lastCharging = charging;
                        }

                        final boolean screenOn =
                            (rec.states&HistoryItem.STATE_SCREEN_ON_FLAG) != 0;
                        if (screenOn != lastScreenOn) {
                            if (screenOn) {
                                mScreenOnPath.moveTo(x, h-mScreenOnOffset);
                            } else {
                                mScreenOnPath.lineTo(x, h-mScreenOnOffset);
                            }
                            lastScreenOn = screenOn;
                        }

                        final boolean gpsOn =
                            (rec.states&HistoryItem.STATE_GPS_ON_FLAG) != 0;
                        if (gpsOn != lastGpsOn) {
                            if (gpsOn) {
                                mGpsOnPath.moveTo(x, h-mGpsOnOffset);
                            } else {
                                mGpsOnPath.lineTo(x, h-mGpsOnOffset);
                            }
                            lastGpsOn = gpsOn;
                        }

                        final boolean flashlightOn =
                            (rec.states2&HistoryItem.STATE2_FLASHLIGHT_FLAG) != 0;
                        if (flashlightOn != lastFlashlightOn) {
                            if (flashlightOn) {
                                mFlashlightOnPath.moveTo(x, h-mFlashlightOnOffset);
                            } else {
                                mFlashlightOnPath.lineTo(x, h-mFlashlightOnOffset);
                            }
                            lastFlashlightOn = flashlightOn;
                        }

                        final boolean cameraOn =
                            (rec.states2&HistoryItem.STATE2_CAMERA_FLAG) != 0;
                        if (cameraOn != lastCameraOn) {
                            if (cameraOn) {
                                mCameraOnPath.moveTo(x, h-mCameraOnOffset);
                            } else {
                                mCameraOnPath.lineTo(x, h-mCameraOnOffset);
                            }
                            lastCameraOn = cameraOn;
                        }

                        final int wifiSupplState =
                            ((rec.states2&HistoryItem.STATE2_WIFI_SUPPL_STATE_MASK)
                                    >> HistoryItem.STATE2_WIFI_SUPPL_STATE_SHIFT);
                        boolean wifiRunning;
                        if (lastWifiSupplState != wifiSupplState) {
                            lastWifiSupplState = wifiSupplState;
                            switch (wifiSupplState) {
                                case BatteryStats.WIFI_SUPPL_STATE_DISCONNECTED:
                                case BatteryStats.WIFI_SUPPL_STATE_DORMANT:
                                case BatteryStats.WIFI_SUPPL_STATE_INACTIVE:
                                case BatteryStats.WIFI_SUPPL_STATE_INTERFACE_DISABLED:
                                case BatteryStats.WIFI_SUPPL_STATE_INVALID:
                                case BatteryStats.WIFI_SUPPL_STATE_UNINITIALIZED:
                                    wifiRunning = lastWifiSupplRunning = false;
                                    break;
                                default:
                                    wifiRunning = lastWifiSupplRunning = true;
                                    break;
                            }
                        } else {
                            wifiRunning = lastWifiSupplRunning;
                        }
                        if ((rec.states&(HistoryItem.STATE_WIFI_FULL_LOCK_FLAG
                                |HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG
                                |HistoryItem.STATE_WIFI_SCAN_FLAG)) != 0) {
                            wifiRunning = true;
                        }
                        if (wifiRunning != lastWifiRunning) {
                            if (wifiRunning) {
                                mWifiRunningPath.moveTo(x, h-mWifiRunningOffset);
                            } else {
                                mWifiRunningPath.lineTo(x, h-mWifiRunningOffset);
                            }
                            lastWifiRunning = wifiRunning;
                        }

                        final boolean cpuRunning =
                            (rec.states&HistoryItem.STATE_CPU_RUNNING_FLAG) != 0;
                        if (cpuRunning != lastCpuRunning) {
                            if (cpuRunning) {
                                mCpuRunningPath.moveTo(x, h - mCpuRunningOffset);
                            } else {
                                mCpuRunningPath.lineTo(x, h - mCpuRunningOffset);
                            }
                            lastCpuRunning = cpuRunning;
                        }

                        if (mLargeMode && mHavePhoneSignal) {
                            int bin;
                            if (((rec.states&HistoryItem.STATE_PHONE_STATE_MASK)
                                    >> HistoryItem.STATE_PHONE_STATE_SHIFT)
                                    == ServiceState.STATE_POWER_OFF) {
                                bin = 0;
                            } else if ((rec.states&HistoryItem.STATE_PHONE_SCANNING_FLAG) != 0) {
                                bin = 1;
                            } else {
                                bin = (rec.states&HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_MASK)
                                        >> HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_SHIFT;
                                bin += 2;
                            }
                            mPhoneSignalChart.addTick(x, bin);
                        }
                    }

                } else {
                    long lastWalltime = curWalltime;
                    if (rec.cmd == HistoryItem.CMD_CURRENT_TIME
                            || rec.cmd == HistoryItem.CMD_RESET) {
                        if (rec.currentTime >= mStartWallTime) {
                            curWalltime = rec.currentTime;
                        } else {
                            curWalltime = mStartWallTime + (rec.time-mHistStart);
                        }
                        lastRealtime = rec.time;
                    }

                    if (rec.cmd != HistoryItem.CMD_OVERFLOW
                            && (rec.cmd != HistoryItem.CMD_CURRENT_TIME
                                    || Math.abs(lastWalltime-curWalltime) > (60*60*1000))) {
                        if (curLevelPath != null) {
                            finishPaths(x+1, h, levelh, startX, lastY, curLevelPath, lastX,
                                    lastCharging, lastScreenOn, lastGpsOn, lastFlashlightOn,
                                    lastCameraOn, lastWifiRunning, lastCpuRunning, lastLinePath);
                            lastX = lastY = -1;
                            curLevelPath = null;
                            lastLinePath = null;
                            lastCharging = lastScreenOn = lastGpsOn = lastFlashlightOn =
                                    lastCameraOn = lastCpuRunning = false;
                        }
                    }
                }

                i++;
            }
            mStats.finishIteratingHistoryLocked();
        }

        if (lastY < 0 || lastX < 0) {
            // Didn't get any data...
            x = lastX = mLevelLeft;
            y = lastY = mLevelTop + levelh - ((mBatteryLevel-batLow)*(levelh-1))/batChange;
            Path path;
            byte value = (byte)mBatteryLevel;
            if (value <= mBatteryCriticalLevel) path = mBatCriticalPath;
            else if (value <= mBatteryWarnLevel) path = mBatWarnPath;
            else path = null; //mBatGoodPath;
            if (path != null) {
                path.moveTo(x, y);
                lastLinePath = path;
            }
            mBatLevelPath.moveTo(x, y);
            curLevelPath = mBatLevelPath;
            x = w;
        } else {
            // Figure out where the actual data ends on the screen.
            x = mLevelLeft + (int)(((mEndDataWallTime-walltimeStart)*levelWidth)/walltimeChange);
            if (x < 0) {
                x = 0;
            }
        }

        finishPaths(x, h, levelh, startX, lastY, curLevelPath, lastX,
                lastCharging, lastScreenOn, lastGpsOn, lastFlashlightOn, lastCameraOn,
                lastWifiRunning, lastCpuRunning, lastLinePath);

        if (x < w) {
            // If we reserved room for the remaining time, create a final path to draw
            // that part of the UI.
            mTimeRemainPath.moveTo(x, lastY);
            int fullY = mLevelTop + levelh - ((100-batLow)*(levelh-1))/batChange;
            int emptyY = mLevelTop + levelh - ((0-batLow)*(levelh-1))/batChange;
            if (mDischarging) {
                mTimeRemainPath.lineTo(mLevelRight, emptyY);
            } else {
                mTimeRemainPath.lineTo(mLevelRight, fullY);
                mTimeRemainPath.lineTo(mLevelRight, emptyY);
            }
            mTimeRemainPath.lineTo(x, emptyY);
            mTimeRemainPath.close();
        }

        if (mStartWallTime > 0 && mEndWallTime > mStartWallTime) {
            // Create the time labels at the bottom.
            boolean is24hr = is24Hour();
            Calendar calStart = Calendar.getInstance();
            calStart.setTimeInMillis(mStartWallTime);
            calStart.set(Calendar.MILLISECOND, 0);
            calStart.set(Calendar.SECOND, 0);
            calStart.set(Calendar.MINUTE, 0);
            long startRoundTime = calStart.getTimeInMillis();
            if (startRoundTime < mStartWallTime) {
                calStart.set(Calendar.HOUR_OF_DAY, calStart.get(Calendar.HOUR_OF_DAY)+1);
                startRoundTime = calStart.getTimeInMillis();
            }
            Calendar calEnd = Calendar.getInstance();
            calEnd.setTimeInMillis(mEndWallTime);
            calEnd.set(Calendar.MILLISECOND, 0);
            calEnd.set(Calendar.SECOND, 0);
            calEnd.set(Calendar.MINUTE, 0);
            long endRoundTime = calEnd.getTimeInMillis();
            if (startRoundTime < endRoundTime) {
                addTimeLabel(calStart, mLevelLeft, mLevelRight, is24hr);
                Calendar calMid = Calendar.getInstance();
                calMid.setTimeInMillis(mStartWallTime+((mEndWallTime-mStartWallTime)/2));
                calMid.set(Calendar.MILLISECOND, 0);
                calMid.set(Calendar.SECOND, 0);
                calMid.set(Calendar.MINUTE, 0);
                long calMidMillis = calMid.getTimeInMillis();
                if (calMidMillis > startRoundTime && calMidMillis < endRoundTime) {
                    addTimeLabel(calMid, mLevelLeft, mLevelRight, is24hr);
                }
                addTimeLabel(calEnd, mLevelLeft, mLevelRight, is24hr);
            }

            // Create the date labels if the chart includes multiple days
            if (calStart.get(Calendar.DAY_OF_YEAR) != calEnd.get(Calendar.DAY_OF_YEAR) ||
                    calStart.get(Calendar.YEAR) != calEnd.get(Calendar.YEAR)) {
                boolean isDayFirst = isDayFirst();
                calStart.set(Calendar.HOUR_OF_DAY, 0);
                startRoundTime = calStart.getTimeInMillis();
                if (startRoundTime < mStartWallTime) {
                    calStart.set(Calendar.DAY_OF_YEAR, calStart.get(Calendar.DAY_OF_YEAR) + 1);
                    startRoundTime = calStart.getTimeInMillis();
                }
                calEnd.set(Calendar.HOUR_OF_DAY, 0);
                endRoundTime = calEnd.getTimeInMillis();
                if (startRoundTime < endRoundTime) {
                    addDateLabel(calStart, mLevelLeft, mLevelRight, isDayFirst);
                    Calendar calMid = Calendar.getInstance();
                    calMid.setTimeInMillis(startRoundTime + ((endRoundTime - startRoundTime) / 2));
                    calMid.set(Calendar.HOUR_OF_DAY, 0);
                    long calMidMillis = calMid.getTimeInMillis();
                    if (calMidMillis > startRoundTime && calMidMillis < endRoundTime) {
                        addDateLabel(calMid, mLevelLeft, mLevelRight, isDayFirst);
                    }
                }
                addDateLabel(calEnd, mLevelLeft, mLevelRight, isDayFirst);
            }
        }

        if (mTimeLabels.size() < 2) {
            // If there are fewer than 2 time labels, then they are useless.  Just
            // show an axis label giving the entire duration.
            mDurationString = Formatter.formatShortElapsedTime(getContext(),
                    mEndWallTime - mStartWallTime);
            mDurationStringWidth = (int)mTextPaint.measureText(mDurationString);
        } else {
            mDurationString = null;
            mDurationStringWidth = 0;
        }
    }

    void addTimeLabel(Calendar cal, int levelLeft, int levelRight, boolean is24hr) {
        final long walltimeStart = mStartWallTime;
        final long walltimeChange = mEndWallTime-walltimeStart;
        mTimeLabels.add(new TimeLabel(mTextPaint,
                levelLeft + (int)(((cal.getTimeInMillis()-walltimeStart)*(levelRight-levelLeft))
                        / walltimeChange),
                cal, is24hr));
    }

    void addDateLabel(Calendar cal, int levelLeft, int levelRight, boolean isDayFirst) {
        final long walltimeStart = mStartWallTime;
        final long walltimeChange = mEndWallTime-walltimeStart;
        mDateLabels.add(new DateLabel(mTextPaint,
                levelLeft + (int)(((cal.getTimeInMillis()-walltimeStart)*(levelRight-levelLeft))
                        / walltimeChange),
                cal, isDayFirst));
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        final int width = getWidth();
        final int height = getHeight();

        //buildBitmap(width, height);

        if (DEBUG) Log.d(TAG, "onDraw: " + width + "x" + height);
        //canvas.drawBitmap(mBitmap, 0, 0, null);
        drawChart(canvas, width, height);
    }

    void buildBitmap(int width, int height) {
        if (mBitmap != null && width == mBitmap.getWidth() && height == mBitmap.getHeight()) {
            return;
        }

        if (DEBUG) Log.d(TAG, "buildBitmap: " + width + "x" + height);

        mBitmap = Bitmap.createBitmap(getResources().getDisplayMetrics(), width, height,
                Bitmap.Config.ARGB_8888);
        mCanvas = new Canvas(mBitmap);
        drawChart(mCanvas, width, height);
    }

    void drawChart(Canvas canvas, int width, int height) {
        final boolean layoutRtl = isLayoutRtl();
        final int textStartX = layoutRtl ? width : 0;
        final int textEndX = layoutRtl ? 0 : width;
        final Paint.Align textAlignLeft = layoutRtl ? Paint.Align.RIGHT : Paint.Align.LEFT;
        final Paint.Align textAlignRight = layoutRtl ? Paint.Align.LEFT : Paint.Align.RIGHT;

        if (DEBUG) {
            canvas.drawRect(1, 1, width, height, mDebugRectPaint);
        }

        if (DEBUG) Log.d(TAG, "Drawing level path.");
        canvas.drawPath(mBatLevelPath, mBatteryBackgroundPaint);
        if (!mTimeRemainPath.isEmpty()) {
            if (DEBUG) Log.d(TAG, "Drawing time remain path.");
            canvas.drawPath(mTimeRemainPath, mTimeRemainPaint);
        }
        if (mTimeLabels.size() > 1) {
            int y = mLevelBottom - mTextAscent + (mThinLineWidth*4);
            int ytick = mLevelBottom+mThinLineWidth+(mThinLineWidth/2);
            mTextPaint.setTextAlign(Paint.Align.LEFT);
            int lastX = 0;
            for (int i=0; i<mTimeLabels.size(); i++) {
                TimeLabel label = mTimeLabels.get(i);
                if (i == 0) {
                    int x = label.x - label.width/2;
                    if (x < 0) {
                        x = 0;
                    }
                    if (DEBUG) Log.d(TAG, "Drawing left label: " + label.label + " @ " + x);
                    canvas.drawText(label.label, x, y, mTextPaint);
                    canvas.drawLine(label.x, ytick, label.x, ytick+mThinLineWidth, mTextPaint);
                    lastX = x + label.width;
                } else if (i < (mTimeLabels.size()-1)) {
                    int x = label.x - label.width/2;
                    if (x < (lastX+mTextAscent)) {
                        continue;
                    }
                    TimeLabel nextLabel = mTimeLabels.get(i+1);
                    if (x > (width-nextLabel.width-mTextAscent)) {
                        continue;
                    }
                    if (DEBUG) Log.d(TAG, "Drawing middle label: " + label.label + " @ " + x);
                    canvas.drawText(label.label, x, y, mTextPaint);
                    canvas.drawLine(label.x, ytick, label.x, ytick + mThinLineWidth, mTextPaint);
                    lastX = x + label.width;
                } else {
                    int x = label.x - label.width/2;
                    if ((x+label.width) >= width) {
                        x = width-1-label.width;
                    }
                    if (DEBUG) Log.d(TAG, "Drawing right label: " + label.label + " @ " + x);
                    canvas.drawText(label.label, x, y, mTextPaint);
                    canvas.drawLine(label.x, ytick, label.x, ytick+mThinLineWidth, mTextPaint);
                }
            }
        } else if (mDurationString != null) {
            int y = mLevelBottom - mTextAscent + (mThinLineWidth*4);
            mTextPaint.setTextAlign(Paint.Align.LEFT);
            canvas.drawText(mDurationString,
                    mLevelLeft + (mLevelRight-mLevelLeft)/2 - mDurationStringWidth/2,
                    y, mTextPaint);
        }

        int headerTop = -mHeaderTextAscent + (mHeaderTextDescent-mHeaderTextAscent)/3;
        mHeaderTextPaint.setTextAlign(textAlignLeft);
        if (DEBUG) Log.d(TAG, "Drawing charge label string: " + mChargeLabelString);
        canvas.drawText(mChargeLabelString, textStartX, headerTop, mHeaderTextPaint);
        int stringHalfWidth = mChargeDurationStringWidth / 2;
        if (layoutRtl) stringHalfWidth = -stringHalfWidth;
        int headerCenter = ((width-mChargeDurationStringWidth-mDrainStringWidth)/2)
                + (layoutRtl ? mDrainStringWidth : mChargeLabelStringWidth);
        if (DEBUG) Log.d(TAG, "Drawing charge duration string: " + mChargeDurationString);
        canvas.drawText(mChargeDurationString, headerCenter - stringHalfWidth, headerTop,
                mHeaderTextPaint);
        mHeaderTextPaint.setTextAlign(textAlignRight);
        if (DEBUG) Log.d(TAG, "Drawing drain string: " + mDrainString);
        canvas.drawText(mDrainString, textEndX, headerTop, mHeaderTextPaint);

        if (!mBatGoodPath.isEmpty()) {
            if (DEBUG) Log.d(TAG, "Drawing good battery path");
            canvas.drawPath(mBatGoodPath, mBatteryGoodPaint);
        }
        if (!mBatWarnPath.isEmpty()) {
            if (DEBUG) Log.d(TAG, "Drawing warn battery path");
            canvas.drawPath(mBatWarnPath, mBatteryWarnPaint);
        }
        if (!mBatCriticalPath.isEmpty()) {
            if (DEBUG) Log.d(TAG, "Drawing critical battery path");
            canvas.drawPath(mBatCriticalPath, mBatteryCriticalPaint);
        }
        if (mHavePhoneSignal) {
            if (DEBUG) Log.d(TAG, "Drawing phone signal path");
            int top = height-mPhoneSignalOffset - (mLineWidth/2);
            mPhoneSignalChart.draw(canvas, top, mLineWidth);
        }
        if (!mScreenOnPath.isEmpty()) {
            if (DEBUG) Log.d(TAG, "Drawing screen on path");
            canvas.drawPath(mScreenOnPath, mScreenOnPaint);
        }
        if (!mChargingPath.isEmpty()) {
            if (DEBUG) Log.d(TAG, "Drawing charging path");
            canvas.drawPath(mChargingPath, mChargingPaint);
        }
        if (mHaveGps) {
            if (!mGpsOnPath.isEmpty()) {
                if (DEBUG) Log.d(TAG, "Drawing gps path");
                canvas.drawPath(mGpsOnPath, mGpsOnPaint);
            }
        }
        if (mHaveFlashlight) {
            if (!mFlashlightOnPath.isEmpty()) {
                if (DEBUG) Log.d(TAG, "Drawing flashlight path");
                canvas.drawPath(mFlashlightOnPath, mFlashlightOnPaint);
            }
        }
        if (mHaveCamera) {
            if (!mCameraOnPath.isEmpty()) {
                if (DEBUG) Log.d(TAG, "Drawing camera path");
                canvas.drawPath(mCameraOnPath, mCameraOnPaint);
            }
        }
        if (mHaveWifi) {
            if (!mWifiRunningPath.isEmpty()) {
                if (DEBUG) Log.d(TAG, "Drawing wifi path");
                canvas.drawPath(mWifiRunningPath, mWifiRunningPaint);
            }
        }
        if (!mCpuRunningPath.isEmpty()) {
            if (DEBUG) Log.d(TAG, "Drawing running path");
            canvas.drawPath(mCpuRunningPath, mCpuRunningPaint);
        }

        if (mLargeMode) {
            if (DEBUG) Log.d(TAG, "Drawing large mode labels");
            Paint.Align align = mTextPaint.getTextAlign();
            mTextPaint.setTextAlign(textAlignLeft);  // large-mode labels always aligned to start
            if (mHavePhoneSignal) {
                canvas.drawText(mPhoneSignalLabel, textStartX,
                        height - mPhoneSignalOffset - mTextDescent, mTextPaint);
            }
            if (mHaveGps) {
                canvas.drawText(mGpsOnLabel, textStartX,
                        height - mGpsOnOffset - mTextDescent, mTextPaint);
            }
            if (mHaveFlashlight) {
                canvas.drawText(mFlashlightOnLabel, textStartX,
                        height - mFlashlightOnOffset - mTextDescent, mTextPaint);
            }
            if (mHaveCamera) {
                canvas.drawText(mCameraOnLabel, textStartX,
                        height - mCameraOnOffset - mTextDescent, mTextPaint);
            }
            if (mHaveWifi) {
                canvas.drawText(mWifiRunningLabel, textStartX,
                        height - mWifiRunningOffset - mTextDescent, mTextPaint);
            }
            canvas.drawText(mCpuRunningLabel, textStartX,
                    height - mCpuRunningOffset - mTextDescent, mTextPaint);
            canvas.drawText(mChargingLabel, textStartX,
                    height - mChargingOffset - mTextDescent, mTextPaint);
            canvas.drawText(mScreenOnLabel, textStartX,
                    height - mScreenOnOffset - mTextDescent, mTextPaint);
            mTextPaint.setTextAlign(align);
        }

        canvas.drawLine(mLevelLeft-mThinLineWidth, mLevelTop, mLevelLeft-mThinLineWidth,
                mLevelBottom+(mThinLineWidth/2), mTextPaint);
        if (mLargeMode) {
            for (int i=0; i<10; i++) {
                int y = mLevelTop + mThinLineWidth/2 + ((mLevelBottom-mLevelTop)*i)/10;
                canvas.drawLine(mLevelLeft-mThinLineWidth*2-mThinLineWidth/2, y,
                        mLevelLeft-mThinLineWidth-mThinLineWidth/2, y, mTextPaint);
            }
        }
        if (DEBUG) Log.d(TAG, "Drawing max percent, origw=" + mMaxPercentLabelStringWidth
                + ", noww=" + (int)mTextPaint.measureText(mMaxPercentLabelString));
        canvas.drawText(mMaxPercentLabelString, 0, mLevelTop, mTextPaint);
        canvas.drawText(mMinPercentLabelString,
                mMaxPercentLabelStringWidth-mMinPercentLabelStringWidth,
                mLevelBottom - mThinLineWidth, mTextPaint);
        canvas.drawLine(mLevelLeft/2, mLevelBottom+mThinLineWidth, width,
                mLevelBottom+mThinLineWidth, mTextPaint);

        if (mDateLabels.size() > 0) {
            int ytop = mLevelTop + mTextAscent;
            int ybottom = mLevelBottom;
            int lastLeft = mLevelRight;
            mTextPaint.setTextAlign(Paint.Align.LEFT);
            for (int i=mDateLabels.size()-1; i>=0; i--) {
                DateLabel label = mDateLabels.get(i);
                int left = label.x - mThinLineWidth;
                int x = label.x + mThinLineWidth*2;
                if ((x+label.width) >= lastLeft) {
                    x = label.x - mThinLineWidth*2 - label.width;
                    left = x - mThinLineWidth;
                    if (left >= lastLeft) {
                        // okay we give up.
                        continue;
                    }
                }
                if (left < mLevelLeft) {
                    // Won't fit on left, give up.
                    continue;
                }
                mDateLinePath.reset();
                mDateLinePath.moveTo(label.x, ytop);
                mDateLinePath.lineTo(label.x, ybottom);
                canvas.drawPath(mDateLinePath, mDateLinePaint);
                canvas.drawText(label.label, x, ytop - mTextAscent, mTextPaint);
            }
        }
    }
}

redpajama_set_name: RedPajamaGithub


text:
// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.codeInspection;

import com.intellij.codeInsight.daemon.GroupNames;
import com.intellij.codeInsight.daemon.JavaErrorMessages;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Key;
import com.intellij.psi.*;
import com.intellij.psi.util.ConstantEvaluationOverflowException;
import com.intellij.psi.util.TypeConversionUtil;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;

/**
 * @author cdr
 */
public class NumericOverflowInspection extends AbstractBaseJavaLocalInspectionTool {
  private static final Key<String> HAS_OVERFLOW_IN_CHILD = Key.create("HAS_OVERFLOW_IN_CHILD");

  @Nls
  @NotNull
  @Override
  public String getGroupDisplayName() {
    return GroupNames.NUMERIC_GROUP_NAME;
  }

  @Nls
  @NotNull
  @Override
  public String getDisplayName() {
    return "Numeric overflow";
  }

  @NotNull
  @Override
  public String getShortName() {
    return "NumericOverflow";
  }

  @NotNull
  @Override
  public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
    return new JavaElementVisitor() {
      @Override
      public void visitReferenceExpression(PsiReferenceExpression expression) {
        visitExpression(expression);
      }

      @Override
      public void visitExpression(PsiExpression expression) {
        boolean info = hasOverflow(expression, holder.getProject());
        if (info) {
          holder.registerProblem(expression, JavaErrorMessages.message("numeric.overflow.in.expression"), ProblemHighlightType.GENERIC_ERROR_OR_WARNING);
        }
      }
    };
  }

  private static boolean hasOverflow(PsiExpression expr, @NotNull Project project) {
    if (!TypeConversionUtil.isNumericType(expr.getType())) {
      return false;
    }

    boolean result = false;
    boolean toStoreInParent = false;
    try {
      if (expr.getUserData(HAS_OVERFLOW_IN_CHILD) == null) {
        JavaPsiFacade.getInstance(project).getConstantEvaluationHelper().computeConstantExpression(expr, true);
      }
      else {
        toStoreInParent = true;
        expr.putUserData(HAS_OVERFLOW_IN_CHILD, null);
      }
    }
    catch (ConstantEvaluationOverflowException e) {
      result = toStoreInParent = true;
    }
    finally {
      PsiElement parent = expr.getParent();
      if (toStoreInParent && parent instanceof PsiExpression) {
        parent.putUserData(HAS_OVERFLOW_IN_CHILD, "");
      }
    }

    return result;
  }
}